[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Aug 12 15:06:22 PDT 2005



Changes in directory llvm/lib/Transforms/Scalar:

LoopStrengthReduce.cpp updated: 1.47 -> 1.48
---
Log message:

Fix a FIXME: if we are inserting code for a PHI argument, split the critical
edge so that the code is not always executed for both operands.  This 
prevents LSR from inserting code into loops whose exit blocks contain
PHI uses of IV expressions (which are outside of loops).  On gzip, for
example, we turn this ugly code:

.LBB_test_1:    ; loopentry
        add r27, r3, r28
        lhz r27, 3(r27)
        add r26, r4, r28
        lhz r26, 3(r26)
        add r25, r30, r28    ;; Only live if exiting the loop
        add r24, r29, r28    ;; Only live if exiting the loop
        cmpw cr0, r27, r26
        bne .LBB_test_5 ; loopexit

into this:

.LBB_test_1:    ; loopentry
        or r27, r28, r28
        add r28, r3, r27
        lhz r28, 3(r28)
        add r26, r4, r27
        lhz r26, 3(r26)
        cmpw cr0, r28, r26
        beq .LBB_test_3 ; shortcirc_next.0
.LBB_test_2:    ; loopentry.loopexit_crit_edge
        add r2, r30, r27
        add r8, r29, r27
        b .LBB_test_9   ; loopexit
.LBB_test_2:    ; shortcirc_next.0
        ...
        blt .LBB_test_1


into this:

.LBB_test_1:    ; loopentry
        or r27, r28, r28
        add r28, r3, r27
        lhz r28, 3(r28)
        add r26, r4, r27
        lhz r26, 3(r26)
        cmpw cr0, r28, r26
        beq .LBB_test_3 ; shortcirc_next.0
.LBB_test_2:    ; loopentry.loopexit_crit_edge
        add r2, r30, r27
        add r8, r29, r27
        b .LBB_t_3:    ; shortcirc_next.0
.LBB_test_3:    ; shortcirc_next.0
        ...
        blt .LBB_test_1


Next step: get the block out of the loop so that the loop is all 
fall-throughs again.



---
Diffs of the changes:  (+19 -6)

 LoopStrengthReduce.cpp |   25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)


Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.47 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.48
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.47	Tue Aug  9 19:45:21 2005
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp	Fri Aug 12 17:06:11 2005
@@ -26,6 +26,7 @@
 #include "llvm/Analysis/ScalarEvolutionExpander.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/ADT/Statistic.h"
@@ -391,7 +392,7 @@
     // operands of Inst to use the new expression 'NewBase', with 'Imm' added
     // to it.
     void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
-                                        SCEVExpander &Rewriter);
+                                        SCEVExpander &Rewriter, Pass *P);
 
     // Sort by the Base field.
     bool operator<(const BasedUser &BU) const { return Base < BU.Base; }
@@ -413,12 +414,12 @@
 // operands of Inst to use the new expression 'NewBase', with 'Imm' added
 // to it.
 void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
-                                               SCEVExpander &Rewriter) {
+                                               SCEVExpander &Rewriter,
+                                               Pass *P) {
   if (!isa<PHINode>(Inst)) {
     SCEVHandle NewValSCEV = SCEVAddExpr::get(NewBase, Imm);
     Value *NewVal = Rewriter.expandCodeFor(NewValSCEV, Inst,
                                            OperandValToReplace->getType());
-    
     // Replace the use of the operand Value with the new Phi we just created.
     Inst->replaceUsesOfWith(OperandValToReplace, NewVal);
     DEBUG(std::cerr << "    CHANGED: IMM =" << *Imm << "  Inst = " << *Inst);
@@ -434,7 +435,19 @@
   PHINode *PN = cast<PHINode>(Inst);
   for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
     if (PN->getIncomingValue(i) == OperandValToReplace) {
-      // FIXME: this should split any critical edges.
+      // If this is a critical edge, split the edge so that we do not insert the
+      // code on all predecessor/successor paths.
+      if (e != 1 &&
+          PN->getIncomingBlock(i)->getTerminator()->getNumSuccessors() > 1) {
+        TerminatorInst *PredTI = PN->getIncomingBlock(i)->getTerminator();
+        for (unsigned Succ = 0; ; ++Succ) {
+          assert(Succ != PredTI->getNumSuccessors() &&"Didn't find successor?");
+          if (PredTI->getSuccessor(Succ) == PN->getParent()) {
+            SplitCriticalEdge(PredTI, Succ, P);
+            break;
+          }
+        }
+      }
 
       Value *&Code = InsertedCode[PN->getIncomingBlock(i)];
       if (!Code) {
@@ -623,7 +636,7 @@
       for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
         if (!SubExpressionUseCounts.count(AE->getOperand(j)))
           NewOps.push_back(AE->getOperand(j));
-      if (NewOps.size() == 0)
+      if (NewOps.empty())
         Uses[i].Base = Zero;
       else
         Uses[i].Base = SCEVAddExpr::get(NewOps);
@@ -783,7 +796,7 @@
         // Add BaseV to the PHI value if needed.
         RewriteExpr = SCEVAddExpr::get(RewriteExpr, SCEVUnknown::get(BaseV));
       
-      User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter);
+      User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter, this);
 
       // Mark old value we replaced as possibly dead, so that it is elminated
       // if we just replaced the last use of that value.






More information about the llvm-commits mailing list