diff --git a/lib/Transforms/Scalar/LoopIndexSplit.cpp b/lib/Transforms/Scalar/LoopIndexSplit.cpp index 1eeb9be6a13..f6cb4293f6e 100644 --- a/lib/Transforms/Scalar/LoopIndexSplit.cpp +++ b/lib/Transforms/Scalar/LoopIndexSplit.cpp @@ -58,7 +58,8 @@ namespace { class SplitInfo { public: SplitInfo() : SplitValue(NULL), SplitCondition(NULL), - UseTrueBranchFirst(true) {} + UseTrueBranchFirst(true), A_ExitValue(NULL), + B_StartValue(NULL) {} // Induction variable's range is split at this value. Value *SplitValue; @@ -69,11 +70,20 @@ namespace { // True if after loop index split, first loop will execute split condition's // true branch. bool UseTrueBranchFirst; + + // Exit value for first loop after loop split. + Value *A_ExitValue; + + // Start value for second loop after loop split. + Value *B_StartValue; + // Clear split info. void clear() { SplitValue = NULL; SplitCondition = NULL; UseTrueBranchFirst = true; + A_ExitValue = NULL; + B_StartValue = NULL; } }; @@ -112,6 +122,10 @@ namespace { /// split loop using given split condition. bool safeSplitCondition(SplitInfo &SD); + /// calculateLoopBounds - ALoop exit value and BLoop start values are calculated + /// based on split value. + void calculateLoopBounds(SplitInfo &SD); + /// splitLoop - Split current loop L in two loops using split information /// SD. Update dominator information. Maintain LCSSA form. bool splitLoop(SplitInfo &SD); @@ -295,7 +309,14 @@ void LoopIndexSplit::findLoopConditionals() { ICmpInst *CI = dyn_cast(BR->getCondition()); if (!CI) return; - + + // FIXME + if (CI->getPredicate() == ICmpInst::ICMP_SGT + || CI->getPredicate() == ICmpInst::ICMP_UGT + || CI->getPredicate() == ICmpInst::ICMP_SGE + || CI->getPredicate() == ICmpInst::ICMP_UGE) + return; + ExitCondition = CI; // Exit condition's one operand is loop invariant exit value and second @@ -747,6 +768,207 @@ bool LoopIndexSplit::safeSplitCondition(SplitInfo &SD) { return false; } +/// calculateLoopBounds - ALoop exit value and BLoop start values are calculated +/// based on split value. +void LoopIndexSplit::calculateLoopBounds(SplitInfo &SD) { + + ICmpInst::Predicate SP = SD.SplitCondition->getPredicate(); + const Type *Ty = SD.SplitValue->getType(); + bool Sign = ExitCondition->isSignedPredicate(); + BasicBlock *Preheader = L->getLoopPreheader(); + Instruction *PHTerminator = Preheader->getTerminator(); + + // Initially use split value as upper loop bound for first loop and lower loop + // bound for second loop. + Value *AEV = SD.SplitValue; + Value *BSV = SD.SplitValue; + + switch (ExitCondition->getPredicate()) { + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_SGE: + case ICmpInst::ICMP_UGE: + default: + assert (0 && "Unexpected exit condition predicate"); + + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_ULT: + { + switch (SP) { + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_ULT: + // + // for (i = LB; i < UB; ++i) { if (i < SV) A; else B; } + // + // is transformed into + // AEV = BSV = SV + // for (i = LB; i < min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i < UB; ++i); + // B; + break; + case ICmpInst::ICMP_SLE: + case ICmpInst::ICMP_ULE: + { + // + // for (i = LB; i < UB; ++i) { if (i <= SV) A; else B; } + // + // is transformed into + // + // AEV = SV + 1 + // BSV = SV + 1 + // for (i = LB; i < min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i < UB; ++i) + // B; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + AEV = BSV; + } + break; + case ICmpInst::ICMP_SGE: + case ICmpInst::ICMP_UGE: + // + // for (i = LB; i < UB; ++i) { if (i >= SV) A; else B; } + // + // is transformed into + // AEV = BSV = SV + // for (i = LB; i < min(UB, AEV); ++i) + // B; + // for (i = max(BSV, LB); i < UB; ++i) + // A; + break; + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_UGT: + { + // + // for (i = LB; i < UB; ++i) { if (i > SV) A; else B; } + // + // is transformed into + // + // BSV = AEV = SV + 1 + // for (i = LB; i < min(UB, AEV); ++i) + // B; + // for (i = max(LB, BSV); i < UB; ++i) + // A; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + AEV = BSV; + } + break; + default: + assert (0 && "Unexpected split condition predicate"); + break; + } // end switch (SP) + } + break; + case ICmpInst::ICMP_SLE: + case ICmpInst::ICMP_ULE: + { + switch (SP) { + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_ULT: + // + // for (i = LB; i <= UB; ++i) { if (i < SV) A; else B; } + // + // is transformed into + // AEV = SV - 1; + // BSV = SV; + // for (i = LB; i <= min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i <= UB; ++i) + // B; + AEV = BinaryOperator::createSub(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.sub", PHTerminator); + break; + case ICmpInst::ICMP_SLE: + case ICmpInst::ICMP_ULE: + // + // for (i = LB; i <= UB; ++i) { if (i <= SV) A; else B; } + // + // is transformed into + // AEV = SV; + // BSV = SV + 1; + // for (i = LB; i <= min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i <= UB; ++i) + // B; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + break; + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_UGT: + // + // for (i = LB; i <= UB; ++i) { if (i > SV) A; else B; } + // + // is transformed into + // AEV = SV; + // BSV = SV + 1; + // for (i = LB; i <= min(AEV, UB); ++i) + // B; + // for (i = max(LB, BSV); i <= UB; ++i) + // A; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + break; + case ICmpInst::ICMP_SGE: + case ICmpInst::ICMP_UGE: + // ** TODO ** + // + // for (i = LB; i <= UB; ++i) { if (i >= SV) A; else B; } + // + // is transformed into + // AEV = SV - 1; + // BSV = SV; + // for (i = LB; i <= min(AEV, UB); ++i) + // B; + // for (i = max(LB, BSV); i <= UB; ++i) + // A; + AEV = BinaryOperator::createSub(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.sub", PHTerminator); + break; + default: + assert (0 && "Unexpected split condition predicate"); + break; + } // end switch (SP) + } + break; + } + + // Calculate ALoop induction variable's new exiting value and + // BLoop induction variable's new starting value. Calculuate these + // values in original loop's preheader. + // A_ExitValue = min(SplitValue, OrignalLoopExitValue) + // B_StartValue = max(SplitValue, OriginalLoopStartValue) + if (isa(SD.SplitValue)) { + SD.A_ExitValue = AEV; + SD.B_StartValue = BSV; + return; + } + + Value *C1 = new ICmpInst(Sign ? + ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + AEV, + ExitCondition->getOperand(ExitValueNum), + "lsplit.ev", PHTerminator); + SD.A_ExitValue = new SelectInst(C1, AEV, + ExitCondition->getOperand(ExitValueNum), + "lsplit.ev", PHTerminator); + + Value *C2 = new ICmpInst(Sign ? + ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + BSV, StartValue, "lsplit.sv", + PHTerminator); + SD.B_StartValue = new SelectInst(C2, StartValue, BSV, + "lsplit.sv", PHTerminator); +} + /// splitLoop - Split current loop L in two loops using split information /// SD. Update dominator information. Maintain LCSSA form. bool LoopIndexSplit::splitLoop(SplitInfo &SD) { @@ -762,38 +984,11 @@ bool LoopIndexSplit::splitLoop(SplitInfo &SD) { // // ALoop's exit edge enters BLoop's header through a forwarding block which // acts as a BLoop's preheader. + BasicBlock *Preheader = L->getLoopPreheader(); - //[*] Calculate ALoop induction variable's new exiting value and - // BLoop induction variable's new starting value. Calculuate these - // values in original loop's preheader. - // A_ExitValue = min(SplitValue, OrignalLoopExitValue) - // B_StartValue = max(SplitValue, OriginalLoopStartValue) - Value *A_ExitValue = NULL; - Value *B_StartValue = NULL; - if (isa(SD.SplitValue)) { - A_ExitValue = SD.SplitValue; - B_StartValue = SD.SplitValue; - } - else { - BasicBlock *Preheader = L->getLoopPreheader(); - Instruction *PHTerminator = Preheader->getTerminator(); - bool SignedPredicate = ExitCondition->isSignedPredicate(); - Value *C1 = new ICmpInst(SignedPredicate ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - SD.SplitValue, - ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", PHTerminator); - A_ExitValue = new SelectInst(C1, SD.SplitValue, - ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", PHTerminator); - - Value *C2 = new ICmpInst(SignedPredicate ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - SD.SplitValue, StartValue, "lsplit.sv", - PHTerminator); - B_StartValue = new SelectInst(C2, StartValue, SD.SplitValue, - "lsplit.sv", PHTerminator); - } + // Calculate ALoop induction variable's new exiting value and + // BLoop induction variable's new starting value. + calculateLoopBounds(SD); //[*] Clone loop. DenseMap ValueMap; @@ -815,7 +1010,7 @@ bool LoopIndexSplit::splitLoop(SplitInfo &SD) { A_ExitInsn->setSuccessor(1, B_Header); //[*] Update ALoop's exit value using new exit value. - ExitCondition->setOperand(ExitValueNum, A_ExitValue); + ExitCondition->setOperand(ExitValueNum, SD.A_ExitValue); // [*] Update BLoop's header phi nodes. Remove incoming PHINode's from // original loop's preheader. Add incoming PHINode values from @@ -831,7 +1026,7 @@ bool LoopIndexSplit::splitLoop(SplitInfo &SD) { } else break; } - BasicBlock *Preheader = L->getLoopPreheader(); + for (BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { @@ -840,7 +1035,7 @@ bool LoopIndexSplit::splitLoop(SplitInfo &SD) { // Add incoming value from A_ExitingBlock. if (PN == B_IndVar) - PN->addIncoming(B_StartValue, A_ExitingBlock); + PN->addIncoming(SD.B_StartValue, A_ExitingBlock); else { PHINode *OrigPN = cast(InverseMap[PN]); Value *V2 = OrigPN->getIncomingValueForBlock(A_ExitingBlock); diff --git a/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll b/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll new file mode 100644 index 00000000000..27327a059cf --- /dev/null +++ b/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll @@ -0,0 +1,52 @@ +; Split loop. Save last value. Split value is off by one in this example. +; RUN: llvm-as < %s | opt -loop-index-split -disable-output -stats |& \ +; RUN: grep "loop-index-split" | count 1 + +@k = external global i32 ; [#uses=2] + +define void @foobar(i32 %a, i32 %b) { +entry: + br label %bb + +bb: ; preds = %cond_next16, %entry + %i.01.0 = phi i32 [ 0, %entry ], [ %tmp18, %cond_next16 ] ; [#uses=5] + %tsum.18.0 = phi i32 [ 42, %entry ], [ %tsum.013.1, %cond_next16 ] ; [#uses=3] + %tmp1 = icmp sgt i32 %i.01.0, 50 ; [#uses=1] + br i1 %tmp1, label %cond_true, label %cond_false + +cond_true: ; preds = %bb + %tmp4 = tail call i32 @foo( i32 %i.01.0 ) ; [#uses=1] + %tmp6 = add i32 %tmp4, %tsum.18.0 ; [#uses=2] + %tmp914 = load i32* @k, align 4 ; [#uses=1] + %tmp1015 = icmp eq i32 %tmp914, 0 ; [#uses=1] + br i1 %tmp1015, label %cond_next16, label %cond_true13 + +cond_false: ; preds = %bb + %tmp8 = tail call i32 @bar( i32 %i.01.0 ) ; [#uses=0] + %tmp9 = load i32* @k, align 4 ; [#uses=1] + %tmp10 = icmp eq i32 %tmp9, 0 ; [#uses=1] + br i1 %tmp10, label %cond_next16, label %cond_true13 + +cond_true13: ; preds = %cond_false, %cond_true + %tsum.013.0 = phi i32 [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; [#uses=1] + %tmp15 = tail call i32 @bar( i32 %i.01.0 ) ; [#uses=0] + br label %cond_next16 + +cond_next16: ; preds = %cond_false, %cond_true, %cond_true13 + %tsum.013.1 = phi i32 [ %tsum.013.0, %cond_true13 ], [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; [#uses=2] + %tmp18 = add i32 %i.01.0, 1 ; [#uses=3] + %tmp21 = icmp slt i32 %tmp18, 100 ; [#uses=1] + br i1 %tmp21, label %bb, label %bb24 + +bb24: ; preds = %cond_next16 + %tmp18.lcssa = phi i32 [ %tmp18, %cond_next16 ] ; [#uses=1] + %tsum.013.1.lcssa = phi i32 [ %tsum.013.1, %cond_next16 ] ; [#uses=1] + %tmp27 = tail call i32 @t( i32 %tmp18.lcssa, i32 %tsum.013.1.lcssa ) ; [#uses=0] + ret void +} + +declare i32 @foo(i32) + +declare i32 @bar(i32) + +declare i32 @t(i32, i32)