[llvm-branch-commits] [llvm-branch] r86182 - in /llvm/branches/Apple/Leela: include/llvm/Analysis/ lib/Analysis/ lib/Transforms/IPO/ lib/Transforms/Scalar/ lib/Transforms/Utils/ test/Transforms/LoopSimplify/

Dan Gohman gohman at apple.com
Thu Nov 5 13:54:02 PST 2009


Author: djg
Date: Thu Nov  5 15:54:02 2009
New Revision: 86182

URL: http://llvm.org/viewvc/llvm-project?rev=86182&view=rev
Log:
$ svn merge -c 86159 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86159 into '.':
U    include/llvm/Analysis/LoopInfo.h
U    lib/Analysis/LoopInfo.cpp
$ svn merge -c 86160 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86160 into '.':
U    lib/Transforms/Utils/LCSSA.cpp
$ svn merge -c 86161 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86161 into '.':
U    lib/Analysis/IVUsers.cpp
$ svn merge -c 86163 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86163 into '.':
U    lib/Transforms/Scalar/LoopRotation.cpp
$ svn merge -c 86164 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86164 into '.':
U    lib/Transforms/Utils/LoopUnroll.cpp
$ svn merge -c 86176 https://llvm.org/svn/llvm-project/llvm/trunk
svn: Copyfrom-url 'https://llvm.org/svn/llvm-project/llvm/trunk/test/Transforms/LoopSimplify/indirectbr.ll' has different repository root than 'https://djg@llvm.org/svn/llvm-project'
svn: Error reading spooled REPORT request response
$ svn merge -c 86175 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86175 into '.':
U    lib/Transforms/Scalar/LoopUnswitch.cpp
U    lib/Transforms/Scalar/IndVarSimplify.cpp
U    lib/Transforms/Scalar/LoopStrengthReduce.cpp
G    lib/Transforms/Scalar/LoopRotation.cpp
U    lib/Transforms/Scalar/LoopIndexSplit.cpp
U    lib/Transforms/Scalar/LICM.cpp
U    lib/Transforms/IPO/LoopExtractor.cpp
$ svn merge -c 86180 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86180 into '.':
U    lib/Transforms/Scalar/LoopDeletion.cpp
$ svn merge -c 86181 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86181 into '.':
U    lib/Transforms/Utils/LoopSimplify.cpp
$ cp ../llvm/test/Transforms/LoopSimplify/indirectbr.ll test/Transforms/LoopSimplify/
$ svn add test/Transforms/LoopSimplify/indirectbr.ll 
A         test/Transforms/LoopSimplify/indirectbr.ll

Added:
    llvm/branches/Apple/Leela/test/Transforms/LoopSimplify/indirectbr.ll
Modified:
    llvm/branches/Apple/Leela/include/llvm/Analysis/LoopInfo.h
    llvm/branches/Apple/Leela/lib/Analysis/IVUsers.cpp
    llvm/branches/Apple/Leela/lib/Analysis/LoopInfo.cpp
    llvm/branches/Apple/Leela/lib/Transforms/IPO/LoopExtractor.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Scalar/IndVarSimplify.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Scalar/LICM.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopDeletion.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopIndexSplit.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopRotation.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopStrengthReduce.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopUnswitch.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Utils/LCSSA.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopSimplify.cpp
    llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopUnroll.cpp

Modified: llvm/branches/Apple/Leela/include/llvm/Analysis/LoopInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/include/llvm/Analysis/LoopInfo.h?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/include/llvm/Analysis/LoopInfo.h (original)
+++ llvm/branches/Apple/Leela/include/llvm/Analysis/LoopInfo.h Thu Nov  5 15:54:02 2009
@@ -572,6 +572,10 @@
   /// normal form.
   bool isLoopSimplifyForm() const;
 
+  /// hasDedicatedExits - Return true if no exit block for the loop
+  /// has a predecessor that is outside the loop.
+  bool hasDedicatedExits() const;
+
   /// getUniqueExitBlocks - Return all unique successor blocks of this loop. 
   /// These are the blocks _outside of the current loop_ which are branched to.
   /// This assumes that loop is in canonical form.

Modified: llvm/branches/Apple/Leela/lib/Analysis/IVUsers.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Analysis/IVUsers.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Analysis/IVUsers.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Analysis/IVUsers.cpp Thu Nov  5 15:54:02 2009
@@ -151,6 +151,8 @@
   if (L->contains(User->getParent())) return false;
 
   BasicBlock *LatchBlock = L->getLoopLatch();
