Changes in directory llvm/lib/Transforms/Scalar:
LoopRotation.cpp updated: 1.6 -> 1.7 --- Log message: Preserve canonical loop form. --- Diffs of the changes: (+55 -5) LoopRotation.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 55 insertions(+), 5 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopRotation.cpp diff -u llvm/lib/Transforms/Scalar/LoopRotation.cpp:1.6 llvm/lib/Transforms/Scalar/LoopRotation.cpp:1.7 --- llvm/lib/Transforms/Scalar/LoopRotation.cpp:1.6 Mon Apr 9 14:04:21 2007 +++ llvm/lib/Transforms/Scalar/LoopRotation.cpp Mon Apr 9 15:19:46 2007 @@ -75,6 +75,11 @@ /// not available. const RenameData *findReplacementData(Instruction *I); + /// After loop rotation, loop pre-header has multiple sucessors. + /// Insert one forwarding basic block to ensure that loop pre-header + /// has only one successor. + void preserveCanonicalLoopForm(LPPassManager &LPM); + private: Loop *L; @@ -121,11 +126,8 @@ if (L->getBlocks().size() == 1) return false; - if (!OrigHeader || !OrigLatch || !OrigPreHeader) - return false; - - if (!OrigHeader || !OrigLatch || !OrigPreHeader) - return false; + assert (OrigHeader && OrigLatch && OrigPreHeader && + "Loop is not in cannocial form"); // If loop header is not one of the loop exit block then // either this loop is already rotated or it is not @@ -344,6 +346,8 @@ // Make NewHeader as the new header for the loop. L->moveToHeader(NewHeader); + preserveCanonicalLoopForm(LPM); + NumRotated++; return true; } @@ -415,3 +419,49 @@ } return NULL; } + +/// After loop rotation, loop pre-header has multiple sucessors. +/// Insert one forwarding basic block to ensure that loop pre-header +/// has only one successor. +void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) { + + // Right now original pre-header has two successors, new header and + // exit block. Insert new block between original pre-header and + // new header such that loop's new pre-header has only one successor. + BasicBlock *NewPreHeader = new BasicBlock("bb.nph", OrigHeader->getParent(), + OrigPreHeader); + LoopInfo &LI = LPM.getAnalysis<LoopInfo>(); + if (Loop *PL = LI.getLoopFor(OrigPreHeader)) + PL->addBasicBlockToLoop(NewPreHeader, LI); + new BranchInst(NewHeader, NewPreHeader); + + BranchInst *OrigPH_BI = cast<BranchInst>(OrigPreHeader->getTerminator()); + if (OrigPH_BI->getSuccessor(0) == NewHeader) + OrigPH_BI->setSuccessor(0, NewPreHeader); + else { + assert (OrigPH_BI->getSuccessor(1) == NewPreHeader && + "Unexpected original pre-header terminator"); + OrigPH_BI->setSuccessor(1, NewPreHeader); + } + + for (BasicBlock::iterator I = NewHeader->begin(), E = NewHeader->end(); + I != E; ++I) { + Instruction *In = I; + PHINode *PN = dyn_cast<PHINode>(In); + if (!PN) + break; + + int index = PN->getBasicBlockIndex(OrigPreHeader); + assert (index != -1 && "Expected incoming value from Original PreHeader"); + PN->setIncomingBlock(index, NewPreHeader); + assert (PN->getBasicBlockIndex(OrigPreHeader) == -1 && + "Expected only one incoming value from Original PreHeader"); + } + + assert (NewHeader && L->getHeader() == NewHeader + && "Invalid loop header after loop rotation"); + assert (NewPreHeader && L->getLoopPreheader() == NewPreHeader + && "Invalid loop preheader after loop rotation"); + assert (L->getLoopLatch() + && "Invalid loop latch after loop rotation"); +} _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits