mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-15 07:59:50 +00:00
Only cosmetic changes. Zero functionality Change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35819 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4746ecf16e
commit
322313376a
@ -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 <map>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -32,29 +31,28 @@ using namespace llvm;
|
||||
STATISTIC(NumRotated, "Number of loops rotated");
|
||||
namespace {
|
||||
|
||||
cl::opt<unsigned>
|
||||
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<LoopInfo>();
|
||||
//AU.addPreserved<LoopInfo>();
|
||||
}
|
||||
|
||||
// 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<InsnReplacementData, MAX_HEADER_SIZE> RD;
|
||||
SmallVector<RenameData, MAX_HEADER_SIZE> LoopHeaderInfo;
|
||||
};
|
||||
|
||||
RegisterPass<LoopRotate> 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<BranchInst>(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<BasicBlock *> 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<PHINode>(I)) {
|
||||
PHINode *PN = dyn_cast<PHINode>(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<PHINode>(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<InsnReplacementData, MAX_HEADER_SIZE>::iterator
|
||||
I = RD.begin(), E = RD.end(); I != E; ++I) {
|
||||
for (SmallVector<RenameData, MAX_HEADER_SIZE>::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<PHINode>(In->getOperand(opi))) {
|
||||
if (InsnReplacementData *D = findReplacementData(OpPhi))
|
||||
if (RenameData *D = findReplacementData(OpPhi))
|
||||
C->setOperand(opi, D->PreHeader);
|
||||
}
|
||||
else if (Instruction *OpInsn =
|
||||
dyn_cast<Instruction>(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<InsnReplacementData, MAX_HEADER_SIZE>::iterator
|
||||
I = RD.begin(), E = RD.end(); I != E; ++I) {
|
||||
for (SmallVector<RenameData, MAX_HEADER_SIZE>::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<Constant>(V))
|
||||
PN->addIncoming(V, NewPreHeader);
|
||||
else {
|
||||
InsnReplacementData *IRD = findReplacementData(cast<Instruction>(V));
|
||||
assert (IRD && IRD->PreHeader && "Missing New Preheader Instruction");
|
||||
PN->addIncoming(IRD->PreHeader, NewPreHeader);
|
||||
RenameData *ILoopHeaderInfo = findReplacementData(cast<Instruction>(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<InsnReplacementData, MAX_HEADER_SIZE>::iterator
|
||||
I = RD.begin(), E = RD.end(); I != E; ++I)
|
||||
// Since LoopHeaderInfo is small, linear walk is OK.
|
||||
for (SmallVector<RenameData, MAX_HEADER_SIZE>::iterator
|
||||
I = LoopHeaderInfo.begin(), E = LoopHeaderInfo.end(); I != E; ++I)
|
||||
if ((*I).Original == In)
|
||||
return &(*I);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user