[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopRotation.cpp
Devang Patel
dpatel at apple.com
Mon Apr 9 13:20:03 PDT 2007
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");
+}
More information about the llvm-commits
mailing list