| 700 | } |
| 701 | |
| 702 | bool 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 |
nothing calls this directly
no test coverage detected