From 322313376a9ccac86cbfc208684d84936d62322d Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 9 Apr 2007 16:11:48 +0000 Subject: [PATCH] Only cosmetic changes. Zero functionality Change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35819 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopRotation.cpp | 193 +++++++++++++------------ 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp index edcfe7eb68d..04347b8d813 100644 --- a/lib/Transforms/Scalar/LoopRotation.cpp +++ b/lib/Transforms/Scalar/LoopRotation.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "loop-rotation" +#define DEBUG_TYPE "loop-rotate" #include "llvm/Transforms/Scalar.h" #include "llvm/Function.h" @@ -23,7 +23,6 @@ #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallVector.h" -#include using namespace llvm; @@ -32,29 +31,28 @@ using namespace llvm; STATISTIC(NumRotated, "Number of loops rotated"); namespace { - cl::opt - RotateThreshold("rotate-threshold", cl::init(200), cl::Hidden, - cl::desc("The cut-off point for loop rotating")); - - class VISIBILITY_HIDDEN InsnReplacementData { + class VISIBILITY_HIDDEN RenameData { public: - InsnReplacementData(Instruction *O, Instruction *P, Instruction *H) - : Original(O), PreHeader(P), Header(H) {} + RenameData(Instruction *O, Instruction *P, Instruction *H) + : Original(O), PreHeader(P), Header(H) { } public: Instruction *Original; // Original instruction Instruction *PreHeader; // New pre-header replacement Instruction *Header; // New header replacement }; - + class VISIBILITY_HIDDEN LoopRotate : public LoopPass { public: + + // Rotate Loop L as many times as possible. Return true if + // loop is rotated at least once. bool runOnLoop(Loop *L, LPPassManager &LPM); + + // LCSSA form makes instruction renaming easier. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredID(LCSSAID); AU.addPreservedID(LCSSAID); - //AU.addRequired(); - //AU.addPreserved(); } // Helper functions @@ -75,7 +73,7 @@ namespace { /// Find Replacement information for instruction. Return NULL if it is /// not available. - InsnReplacementData *findReplacementData(Instruction *I); + RenameData *findReplacementData(Instruction *I); private: @@ -87,7 +85,7 @@ namespace { BasicBlock *NewPreHeader; BasicBlock *Exit; - SmallVector RD; + SmallVector LoopHeaderInfo; }; RegisterPass X ("loop-rotate", "Rotate Loops"); @@ -95,6 +93,8 @@ namespace { LoopPass *llvm::createLoopRotatePass() { return new LoopRotate(); } +/// Rotate Loop L as many times as possible. Return true if +/// loop is rotated at least once. bool LoopRotate::runOnLoop(Loop *Lp, LPPassManager &LPM) { bool RotatedOneLoop = false; @@ -109,18 +109,17 @@ bool LoopRotate::runOnLoop(Loop *Lp, LPPassManager &LPM) { return RotatedOneLoop; } +/// Rotate loop LP. Return true if it loop is rotated. bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { L = Lp; - if ( NumRotated >= RotateThreshold) - return false; OrigHeader = L->getHeader(); OrigPreHeader = L->getLoopPreheader(); OrigLatch = L->getLoopLatch(); // If loop has only one block then there is not much to rotate. - if (L->getBlocks().size() <= 1) + if (L->getBlocks().size() == 1) return false; if (!OrigHeader || !OrigLatch || !OrigPreHeader) @@ -135,33 +134,27 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { BranchInst *BI = dyn_cast(OrigHeader->getTerminator()); if (!BI) return false; + assert (BI->isConditional() && "Branch Instruction is not condiitional"); + // Updating PHInodes in loops with multiple exits adds complexity. + // Keep it simple, and restrict loop rotation to loops with one exit only. + // In future, lift this restriction and support for multiple exits if + // required. std::vector ExitBlocks; L->getExitBlocks(ExitBlocks); if (ExitBlocks.size() > 1) return false; // Find new Loop header. NewHeader is a Header's one and only successor - // that is inside loop. Header's all other successors are out side the + // that is inside loop. Header's other successor is out side the // loop. Otherwise loop is not suitable for rotation. - for (unsigned index = 0; index < BI->getNumSuccessors(); ++index) { - BasicBlock *S = BI->getSuccessor(index); - if (L->contains(S)) { - if (!NewHeader) - NewHeader = S; - else - // Loop Header has two successors inside loop. This loop is - // not suitable for rotation. - return false; - } else { - if (!Exit) - Exit = S; - else - // Loop has multiple exits. - return false; - } - } + Exit = BI->getSuccessor(0); + NewHeader = BI->getSuccessor(1); + if (L->contains(Exit)) + std::swap(Exit, NewHeader); assert (NewHeader && "Unable to determine new loop header"); + assert(L->contains(NewHeader) && !L->contains(Exit) && + "Unable to determine loop header and exit blocks"); // Check size of original header and reject // loop if it is very big. @@ -170,7 +163,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // Now, this loop is suitable for rotation. - // Copy Prepare PHI nodes and other instructions from original header + // Copy PHI nodes and other instructions from original header // into new pre-header. Unlike original header, new pre-header is // not a member of loop. New pre-header has only one predecessor, // that is original loop pre-header. @@ -185,59 +178,69 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // from new loop pre-header (which is a clone of original header definition). NewPreHeader = new BasicBlock("bb.nph", OrigHeader->getParent(), OrigHeader); - for (BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end(); - I != E; ++I) { + BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end(); + for (; I != E; ++I) { Instruction *In = I; - if (PHINode *PN = dyn_cast(I)) { + PHINode *PN = dyn_cast(I); + if (!PN) + break; - // Create new PHI node with one value incoming from OrigPreHeader. - // NewPreHeader has only one predecessor, OrigPreHeader. - PHINode *NPH = new PHINode(In->getType(), In->getName()); - NPH->addIncoming(PN->getIncomingValueForBlock(OrigPreHeader), - OrigPreHeader); - NewPreHeader->getInstList().push_back(NPH); - - // Create new PHI node with two incoming values for NewHeader. - // One incoming value is from OrigLatch (through OrigHeader) and - // second incoming value is from NewPreHeader. - PHINode *NH = new PHINode(In->getType(), In->getName()); - NH->addIncoming(PN->getIncomingValueForBlock(OrigLatch), OrigHeader); - NH->addIncoming(NPH, NewPreHeader); - NewHeader->getInstList().push_front(NH); + // Create new PHI node with one value incoming from OrigPreHeader. + // NewPreHeader has only one predecessor, OrigPreHeader. + PHINode *NPH = new PHINode(In->getType(), In->getName()); + NPH->addIncoming(PN->getIncomingValueForBlock(OrigPreHeader), + OrigPreHeader); + NewPreHeader->getInstList().push_back(NPH); + + // Create new PHI node with two incoming values for NewHeader. + // One incoming value is from OrigLatch (through OrigHeader) and + // second incoming value is from NewPreHeader. + PHINode *NH = new PHINode(In->getType(), In->getName()); + NH->addIncoming(PN->getIncomingValueForBlock(OrigLatch), OrigHeader); + NH->addIncoming(NPH, NewPreHeader); + NewHeader->getInstList().push_front(NH); + + // "In" can be replaced by NPH or NH at various places. + LoopHeaderInfo.push_back(RenameData(In, NPH, NH)); + } - RD.push_back(InsnReplacementData(In, NPH, NH)); - } else { - // This is not a PHI instruction. Insert its clone into NewPreHeader. - // If this instruction is using a value from same basic block then - // update it to use value from cloned instruction. - Instruction *C = In->clone(); - C->setName(In->getName()); - NewPreHeader->getInstList().push_back(C); + // Now, handle non-phi instructions. + for (; I != E; ++I) { + Instruction *In = I; - // If this instruction is used outside this basic block then - // create new PHINode for this instruction. - Instruction *NewHeaderReplacement = NULL; - if (usedOutsideOriginalHeader(In)) { - PHINode *PN = new PHINode(In->getType(), In->getName()); - PN->addIncoming(In, OrigHeader); - PN->addIncoming(C, NewPreHeader); - NewHeader->getInstList().push_front(PN); - NewHeaderReplacement = PN; - } - RD.push_back(InsnReplacementData(In, C, NewHeaderReplacement)); - } + assert (!isa(In) && "PHINode is not expected here"); + // This is not a PHI instruction. Insert its clone into NewPreHeader. + // If this instruction is using a value from same basic block then + // update it to use value from cloned instruction. + Instruction *C = In->clone(); + C->setName(In->getName()); + NewPreHeader->getInstList().push_back(C); + + // If this instruction is used outside this basic block then + // create new PHINode for this instruction. + Instruction *NewHeaderReplacement = NULL; + if (usedOutsideOriginalHeader(In)) { + PHINode *PN = new PHINode(In->getType(), In->getName()); + PN->addIncoming(In, OrigHeader); + PN->addIncoming(C, NewPreHeader); + NewHeader->getInstList().push_front(PN); + NewHeaderReplacement = PN; + } + + // "In" can be replaced by NPH or NH at various places. + LoopHeaderInfo.push_back(RenameData(In, C, NewHeaderReplacement)); } // Update new pre-header. // Rename values that are defined in original header to reflects values // defined in new pre-header. - for (SmallVector::iterator - I = RD.begin(), E = RD.end(); I != E; ++I) { + for (SmallVector::iterator + I = LoopHeaderInfo.begin(), E = LoopHeaderInfo.end(); I != E; ++I) { - InsnReplacementData IRD = (*I); - Instruction *In = IRD.Original; - Instruction *C = IRD.PreHeader; + RenameData ILoopHeaderInfo = (*I); + Instruction *In = ILoopHeaderInfo.Original; + Instruction *C = ILoopHeaderInfo.PreHeader; if (C->getParent() != NewPreHeader) continue; @@ -248,12 +251,12 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { for (unsigned opi = 0; opi < In->getNumOperands(); ++opi) { if (Instruction *OpPhi = dyn_cast(In->getOperand(opi))) { - if (InsnReplacementData *D = findReplacementData(OpPhi)) + if (RenameData *D = findReplacementData(OpPhi)) C->setOperand(opi, D->PreHeader); } else if (Instruction *OpInsn = dyn_cast(In->getOperand(opi))) { - if (InsnReplacementData *D = findReplacementData(OpInsn)) + if (RenameData *D = findReplacementData(OpInsn)) C->setOperand(opi, D->PreHeader); } } @@ -277,15 +280,15 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // 2) Inside loop but not in original header // // Replace this use to reflect definition from new header. - for (SmallVector::iterator - I = RD.begin(), E = RD.end(); I != E; ++I) { + for (SmallVector::iterator + I = LoopHeaderInfo.begin(), E = LoopHeaderInfo.end(); I != E; ++I) { - InsnReplacementData IRD = (*I); - if (!IRD.Header) + RenameData ILoopHeaderInfo = (*I); + if (!ILoopHeaderInfo.Header) continue; - Instruction *OldPhi = IRD.Original; - Instruction *NewPhi = IRD.Header; + Instruction *OldPhi = ILoopHeaderInfo.Original; + Instruction *NewPhi = ILoopHeaderInfo.Header; // Before replacing uses, collect them first, so that iterator is // not invalidated. @@ -333,7 +336,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // UPhi already has one incoming argument from original header. // Add second incoming argument from new Pre header. - UPhi->addIncoming(IRD.PreHeader, NewPreHeader); + UPhi->addIncoming(ILoopHeaderInfo.PreHeader, NewPreHeader); } } @@ -381,9 +384,9 @@ void LoopRotate::updateExitBlock() { if (isa(V)) PN->addIncoming(V, NewPreHeader); else { - InsnReplacementData *IRD = findReplacementData(cast(V)); - assert (IRD && IRD->PreHeader && "Missing New Preheader Instruction"); - PN->addIncoming(IRD->PreHeader, NewPreHeader); + RenameData *ILoopHeaderInfo = findReplacementData(cast(V)); + assert (ILoopHeaderInfo && ILoopHeaderInfo->PreHeader && "Missing New Preheader Instruction"); + PN->addIncoming(ILoopHeaderInfo->PreHeader, NewPreHeader); } } } @@ -399,7 +402,7 @@ void LoopRotate::initialize() { NewPreHeader = NULL; Exit = NULL; - RD.clear(); + LoopHeaderInfo.clear(); } /// Return true if this instruction is used outside original header. @@ -419,11 +422,11 @@ bool LoopRotate::usedOutsideOriginalHeader(Instruction *In) { /// Find Replacement information for instruction. Return NULL if it is /// not available. -InsnReplacementData *LoopRotate::findReplacementData(Instruction *In) { +RenameData *LoopRotate::findReplacementData(Instruction *In) { - // Since RD is small, linear walk is OK. - for (SmallVector::iterator - I = RD.begin(), E = RD.end(); I != E; ++I) + // Since LoopHeaderInfo is small, linear walk is OK. + for (SmallVector::iterator + I = LoopHeaderInfo.begin(), E = LoopHeaderInfo.end(); I != E; ++I) if ((*I).Original == In) return &(*I);