Check for volatile loads only once.
[oota-llvm.git] / lib / Transforms / Scalar / LoopUnroll.cpp
index 1b807873e6a4e35a1c9032ecb487533834b184f7..75df8bb72814fd882573ed2ecbdde39ac242b49e 100644 (file)
@@ -1,10 +1,10 @@
 //===-- LoopUnroll.cpp - Loop unroller pass -------------------------------===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This pass implements a simple loop unroller.  It works best when loops have
@@ -88,7 +88,7 @@ static unsigned ApproximateLoopSize(const Loop *L) {
       } else if (I->hasOneUse() && I->use_back() == Term) {
         // Ignore instructions only used by the loop terminator.
       } else if (DbgInfoIntrinsic *DbgI = dyn_cast<DbgInfoIntrinsic>(I)) {
-       // Ignore debug instructions 
+        // Ignore debug instructions
       } else {
         ++Size;
       }
@@ -102,10 +102,10 @@ static unsigned ApproximateLoopSize(const Loop *L) {
   return Size;
 }
 
-// RemapInstruction - Convert the instruction operands from referencing the 
+// RemapInstruction - Convert the instruction operands from referencing the
 // current values into those specified by ValueMap.
 //
-static inline void RemapInstruction(Instruction *I, 
+static inline void RemapInstruction(Instruction *I,
                                     std::map<const Value *, Value*> &ValueMap) {
   for (unsigned op = 0, E = I->getNumOperands(); op != E; ++op) {
     Value *Op = I->getOperand(op);
@@ -136,21 +136,23 @@ bool LoopUnroll::visitLoop(Loop *L) {
   ConstantInt *TripCountC = dyn_cast_or_null<ConstantInt>(L->getTripCount());
   if (!TripCountC) return Changed;  // Must have constant trip count!
 
-  unsigned TripCount = TripCountC->getRawValue();
-  if (TripCount != TripCountC->getRawValue() || TripCount == 0)
+  uint64_t TripCountFull = TripCountC->getRawValue();
+  if (TripCountFull != TripCountC->getRawValue() || TripCountFull == 0)
     return Changed; // More than 2^32 iterations???
 
   unsigned LoopSize = ApproximateLoopSize(L);
   DEBUG(std::cerr << "Loop Unroll: F[" << BB->getParent()->getName()
         << "] Loop %" << BB->getName() << " Loop Size = " << LoopSize
-        << " Trip Count = " << TripCount << " - ");
-  uint64_t Size = (uint64_t)LoopSize*(uint64_t)TripCount;
+        << " Trip Count = " << TripCountFull << " - ");
+  uint64_t Size = (uint64_t)LoopSize*TripCountFull;
   if (Size > UnrollThreshold) {
     DEBUG(std::cerr << "TOO LARGE: " << Size << ">" << UnrollThreshold << "\n");
     return Changed;
   }
   DEBUG(std::cerr << "UNROLLING!\n");
-  
+
+  unsigned TripCount = (unsigned)TripCountFull;
+
   BasicBlock *LoopExit = BI->getSuccessor(L->contains(BI->getSuccessor(0)));
 
   // Create a new basic block to temporarily hold all of the cloned code.
@@ -233,7 +235,7 @@ bool LoopUnroll::visitLoop(Loop *L) {
     PN->replaceAllUsesWith(PN->getIncomingValueForBlock(Preheader));
     BB->getInstList().erase(PN);
   }
+
   // Finally, add an unconditional branch to the block to continue into the exit
   // block.
   new BranchInst(LoopExit, BB);
@@ -243,7 +245,7 @@ bool LoopUnroll::visitLoop(Loop *L) {
   // go.
   for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
     Instruction *Inst = I++;
-    
+
     if (isInstructionTriviallyDead(Inst))
       BB->getInstList().erase(Inst);
     else if (Constant *C = ConstantFoldInstruction(Inst)) {
@@ -281,16 +283,27 @@ bool LoopUnroll::visitLoop(Loop *L) {
   // Preheader.
   Preheader->replaceAllUsesWith(LoopExit);
 
+  Function *F = LoopExit->getParent();
+  if (Parent) {
+    // Otherwise, if this is a sub-loop, and the preheader was the loop header
+    // of the parent loop, move the exit block to be the new parent loop header.
+    if (Parent->getHeader() == Preheader) {
+      assert(Parent->contains(LoopExit) &&
+             "Exit block isn't contained in parent?");
+      Parent->moveToHeader(LoopExit);
+    }
+  } else {
+    // If the preheader was the entry block of this function, move the exit
+    // block to be the new entry of the function.
+    if (Preheader == &F->front())
+      F->getBasicBlockList().splice(F->begin(),
+                                    F->getBasicBlockList(), LoopExit);
+  }
+
   // Remove BB and LoopExit from our analyses.
   LI->removeBlock(Preheader);
   LI->removeBlock(BB);
 
-  // If the preheader was the entry block of this function, move the exit block
-  // to be the new entry of the loop.
-  Function *F = LoopExit->getParent();
-  if (Preheader == &F->front())
-    F->getBasicBlockList().splice(F->begin(), F->getBasicBlockList(), LoopExit);
-
   // Actually delete the blocks now.
   F->getBasicBlockList().erase(Preheader);
   F->getBasicBlockList().erase(BB);