[llvm-commits] [llvm] r41387 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll
Devang Patel
dpatel at apple.com
Fri Aug 24 17:56:38 PDT 2007
Author: dpatel
Date: Fri Aug 24 19:56:38 2007
New Revision: 41387
URL: http://llvm.org/viewvc/llvm-project?rev=41387&view=rev
Log:
While calculating upper loop bound for first loop and lower loop bound for second loop, take care of edge cases.
Added:
llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41387&r1=41386&r2=41387&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 19:56:38 2007
@@ -58,7 +58,8 @@
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 @@
// 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 @@
/// 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 @@
ICmpInst *CI = dyn_cast<ICmpInst>(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 @@
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<ConstantInt>(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 @@
//
// 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<ConstantInt>(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<const Value *, Value *> ValueMap;
@@ -815,7 +1010,7 @@
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 @@
} 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<PHINode>(BI)) {
@@ -840,7 +1035,7 @@
// 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<PHINode>(InverseMap[PN]);
Value *V2 = OrigPN->getIncomingValueForBlock(A_ExitingBlock);
Added: llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll?rev=41387&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll (added)
+++ llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll Fri Aug 24 19:56:38 2007
@@ -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
+
+ at k = external global i32 ; <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 ] ; <i32> [#uses=5]
+ %tsum.18.0 = phi i32 [ 42, %entry ], [ %tsum.013.1, %cond_next16 ] ; <i32> [#uses=3]
+ %tmp1 = icmp sgt i32 %i.01.0, 50 ; <i1> [#uses=1]
+ br i1 %tmp1, label %cond_true, label %cond_false
+
+cond_true: ; preds = %bb
+ %tmp4 = tail call i32 @foo( i32 %i.01.0 ) ; <i32> [#uses=1]
+ %tmp6 = add i32 %tmp4, %tsum.18.0 ; <i32> [#uses=2]
+ %tmp914 = load i32* @k, align 4 ; <i32> [#uses=1]
+ %tmp1015 = icmp eq i32 %tmp914, 0 ; <i1> [#uses=1]
+ br i1 %tmp1015, label %cond_next16, label %cond_true13
+
+cond_false: ; preds = %bb
+ %tmp8 = tail call i32 @bar( i32 %i.01.0 ) ; <i32> [#uses=0]
+ %tmp9 = load i32* @k, align 4 ; <i32> [#uses=1]
+ %tmp10 = icmp eq i32 %tmp9, 0 ; <i1> [#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 ] ; <i32> [#uses=1]
+ %tmp15 = tail call i32 @bar( i32 %i.01.0 ) ; <i32> [#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 ] ; <i32> [#uses=2]
+ %tmp18 = add i32 %i.01.0, 1 ; <i32> [#uses=3]
+ %tmp21 = icmp slt i32 %tmp18, 100 ; <i1> [#uses=1]
+ br i1 %tmp21, label %bb, label %bb24
+
+bb24: ; preds = %cond_next16
+ %tmp18.lcssa = phi i32 [ %tmp18, %cond_next16 ] ; <i32> [#uses=1]
+ %tsum.013.1.lcssa = phi i32 [ %tsum.013.1, %cond_next16 ] ; <i32> [#uses=1]
+ %tmp27 = tail call i32 @t( i32 %tmp18.lcssa, i32 %tsum.013.1.lcssa ) ; <i32> [#uses=0]
+ ret void
+}
+
+declare i32 @foo(i32)
+
+declare i32 @bar(i32)
+
+declare i32 @t(i32, i32)
More information about the llvm-commits
mailing list