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

Method CopyBody

source/opt/loop_unroller.cpp:702–766  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

700}
701
702bool LoopUnrollerUtilsImpl::CopyBody(Loop* loop, bool eliminate_conditions) {
703 // Copy each basic block in the loop, give them new ids, and save state
704 // information.
705 for (const BasicBlock* itr : loop_blocks_inorder_) {
706 if (!CopyBasicBlock(loop, itr, false)) {
707 return false;
708 }
709 }
710
711 // Set the previous latch block to point to the new header.
712 Instruction* latch_branch = state_.previous_latch_block_->terminator();
713 latch_branch->SetInOperand(0, {state_.new_header_block->id()});
714 context_->UpdateDefUse(latch_branch);
715
716 // As the algorithm copies the original loop blocks exactly, the tail of the
717 // latch block on iterations after the first one will be a branch to the new
718 // header and not the actual loop header. The last continue block in the loop
719 // should always be a backedge to the global header.
720 Instruction* new_latch_branch = state_.new_latch_block->terminator();
721 new_latch_branch->SetInOperand(0, {loop->GetHeaderBlock()->id()});
722 context_->AnalyzeUses(new_latch_branch);
723
724 std::vector<Instruction*> inductions;
725 loop->GetInductionVariables(inductions);
726 for (size_t index = 0; index < inductions.size(); ++index) {
727 Instruction* primary_copy = inductions[index];
728
729 assert(primary_copy->result_id() != 0);
730 Instruction* induction_clone =
731 state_.ids_to_new_inst[state_.new_inst[primary_copy->result_id()]];
732
733 state_.new_phis_.push_back(induction_clone);
734 assert(induction_clone->result_id() != 0);
735
736 if (!state_.previous_phis_.empty()) {
737 state_.new_inst[primary_copy->result_id()] = GetPhiDefID(
738 state_.previous_phis_[index], state_.previous_latch_block_->id());
739 } else {
740 // Do not replace the first phi block ids.
741 state_.new_inst[primary_copy->result_id()] = primary_copy->result_id();
742 }
743 }
744
745 if (eliminate_conditions &&
746 state_.new_condition_block != loop_condition_block_) {
747 if (!FoldConditionBlock(state_.new_condition_block, 1)) {
748 return false;
749 }
750 }
751
752 // Only reference to the header block is the backedge in the latch block,
753 // don't change this.
754 state_.new_inst[loop->GetHeaderBlock()->id()] = loop->GetHeaderBlock()->id();
755
756 for (auto& pair : state_.new_blocks) {
757 RemapOperands(pair.second);
758 }
759

Callers

nothing calls this directly

Calls 12

SetInOperandMethod · 0.80
AnalyzeUsesMethod · 0.80
GetInductionVariablesMethod · 0.80
NextIterationStateMethod · 0.80
terminatorMethod · 0.45
idMethod · 0.45
UpdateDefUseMethod · 0.45
GetHeaderBlockMethod · 0.45
sizeMethod · 0.45
result_idMethod · 0.45
push_backMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected