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

Method FindConditionVariable

source/opt/loop_descriptor.cpp:860–925  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

858}
859
860Instruction* Loop::FindConditionVariable(
861 const BasicBlock* condition_block) const {
862 // Find the branch instruction.
863 const Instruction& branch_inst = *condition_block->ctail();
864
865 Instruction* induction = nullptr;
866 // Verify that the branch instruction is a conditional branch.
867 if (branch_inst.opcode() == spv::Op::OpBranchConditional) {
868 // From the branch instruction find the branch condition.
869 analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
870
871 // Find the instruction representing the condition used in the conditional
872 // branch.
873 Instruction* condition =
874 def_use_manager->GetDef(branch_inst.GetSingleWordOperand(0));
875
876 // Ensure that the condition is a less than operation.
877 if (condition && IsSupportedCondition(condition->opcode())) {
878 // The left hand side operand of the operation.
879 Instruction* variable_inst =
880 def_use_manager->GetDef(condition->GetSingleWordOperand(2));
881
882 // Make sure the variable instruction used is a phi.
883 if (!variable_inst || variable_inst->opcode() != spv::Op::OpPhi)
884 return nullptr;
885
886 // Make sure the phi instruction only has two incoming blocks. Each
887 // incoming block will be represented by two in operands in the phi
888 // instruction, the value and the block which that value came from. We
889 // assume the cannocalised phi will have two incoming values, one from the
890 // preheader and one from the continue block.
891 size_t max_supported_operands = 4;
892 if (variable_inst->NumInOperands() == max_supported_operands) {
893 // The operand index of the first incoming block label.
894 uint32_t operand_label_1 = 1;
895
896 // The operand index of the second incoming block label.
897 uint32_t operand_label_2 = 3;
898
899 // Make sure one of them is the preheader.
900 if (!IsInsideLoop(
901 variable_inst->GetSingleWordInOperand(operand_label_1)) &&
902 !IsInsideLoop(
903 variable_inst->GetSingleWordInOperand(operand_label_2))) {
904 return nullptr;
905 }
906
907 // And make sure that the other is the latch block.
908 if (variable_inst->GetSingleWordInOperand(operand_label_1) !=
909 loop_latch_->id() &&
910 variable_inst->GetSingleWordInOperand(operand_label_2) !=
911 loop_latch_->id()) {
912 return nullptr;
913 }
914 } else {
915 return nullptr;
916 }
917

Callers 6

ProcessLoopMethod · 0.80
GetTripCountMethod · 0.80
InitMethod · 0.80
CanPerformUnrollMethod · 0.80
TEST_FFunction · 0.80

Calls 8

ctailMethod · 0.80
GetSingleWordOperandMethod · 0.80
NumInOperandsMethod · 0.80
opcodeMethod · 0.45
get_def_use_mgrMethod · 0.45
GetDefMethod · 0.45
idMethod · 0.45

Tested by

no test coverage detected