[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