Don't unroll loops whose header block's address is taken.
authorChris Lattner <sabre@nondot.org>
Fri, 18 Feb 2011 04:25:21 +0000 (04:25 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 18 Feb 2011 04:25:21 +0000 (04:25 +0000)
This is part of a futile attempt to not "break" bizzaro
code like this:

 l1:
  printf("l1: %p\n", &&l1);
  ++x;

  if( x < 3 ) goto l1;

Previously we'd fold &&l1 to 1, which is fine per our semantics
but not helpful to the user.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125827 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/LoopUnroll.cpp

index dd8c154fdd7fc26336e151d953d49eb37de22299..7da7271e642ccee011e492b49bbf658bf645674d 100644 (file)
@@ -96,7 +96,7 @@ static BasicBlock *FoldBlockIntoPredecessor(BasicBlock *BB, LoopInfo* LI) {
 }
 
 /// Unroll the given loop by Count. The loop must be in LCSSA form. Returns true
-/// if unrolling was succesful, or false if the loop was unmodified. Unrolling
+/// if unrolling was successful, or false if the loop was unmodified. Unrolling
 /// can only fail when the loop's latch block is not terminated by a conditional
 /// branch instruction. However, if the trip count (and multiple) are not known,
 /// loop unrolling will mostly produce more code that is no faster.
@@ -105,7 +105,8 @@ static BasicBlock *FoldBlockIntoPredecessor(BasicBlock *BB, LoopInfo* LI) {
 ///
 /// If a LoopPassManager is passed in, and the loop is fully removed, it will be
 /// removed from the LoopPassManager as well. LPM can also be NULL.
-bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM) {
+bool llvm::UnrollLoop(Loop *L, unsigned Count,
+                      LoopInfo *LI, LPPassManager *LPM) {
   BasicBlock *Preheader = L->getLoopPreheader();
   if (!Preheader) {
     DEBUG(dbgs() << "  Can't unroll; loop preheader-insertion failed.\n");
@@ -127,6 +128,13 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM)
              "  Can't unroll; loop not terminated by a conditional branch.\n");
     return false;
   }
+  
+  if (Header->hasAddressTaken()) {
+    // The loop-rotate pass can be helpful to avoid this in many cases.
+    DEBUG(dbgs() <<
+          "  Won't unroll loop: address of header block is taken.\n");
+    return false;
+  }
 
   // Notify ScalarEvolution that the loop will be substantially changed,
   // if not outright eliminated.