[llvm-commits] [llvm] r60374 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll

Dale Johannesen dalej at apple.com
Mon Dec 1 14:00:02 PST 2008


Author: johannes
Date: Mon Dec  1 16:00:01 2008
New Revision: 60374

URL: http://llvm.org/viewvc/llvm-project?rev=60374&view=rev
Log:
Consider only references to an IV within the loop when
figuring out the base of the IV.  This produces better
code in the example.  (Addresses use (IV) instead of 
(BASE,IV) - a significant improvement on low-register
machines like x86).


Added:
    llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60374&r1=60373&r2=60374&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec  1 16:00:01 2008
@@ -643,7 +643,9 @@
     // cases (e.g. use of a post-incremented induction variable) the NewBase
     // value will be pinned to live somewhere after the original computation.
     // In this case, we have to back off.
-    if (!isUseOfPostIncrementedValue) {
+    // However, do not insert new code inside the loop when the reference
+    // is outside.
+    if (!isUseOfPostIncrementedValue && L->contains(Inst->getParent())) {
       if (NewBasePt && isa<PHINode>(OperandValToReplace)) {
         InsertPt = NewBasePt;
         ++InsertPt;
@@ -921,14 +923,16 @@
 /// (a+c+d) -> (a+c).  The common expression is *removed* from the Bases.
 static SCEVHandle 
 RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
-                                    ScalarEvolution *SE) {
+                                    ScalarEvolution *SE, Loop *L) {
   unsigned NumUses = Uses.size();
 
-  // Only one use?  Use its base, regardless of what it is!
+  // Only one use?  If inside the loop, use its base, regardless of what it is;
+  // if outside, use 0.
   SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
   SCEVHandle Result = Zero;
   if (NumUses == 1) {
-    std::swap(Result, Uses[0].Base);
+    if (L->contains(Uses[0].Inst->getParent()))
+      std::swap(Result, Uses[0].Base);
     return Result;
   }
 
@@ -941,7 +945,13 @@
   std::vector<SCEVHandle> UniqueSubExprs;
 
   std::vector<SCEVHandle> SubExprs;
+  uint64_t NumUsesInsideLoop = 0;
   for (unsigned i = 0; i != NumUses; ++i) {
+    // For this purpose, consider only uses that are inside the loop.
+    if (!L->contains(Uses[i].Inst->getParent()))
+      continue;
+    NumUsesInsideLoop++;
+    
     // If the base is zero (which is common), return zero now, there are no
     // CSEs we can find.
     if (Uses[i].Base == Zero) return Zero;
@@ -961,7 +971,7 @@
     std::map<SCEVHandle, unsigned>::iterator I = 
        SubExpressionUseCounts.find(UniqueSubExprs[i]);
     assert(I != SubExpressionUseCounts.end() && "Entry not found?");
-    if (I->second == NumUses) {  // Found CSE!
+    if (I->second == NumUsesInsideLoop) {  // Found CSE!
       Result = SE->getAddExpr(Result, I->first);
     } else {
       // Remove non-cse's from SubExpressionUseCounts.
@@ -974,6 +984,10 @@
   
   // Otherwise, remove all of the CSE's we found from each of the base values.
   for (unsigned i = 0; i != NumUses; ++i) {
+    // For this purpose, consider only uses that are inside the loop.
+    if (!L->contains(Uses[i].Inst->getParent()))
+      continue;
+
     // Split the expression into subexprs.
     SeparateSubExprs(SubExprs, Uses[i].Base, SE);
 
@@ -1166,7 +1180,7 @@
   // "A+B"), emit it to the preheader, then remove the expression from the
   // UsersToProcess base values.
   SCEVHandle CommonExprs =
-    RemoveCommonExpressionsFromUseBases(UsersToProcess, SE);
+    RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L);
 
   // Next, figure out what we can represent in the immediate fields of
   // instructions.  If we can represent anything there, move it to the imm
@@ -1450,6 +1464,12 @@
         // Add BaseV to the PHI value if needed.
         RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
 
+      // If this reference is not in the loop and we have a Common base,
+      // that has been added into the induction variable and must be
+      // subtracted off here.
+      if (HaveCommonExprs && !L->contains(User.Inst->getParent()))
+        RewriteExpr = SE->getMinusSCEV(RewriteExpr, CommonExprs);
+
       User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt,
                                           Rewriter, L, this,
                                           DeadInsts);

Added: llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll?rev=60374&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Mon Dec  1 16:00:01 2008
@@ -0,0 +1,28 @@
+; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | grep -v lea
+; ModuleID = '<stdin>'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin9.5"
+
+define i8* @test(i8* %Q, i32* %L) nounwind {
+entry:
+	br label %bb1
+
+bb:		; preds = %bb1, %bb1
+	%indvar.next = add i32 %P.0.rec, 1		; <i32> [#uses=1]
+	br label %bb1
+
+bb1:		; preds = %bb, %entry
+	%P.0.rec = phi i32 [ 0, %entry ], [ %indvar.next, %bb ]		; <i32> [#uses=3]
+	%P.0 = getelementptr i8* %Q, i32 %P.0.rec		; <i8*> [#uses=2]
+	%0 = load i8* %P.0, align 1		; <i8> [#uses=1]
+	switch i8 %0, label %bb3 [
+		i8 12, label %bb
+		i8 42, label %bb
+	]
+
+bb3:		; preds = %bb1
+	%P.0.sum = add i32 %P.0.rec, 2		; <i32> [#uses=1]
+	%1 = getelementptr i8* %Q, i32 %P.0.sum		; <i8*> [#uses=1]
+	store i8 4, i8* %1, align 1
+	ret i8* %P.0
+}





More information about the llvm-commits mailing list