mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
- Further cleanups of LICM pass, remove extra work from previous implementation
- Do not clone instructions then insert clone outside of loop. Just move them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3951 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
94170596b7
commit
99a57216a9
@ -34,23 +34,24 @@ namespace {
|
||||
}
|
||||
|
||||
private:
|
||||
Loop *CurLoop; // The current loop we are working on...
|
||||
bool Changed; // Set to true when we change anything.
|
||||
AliasAnalysis *AA; // Currently AliasAnalysis information
|
||||
Loop *CurLoop; // The current loop we are working on...
|
||||
BasicBlock *Preheader; // The preheader block of the current loop...
|
||||
bool Changed; // Set to true when we change anything.
|
||||
AliasAnalysis *AA; // Currently AliasAnalysis information
|
||||
|
||||
/// visitLoop - Hoist expressions out of the specified loop...
|
||||
///
|
||||
void visitLoop(Loop *L);
|
||||
|
||||
/// notInCurrentLoop - Little predicate that returns true if the specified
|
||||
/// inCurrentLoop - Little predicate that returns false if the specified
|
||||
/// basic block is in a subloop of the current one, not the current one
|
||||
/// itself.
|
||||
///
|
||||
bool notInCurrentLoop(BasicBlock *BB) {
|
||||
bool inCurrentLoop(BasicBlock *BB) {
|
||||
for (unsigned i = 0, e = CurLoop->getSubLoops().size(); i != e; ++i)
|
||||
if (CurLoop->getSubLoops()[i]->contains(BB))
|
||||
return true; // A subloop actually contains this block!
|
||||
return false;
|
||||
return false; // A subloop actually contains this block!
|
||||
return true;
|
||||
}
|
||||
|
||||
/// hoist - When an instruction is found to only use loop invariant operands
|
||||
@ -71,10 +72,6 @@ namespace {
|
||||
return true; // All non-instructions are loop invariant
|
||||
}
|
||||
|
||||
/// visitBasicBlock - Run LICM on a particular block.
|
||||
///
|
||||
void visitBasicBlock(BasicBlock *BB);
|
||||
|
||||
/// Instruction visitation handlers... these basically control whether or
|
||||
/// not the specified instruction types are hoisted.
|
||||
///
|
||||
@ -108,7 +105,7 @@ Pass *createLICMPass() { return new LICM(); }
|
||||
/// function, hoisting expressions out of loops if possible.
|
||||
///
|
||||
bool LICM::runOnFunction(Function &) {
|
||||
// get our loop information...
|
||||
// Get information about the top level loops in the function...
|
||||
const std::vector<Loop*> &TopLevelLoops =
|
||||
getAnalysis<LoopInfo>().getTopLevelLoops();
|
||||
|
||||
@ -133,41 +130,25 @@ void LICM::visitLoop(Loop *L) {
|
||||
bind_obj(this, &LICM::visitLoop));
|
||||
CurLoop = L;
|
||||
|
||||
// Get the preheader block to move instructions into...
|
||||
Preheader = L->getLoopPreheader();
|
||||
assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!");
|
||||
|
||||
// We want to visit all of the instructions in this loop... that are not parts
|
||||
// of our subloops (they have already had their invariants hoisted out of
|
||||
// their loop, into this loop, so there is no need to process the BODIES of
|
||||
// the subloops).
|
||||
//
|
||||
std::vector<BasicBlock*> BBs(L->getBlocks().begin(), L->getBlocks().end());
|
||||
|
||||
// Remove blocks that are actually in subloops...
|
||||
BBs.erase(std::remove_if(BBs.begin(), BBs.end(),
|
||||
bind_obj(this, &LICM::notInCurrentLoop)), BBs.end());
|
||||
|
||||
// Visit all of the basic blocks we have chosen, hoisting out the instructions
|
||||
// as neccesary. This leaves dead copies of the instruction in the loop
|
||||
// unfortunately...
|
||||
//
|
||||
for_each(BBs.begin(), BBs.end(), bind_obj(this, &LICM::visitBasicBlock));
|
||||
for (std::vector<BasicBlock*>::const_iterator
|
||||
I = L->getBlocks().begin(), E = L->getBlocks().end(); I != E; ++I)
|
||||
if (inCurrentLoop(*I))
|
||||
visit(**I);
|
||||
|
||||
// Clear out loops state information for the next iteration
|
||||
CurLoop = 0;
|
||||
Preheader = 0;
|
||||
}
|
||||
|
||||
/// visitBasicBlock - Run LICM on a particular block.
|
||||
///
|
||||
void LICM::visitBasicBlock(BasicBlock *BB) {
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
|
||||
visit(*I);
|
||||
|
||||
if (dceInstruction(I))
|
||||
Changed = true;
|
||||
else
|
||||
++I;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// hoist - When an instruction is found to only use loop invariant operands
|
||||
/// that is safe to hoist, this instruction is called to do the dirty work.
|
||||
///
|
||||
@ -177,39 +158,24 @@ void LICM::hoist(Instruction &Inst) {
|
||||
|
||||
BasicBlock *Header = CurLoop->getHeader();
|
||||
|
||||
// Old instruction will be removed, so take it's name...
|
||||
string InstName = Inst.getName();
|
||||
Inst.setName("");
|
||||
|
||||
if (isa<LoadInst>(Inst))
|
||||
++NumHoistedLoads;
|
||||
|
||||
// The common case is that we have a pre-header. Generate special case code
|
||||
// that is faster if that is the case.
|
||||
//
|
||||
BasicBlock *Preheader = CurLoop->getLoopPreheader();
|
||||
assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!");
|
||||
|
||||
// Create a new copy of the instruction, for insertion into Preheader.
|
||||
Instruction *New = Inst.clone();
|
||||
New->setName(InstName);
|
||||
// Remove the instruction from its current basic block... but don't delete the
|
||||
// instruction.
|
||||
Inst.getParent()->getInstList().remove(&Inst);
|
||||
|
||||
// Insert the new node in Preheader, before the terminator.
|
||||
Preheader->getInstList().insert(--Preheader->end(), New);
|
||||
Preheader->getInstList().insert(Preheader->getTerminator(), &Inst);
|
||||
|
||||
// Kill the old instruction...
|
||||
Inst.replaceAllUsesWith(New);
|
||||
++NumHoisted;
|
||||
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
|
||||
void LICM::visitLoadInst(LoadInst &LI) {
|
||||
if (isLoopInvariant(LI.getOperand(0)) &&
|
||||
!pointerInvalidatedByLoop(LI.getOperand(0)))
|
||||
!pointerInvalidatedByLoop(LI.getOperand(0))) {
|
||||
hoist(LI);
|
||||
|
||||
++NumHoistedLoads;
|
||||
}
|
||||
}
|
||||
|
||||
/// pointerInvalidatedByLoop - Return true if the body of this loop may store
|
||||
|
Loading…
Reference in New Issue
Block a user