| 903 | } |
| 904 | |
| 905 | LoopPeelingPass::LoopPeelingInfo::Direction |
| 906 | LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(BasicBlock* bb) const { |
| 907 | if (bb->terminator()->opcode() != spv::Op::OpBranchConditional) { |
| 908 | return GetNoneDirection(); |
| 909 | } |
| 910 | |
| 911 | analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); |
| 912 | |
| 913 | Instruction* condition = |
| 914 | def_use_mgr->GetDef(bb->terminator()->GetSingleWordInOperand(0)); |
| 915 | |
| 916 | if (!IsHandledCondition(condition->opcode())) { |
| 917 | return GetNoneDirection(); |
| 918 | } |
| 919 | |
| 920 | if (!GetFirstLoopInvariantOperand(condition)) { |
| 921 | // No loop invariant, it cannot be peeled by this pass. |
| 922 | return GetNoneDirection(); |
| 923 | } |
| 924 | if (!GetFirstNonLoopInvariantOperand(condition)) { |
| 925 | // Seems to be a job for the unswitch pass. |
| 926 | return GetNoneDirection(); |
| 927 | } |
| 928 | |
| 929 | // Left hand-side. |
| 930 | SExpression lhs = scev_analysis_->AnalyzeInstruction( |
| 931 | def_use_mgr->GetDef(condition->GetSingleWordInOperand(0))); |
| 932 | if (lhs->GetType() == SENode::CanNotCompute) { |
| 933 | // Can't make any conclusion. |
| 934 | return GetNoneDirection(); |
| 935 | } |
| 936 | |
| 937 | // Right hand-side. |
| 938 | SExpression rhs = scev_analysis_->AnalyzeInstruction( |
| 939 | def_use_mgr->GetDef(condition->GetSingleWordInOperand(1))); |
| 940 | if (rhs->GetType() == SENode::CanNotCompute) { |
| 941 | // Can't make any conclusion. |
| 942 | return GetNoneDirection(); |
| 943 | } |
| 944 | |
| 945 | // Only take into account recurrent expression over the current loop. |
| 946 | bool is_lhs_rec = !scev_analysis_->IsLoopInvariant(loop_, lhs); |
| 947 | bool is_rhs_rec = !scev_analysis_->IsLoopInvariant(loop_, rhs); |
| 948 | |
| 949 | if ((is_lhs_rec && is_rhs_rec) || (!is_lhs_rec && !is_rhs_rec)) { |
| 950 | return GetNoneDirection(); |
| 951 | } |
| 952 | |
| 953 | if (is_lhs_rec) { |
| 954 | if (!lhs->AsSERecurrentNode() || |
| 955 | lhs->AsSERecurrentNode()->GetLoop() != loop_) { |
| 956 | return GetNoneDirection(); |
| 957 | } |
| 958 | } |
| 959 | if (is_rhs_rec) { |
| 960 | if (!rhs->AsSERecurrentNode() || |
| 961 | rhs->AsSERecurrentNode()->GetLoop() != loop_) { |
| 962 | return GetNoneDirection(); |
no test coverage detected