MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / Process

Method Process

source/opt/if_conversion.cpp:25–149  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

23namespace opt {
24
25Pass::Status IfConversion::Process() {
26 if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) {
27 return Status::SuccessWithoutChange;
28 }
29
30 const ValueNumberTable& vn_table = *context()->GetValueNumberTable();
31 bool modified = false;
32 std::vector<Instruction*> to_kill;
33 for (auto& func : *get_module()) {
34 DominatorAnalysis* dominators = context()->GetDominatorAnalysis(&func);
35 for (auto& block : func) {
36 // Check if it is possible for |block| to have phis that can be
37 // transformed.
38 BasicBlock* common = nullptr;
39 if (!CheckBlock(&block, dominators, &common)) continue;
40
41 // Get an insertion point.
42 auto iter = block.begin();
43 while (iter != block.end() && iter->opcode() == spv::Op::OpPhi) {
44 ++iter;
45 }
46
47 InstructionBuilder builder(
48 context(), &*iter,
49 IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
50 block.ForEachPhiInst([this, &builder, &modified, &common, &to_kill,
51 dominators, &block, &vn_table](Instruction* phi) {
52 // This phi is not compatible, but subsequent phis might be.
53 if (!CheckType(phi->type_id())) return;
54
55 // We cannot transform cases where the phi is used by another phi in the
56 // same block due to instruction ordering restrictions.
57 // TODO(alan-baker): If all inappropriate uses could also be
58 // transformed, we could still remove this phi.
59 if (!CheckPhiUsers(phi, &block)) return;
60
61 // Identify the incoming values associated with the true and false
62 // branches. If |then_block| dominates |inc0| or if the true edge
63 // branches straight to this block and |common| is |inc0|, then |inc0|
64 // is on the true branch. Otherwise the |inc1| is on the true branch.
65 BasicBlock* inc0 = GetIncomingBlock(phi, 0u);
66 Instruction* branch = common->terminator();
67 uint32_t condition = branch->GetSingleWordInOperand(0u);
68 BasicBlock* then_block = GetBlock(branch->GetSingleWordInOperand(1u));
69 Instruction* true_value = nullptr;
70 Instruction* false_value = nullptr;
71 if ((then_block == &block && inc0 == common) ||
72 dominators->Dominates(then_block, inc0)) {
73 true_value = GetIncomingValue(phi, 0u);
74 false_value = GetIncomingValue(phi, 1u);
75 } else {
76 true_value = GetIncomingValue(phi, 1u);
77 false_value = GetIncomingValue(phi, 0u);
78 }
79
80 BasicBlock* true_def_block = context()->get_instr_block(true_value);
81 BasicBlock* false_def_block = context()->get_instr_block(false_value);
82

Callers

nothing calls this directly

Calls 15

GetBlockFunction · 0.85
GetValueNumberTableMethod · 0.80
GetDominatorAnalysisMethod · 0.80
ForEachPhiInstMethod · 0.80
get_instr_blockMethod · 0.80
GetValueNumberMethod · 0.80
KillNamesAndDecoratesMethod · 0.80
ReplaceAllUsesWithMethod · 0.80
get_type_mgrMethod · 0.80
AsVectorMethod · 0.80
AddSelectMethod · 0.80

Tested by

no test coverage detected