| 710 | } |
| 711 | |
| 712 | std::tuple<Pass::Status, Loop*> LoopPeelingPass::ProcessLoop( |
| 713 | Loop* loop, CodeMetrics* loop_size) { |
| 714 | ScalarEvolutionAnalysis* scev_analysis = |
| 715 | context()->GetScalarEvolutionAnalysis(); |
| 716 | // Default values for bailing out. |
| 717 | std::tuple<Pass::Status, Loop*> bail_out{Pass::Status::SuccessWithoutChange, |
| 718 | nullptr}; |
| 719 | |
| 720 | BasicBlock* exit_block = loop->FindConditionBlock(); |
| 721 | if (!exit_block) { |
| 722 | return bail_out; |
| 723 | } |
| 724 | |
| 725 | Instruction* exiting_iv = loop->FindConditionVariable(exit_block); |
| 726 | if (!exiting_iv) { |
| 727 | return bail_out; |
| 728 | } |
| 729 | size_t iterations = 0; |
| 730 | if (!loop->FindNumberOfIterations(exiting_iv, &*exit_block->tail(), |
| 731 | &iterations)) { |
| 732 | return bail_out; |
| 733 | } |
| 734 | if (!iterations) { |
| 735 | return bail_out; |
| 736 | } |
| 737 | |
| 738 | Instruction* canonical_induction_variable = nullptr; |
| 739 | |
| 740 | loop->GetHeaderBlock()->WhileEachPhiInst([&canonical_induction_variable, |
| 741 | scev_analysis, |
| 742 | this](Instruction* insn) { |
| 743 | if (const SERecurrentNode* iv = |
| 744 | scev_analysis->AnalyzeInstruction(insn)->AsSERecurrentNode()) { |
| 745 | const SEConstantNode* offset = iv->GetOffset()->AsSEConstantNode(); |
| 746 | const SEConstantNode* coeff = iv->GetCoefficient()->AsSEConstantNode(); |
| 747 | if (offset && coeff && offset->FoldToSingleValue() == 0 && |
| 748 | coeff->FoldToSingleValue() == 1) { |
| 749 | if (context()->get_type_mgr()->GetType(insn->type_id())->AsInteger()) { |
| 750 | canonical_induction_variable = insn; |
| 751 | return false; |
| 752 | } |
| 753 | } |
| 754 | } |
| 755 | return true; |
| 756 | }); |
| 757 | |
| 758 | bool is_signed = canonical_induction_variable |
| 759 | ? context() |
| 760 | ->get_type_mgr() |
| 761 | ->GetType(canonical_induction_variable->type_id()) |
| 762 | ->AsInteger() |
| 763 | ->IsSigned() |
| 764 | : false; |
| 765 | |
| 766 | LoopPeeling peeler( |
| 767 | loop, |
| 768 | InstructionBuilder( |
| 769 | context(), loop->GetHeaderBlock(), |
nothing calls this directly
no test coverage detected