+  if (!LatchBlock)
+    return false;
 
   // Ok, the user is outside of the loop.  If it is dominated by the latch
   // block, use the post-inc value.

Modified: llvm/branches/Apple/Leela/lib/Analysis/LoopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Analysis/LoopInfo.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Analysis/LoopInfo.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Analysis/LoopInfo.cpp Thu Nov  5 15:54:02 2009
@@ -286,12 +286,14 @@
 /// the LoopSimplify form transforms loops to, which is sometimes called
 /// normal form.
 bool Loop::isLoopSimplifyForm() const {
-  // Normal-form loops have a preheader.
-  if (!getLoopPreheader())
-    return false;
-  // Normal-form loops have a single backedge.
-  if (!getLoopLatch())
-    return false;
+  // Normal-form loops have a preheader, a single backedge, and all of their
+  // exits have all their predecessors inside the loop.
+  return getLoopPreheader() && getLoopLatch() && hasDedicatedExits();
+}
+
+/// hasDedicatedExits - Return true if no exit block for the loop
+/// has a predecessor that is outside the loop.
+bool Loop::hasDedicatedExits() const {
   // Sort the blocks vector so that we can use binary search to do quick
   // lookups.
   SmallPtrSet<BasicBlock *, 16> LoopBBs(block_begin(), block_end());

Modified: llvm/branches/Apple/Leela/lib/Transforms/IPO/LoopExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/IPO/LoopExtractor.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/IPO/LoopExtractor.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/IPO/LoopExtractor.cpp Thu Nov  5 15:54:02 2009
@@ -75,6 +75,10 @@
   if (L->getParentLoop())
     return false;
 
+  // If LoopSimplify form is not available, stay out of trouble.
+  if (!L->isLoopSimplifyForm())
+    return false;
+
   DominatorTree &DT = getAnalysis<DominatorTree>();
   bool Changed = false;
 

Modified: llvm/branches/Apple/Leela/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Nov  5 15:54:02 2009
@@ -536,8 +536,10 @@
   BasicBlock *ExitBlock = L->getExitBlock();
   if (!ExitBlock) return;
 
-  Instruction *InsertPt = ExitBlock->getFirstNonPHI();
   BasicBlock *Preheader = L->getLoopPreheader();
+  if (!Preheader) return;
+
+  Instruction *InsertPt = ExitBlock->getFirstNonPHI();
   BasicBlock::iterator I = Preheader->getTerminator();
   while (I != Preheader->begin()) {
     --I;

Modified: llvm/branches/Apple/Leela/lib/Transforms/Scalar/LICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Scalar/LICM.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Scalar/LICM.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Scalar/LICM.cpp Thu Nov  5 15:54:02 2009
@@ -263,7 +263,6 @@
 
   // Get the preheader block to move instructions into...
   Preheader = L->getLoopPreheader();
-  assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!");
 
   // Loop over the body of this loop, looking for calls, invokes, and stores.
   // Because subloops have already been incorporated into AST, we skip blocks in
@@ -286,12 +285,14 @@
   // us to sink instructions in one pass, without iteration.  After sinking
   // instructions, we perform another pass to hoist them out of the loop.
   //
-  SinkRegion(DT->getNode(L->getHeader()));
-  HoistRegion(DT->getNode(L->getHeader()));
+  if (L->hasDedicatedExits())
+    SinkRegion(DT->getNode(L->getHeader()));
+  if (Preheader)
+    HoistRegion(DT->getNode(L->getHeader()));
 
   // Now that all loop invariants have been removed from the loop, promote any
   // memory references to scalars that we can...
-  if (!DisablePromotion)
+  if (!DisablePromotion && Preheader && L->hasDedicatedExits())
     PromoteValuesInLoop();
 
   // Clear out loops state information for the next iteration

Modified: llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopDeletion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopDeletion.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopDeletion.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopDeletion.cpp Thu Nov  5 15:54:02 2009
@@ -115,6 +115,10 @@
   if (!preheader)
     return false;
   
+  // If LoopSimplify form is not available, stay out of trouble.
+  if (!L->hasDedicatedExits())
+    return false;
+
   // We can't remove loops that contain subloops.  If the subloops were dead,
   // they would already have been removed in earlier executions of this pass.
   if (L->begin() != L->end())

Modified: llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopIndexSplit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopIndexSplit.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopIndexSplit.cpp Thu Nov  5 15:54:02 2009
@@ -209,6 +209,10 @@
   L = IncomingLoop;
   LPM = &LPM_Ref;
 
+  // If LoopSimplify form is not available, stay out of trouble.
+  if (!L->isLoopSimplifyForm())
+    return false;
+
   // FIXME - Nested loops make dominator info updates tricky. 
   if (!L->getSubLoops().empty())
     return false;

Modified: llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopRotation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopRotation.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopRotation.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopRotation.cpp Thu Nov  5 15:54:02 2009
@@ -15,7 +15,6 @@
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Function.h"
 #include "llvm/IntrinsicInst.h"
-#include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/LoopPass.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/ScalarEvolution.h"
@@ -49,6 +48,7 @@
       AU.addRequiredID(LCSSAID);
       AU.addPreservedID(LCSSAID);
       AU.addPreserved<ScalarEvolution>();
+      AU.addRequired<LoopInfo>();
       AU.addPreserved<LoopInfo>();
       AU.addPreserved<DominatorTree>();
       AU.addPreserved<DominanceFrontier>();
@@ -104,17 +104,18 @@
 bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
   L = Lp;
 
-  OrigHeader =  L->getHeader();
   OrigPreHeader = L->getLoopPreheader();
+  if (!OrigPreHeader) return false;
+
   OrigLatch = L->getLoopLatch();
+  if (!OrigLatch) return false;
+
+  OrigHeader =  L->getHeader();
 
   // If the loop has only one block then there is not much to rotate.
   if (L->getBlocks().size() == 1)
     return false;
 
-  assert(OrigHeader && OrigLatch && OrigPreHeader &&
-         "Loop is not in canonical form");
-
   // If the loop header is not one of the loop exiting blocks then
   // either this loop is already rotated or it is not
   // suitable for loop rotation transformations.
@@ -287,7 +288,7 @@
                                                 "bb.nph",
                                                 OrigHeader->getParent(), 
                                                 NewHeader);
-  LoopInfo &LI = LPM.getAnalysis<LoopInfo>();
+  LoopInfo &LI = getAnalysis<LoopInfo>();
   if (Loop *PL = LI.getLoopFor(OrigPreHeader))
     PL->addBasicBlockToLoop(NewPreHeader, LI.getBase());
   BranchInst::Create(NewHeader, NewPreHeader);

Modified: llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Nov  5 15:54:02 2009
@@ -2528,6 +2528,10 @@
   SE = &getAnalysis<ScalarEvolution>();
   Changed = false;
 
+  // If LoopSimplify form is not available, stay out of trouble.
+  if (!L->getLoopPreheader() || !L->getLoopLatch())
+    return false;
+
   if (!IU->IVUsesByStride.empty()) {
     DEBUG(errs() << "\nLSR on \"" << L->getHeader()->getParent()->getName()
           << "\" ";

Modified: llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopUnswitch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Scalar/LoopUnswitch.cpp Thu Nov  5 15:54:02 2009
@@ -407,6 +407,10 @@
   initLoopData();
   Function *F = loopHeader->getParent();
 
+  // If LoopSimplify was unable to form a preheader, don't do any unswitching.
+  if (!loopPreheader)
+    return false;
+
   // If the condition is trivial, always unswitch.  There is no code growth for
   // this case.
   if (!IsTrivialUnswitchCondition(LoopCond)) {

Modified: llvm/branches/Apple/Leela/lib/Transforms/Utils/LCSSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Utils/LCSSA.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Utils/LCSSA.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Utils/LCSSA.cpp Thu Nov  5 15:54:02 2009
@@ -50,7 +50,6 @@
     LCSSA() : LoopPass(&ID) {}
 
     // Cached analysis information for the current function.
-    LoopInfo *LI;
     DominatorTree *DT;
     std::vector<BasicBlock*> LoopBlocks;
     PredIteratorCache PredCache;
@@ -121,7 +120,6 @@
 bool LCSSA::runOnLoop(Loop *TheLoop, LPPassManager &LPM) {
   L = TheLoop;
   
-  LI = &LPM.getAnalysis<LoopInfo>();
   DT = &getAnalysis<DominatorTree>();
 
   // Get the set of exiting blocks.

Modified: llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopSimplify.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopSimplify.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopSimplify.cpp Thu Nov  5 15:54:02 2009
@@ -233,7 +233,14 @@
   // loop-invariant instructions out of the way to open up more
   // opportunities, and the disadvantage of having the responsibility
   // to preserve dominator information.
-  if (ExitBlocks.size() > 1 && L->getUniqueExitBlock()) {
+  bool UniqueExit = true;
+  if (!ExitBlocks.empty())
+    for (unsigned i = 1, e = ExitBlocks.size(); i != e; ++i)
+      if (ExitBlocks[i] != ExitBlocks[0]) {
+        UniqueExit = false;
+        break;
+      }
+  if (UniqueExit) {
     SmallVector<BasicBlock*, 8> ExitingBlocks;
     L->getExitingBlocks(ExitingBlocks);
     for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {

Modified: llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopUnroll.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopUnroll.cpp?rev=86182&r1=86181&r2=86182&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopUnroll.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/Utils/LoopUnroll.cpp Thu Nov  5 15:54:02 2009
@@ -108,8 +108,19 @@
 bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM) {
   assert(L->isLCSSAForm());
 
-  BasicBlock *Header = L->getHeader();
+  BasicBlock *Preheader = L->getLoopPreheader();
+  if (!Preheader) {
+    DEBUG(errs() << "  Can't unroll; loop preheader-insertion failed.\n");
+    return false;
+  }
+
   BasicBlock *LatchBlock = L->getLoopLatch();
+  if (!LatchBlock) {
+    DEBUG(errs() << "  Can't unroll; loop exit-block-insertion failed.\n");
+    return false;
+  }
+
+  BasicBlock *Header = L->getHeader();
   BranchInst *BI = dyn_cast<BranchInst>(LatchBlock->getTerminator());
   
   if (!BI || BI->isUnconditional()) {

Added: llvm/branches/Apple/Leela/test/Transforms/LoopSimplify/indirectbr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/LoopSimplify/indirectbr.ll?rev=86182&view=auto

==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/LoopSimplify/indirectbr.ll (added)
+++ llvm/branches/Apple/Leela/test/Transforms/LoopSimplify/indirectbr.ll Thu Nov  5 15:54:02 2009
@@ -0,0 +1,83 @@
+; RUN: opt < %s -loopsimplify -lcssa -verify-loop-info -verify-dom-info -S \
+; RUN:   | grep -F {indirectbr i8* %x, \[label %L0, label %L1\]} \
+; RUN:   | count 6
+
+; LoopSimplify should not try to transform loops when indirectbr is involved.
+
+define void @entry(i8* %x) {
+entry:
+  indirectbr i8* %x, [ label %L0, label %L1 ]
+
+L0:
+  br label %L0
+
+L1:
+  ret void
+}
+
+define void @backedge(i8* %x) {
+entry:
+  br label %L0
+
+L0:
+  br label %L1
+
+L1:
+  indirectbr i8* %x, [ label %L0, label %L1 ]
+}
+
+define i64 @exit(i8* %x) {
+entry:
+  br label %L2
+
+L2:
+  %z = bitcast i64 0 to i64
+  indirectbr i8* %x, [ label %L0, label %L1 ]
+
+L0:
+  br label %L2
+
+L1:
+  ret i64 %z
+}
+
+define i64 @criticalexit(i8* %x, i1 %a) {
+entry:
+  br i1 %a, label %L1, label %L2
+
+L2:
+  %z = bitcast i64 0 to i64
+  indirectbr i8* %x, [ label %L0, label %L1 ]
+
+L0:
+  br label %L2
+
+L1:
+  %y = phi i64 [ %z, %L2 ], [ 1, %entry ]
+  ret i64 %y
+}
+
+define i64 @exit_backedge(i8* %x) {
+entry:
+  br label %L0
+
+L0:
+  %z = bitcast i64 0 to i64
+  indirectbr i8* %x, [ label %L0, label %L1 ]
+
+L1:
+  ret i64 %z
+}
+
+define i64 @criticalexit_backedge(i8* %x, i1 %a) {
+entry:
+  br i1 %a, label %L0, label %L1
+
+L0:
+  %z = bitcast i64 0 to i64
+  indirectbr i8* %x, [ label %L0, label %L1 ]
+
+L1:
+  %y = phi i64 [ %z, %L0 ], [ 1, %entry ]
+  ret i64 %y
+}





More information about the llvm-branch-commits mailing list