diff options
Diffstat (limited to 'lib/Transforms/Scalar/LoopRotation.cpp')
-rw-r--r-- | lib/Transforms/Scalar/LoopRotation.cpp | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp index 31957dd..88cb9d7 100644 --- a/lib/Transforms/Scalar/LoopRotation.cpp +++ b/lib/Transforms/Scalar/LoopRotation.cpp @@ -35,7 +35,9 @@ namespace { class LoopRotate : public LoopPass { public: static char ID; // Pass ID, replacement for typeid - LoopRotate() : LoopPass(ID) {} + LoopRotate() : LoopPass(ID) { + initializeLoopRotatePass(*PassRegistry::getPassRegistry()); + } // Rotate Loop L as many times as possible. Return true if // loop is rotated at least once. @@ -79,7 +81,11 @@ namespace { } char LoopRotate::ID = 0; -INITIALIZE_PASS(LoopRotate, "loop-rotate", "Rotate Loops", false, false); +INITIALIZE_PASS_BEGIN(LoopRotate, "loop-rotate", "Rotate Loops", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(LoopSimplify) +INITIALIZE_PASS_DEPENDENCY(LCSSA) +INITIALIZE_PASS_END(LoopRotate, "loop-rotate", "Rotate Loops", false, false) Pass *llvm::createLoopRotatePass() { return new LoopRotate(); } @@ -143,11 +149,11 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // FIXME: Use common api to estimate size. for (BasicBlock::const_iterator OI = OrigHeader->begin(), OE = OrigHeader->end(); OI != OE; ++OI) { - if (isa<PHINode>(OI)) - continue; // PHI nodes don't count. - if (isa<DbgInfoIntrinsic>(OI)) - continue; // Debug intrinsics don't count as size. - ++Size; + if (isa<PHINode>(OI)) + continue; // PHI nodes don't count. + if (isa<DbgInfoIntrinsic>(OI)) + continue; // Debug intrinsics don't count as size. + ++Size; } if (Size > MAX_HEADER_SIZE) @@ -187,13 +193,30 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { for (; PHINode *PN = dyn_cast<PHINode>(I); ++I) ValueMap[PN] = PN->getIncomingValue(PN->getBasicBlockIndex(OrigPreHeader)); - // For the rest of the instructions, create a clone in the OldPreHeader. + // For the rest of the instructions, either hoist to the OrigPreheader if + // possible or create a clone in the OldPreHeader if not. TerminatorInst *LoopEntryBranch = OrigPreHeader->getTerminator(); - for (; I != E; ++I) { - Instruction *C = I->clone(); - C->setName(I->getName()); + while (I != E) { + Instruction *Inst = I++; + + // If the instruction's operands are invariant and it doesn't read or write + // memory, then it is safe to hoist. Doing this doesn't change the order of + // execution in the preheader, but does prevent the instruction from + // executing in each iteration of the loop. This means it is safe to hoist + // something that might trap, but isn't safe to hoist something that reads + // memory (without proving that the loop doesn't write). + if (L->hasLoopInvariantOperands(Inst) && + !Inst->mayReadFromMemory() && !Inst->mayWriteToMemory() && + !isa<TerminatorInst>(Inst)) { + Inst->moveBefore(LoopEntryBranch); + continue; + } + + // Otherwise, create a duplicate of the instruction. + Instruction *C = Inst->clone(); + C->setName(Inst->getName()); C->insertBefore(LoopEntryBranch); - ValueMap[I] = C; + ValueMap[Inst] = C; } // Along with all the other instructions, we just cloned OrigHeader's @@ -221,7 +244,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // The value now exits in two versions: the initial value in the preheader // and the loop "next" value in the original header. - SSA.Initialize(OrigHeaderVal); + SSA.Initialize(OrigHeaderVal->getType(), OrigHeaderVal->getName()); SSA.AddAvailableValue(OrigHeader, OrigHeaderVal); SSA.AddAvailableValue(OrigPreHeader, OrigPreHeaderVal); |