mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
Make makeLoopInvariant report whether it made any changes or not,
and use this to simplify more code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75722 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2e2ad51ffd
commit
bdc017edac
@ -490,7 +490,8 @@ public:
|
||||
/// If InsertPt is specified, it is the point to hoist instructions to.
|
||||
/// If null, the terminator of the loop preheader is used.
|
||||
///
|
||||
bool makeLoopInvariant(Value *V, Instruction *InsertPt = 0) const;
|
||||
bool makeLoopInvariant(Value *V, bool &Changed,
|
||||
Instruction *InsertPt = 0) const;
|
||||
|
||||
/// makeLoopInvariant - If the given instruction is inside of the
|
||||
/// loop and it can be hoisted, do so to make it trivially loop-invariant.
|
||||
@ -501,7 +502,8 @@ public:
|
||||
/// If InsertPt is specified, it is the point to hoist instructions to.
|
||||
/// If null, the terminator of the loop preheader is used.
|
||||
///
|
||||
bool makeLoopInvariant(Instruction *I, Instruction *InsertPt = 0) const;
|
||||
bool makeLoopInvariant(Instruction *I, bool &Changed,
|
||||
Instruction *InsertPt = 0) const;
|
||||
|
||||
/// getCanonicalInductionVariable - Check to see if the loop has a canonical
|
||||
/// induction variable: an integer recurrence that starts at 0 and increments
|
||||
|
@ -58,9 +58,10 @@ bool Loop::isLoopInvariant(Instruction *I) const {
|
||||
/// If InsertPt is specified, it is the point to hoist instructions to.
|
||||
/// If null, the terminator of the loop preheader is used.
|
||||
///
|
||||
bool Loop::makeLoopInvariant(Value *V, Instruction *InsertPt) const {
|
||||
bool Loop::makeLoopInvariant(Value *V, bool &Changed,
|
||||
Instruction *InsertPt) const {
|
||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
||||
return makeLoopInvariant(I);
|
||||
return makeLoopInvariant(I, Changed, InsertPt);
|
||||
return true; // All non-instructions are loop-invariant.
|
||||
}
|
||||
|
||||
@ -73,7 +74,8 @@ bool Loop::makeLoopInvariant(Value *V, Instruction *InsertPt) const {
|
||||
/// If InsertPt is specified, it is the point to hoist instructions to.
|
||||
/// If null, the terminator of the loop preheader is used.
|
||||
///
|
||||
bool Loop::makeLoopInvariant(Instruction *I, Instruction *InsertPt) const {
|
||||
bool Loop::makeLoopInvariant(Instruction *I, bool &Changed,
|
||||
Instruction *InsertPt) const {
|
||||
// Test if the value is already loop-invariant.
|
||||
if (isLoopInvariant(I))
|
||||
return true;
|
||||
@ -96,10 +98,11 @@ bool Loop::makeLoopInvariant(Instruction *I, Instruction *InsertPt) const {
|
||||
}
|
||||
// Don't hoist instructions with loop-variant operands.
|
||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
||||
if (!makeLoopInvariant(I->getOperand(i), InsertPt))
|
||||
if (!makeLoopInvariant(I->getOperand(i), Changed, InsertPt))
|
||||
return false;
|
||||
// Hoist.
|
||||
I->moveBefore(InsertPt);
|
||||
Changed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -38,9 +38,9 @@ namespace {
|
||||
bool SingleDominatingExit(Loop* L,
|
||||
SmallVector<BasicBlock*, 4>& exitingBlocks);
|
||||
bool IsLoopDead(Loop* L, SmallVector<BasicBlock*, 4>& exitingBlocks,
|
||||
SmallVector<BasicBlock*, 4>& exitBlocks);
|
||||
bool IsLoopInvariantInst(Instruction *I, Loop* L);
|
||||
|
||||
SmallVector<BasicBlock*, 4>& exitBlocks,
|
||||
bool &Changed, BasicBlock *Preheader);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage& AU) const {
|
||||
AU.addRequired<ScalarEvolution>();
|
||||
AU.addRequired<DominatorTree>();
|
||||
@ -84,32 +84,13 @@ bool LoopDeletion::SingleDominatingExit(Loop* L,
|
||||
return DT.dominates(exitingBlocks[0], latch);
|
||||
}
|
||||
|
||||
/// IsLoopInvariantInst - Checks if an instruction is invariant with respect to
|
||||
/// a loop, which is defined as being true if all of its operands are defined
|
||||
/// outside of the loop. These instructions can be hoisted out of the loop
|
||||
/// if their results are needed. This could be made more aggressive by
|
||||
/// recursively checking the operands for invariance, but it's not clear that
|
||||
/// it's worth it.
|
||||
bool LoopDeletion::IsLoopInvariantInst(Instruction *I, Loop* L) {
|
||||
// PHI nodes are not loop invariant if defined in the loop.
|
||||
if (isa<PHINode>(I) && L->contains(I->getParent()))
|
||||
return false;
|
||||
|
||||
// The instruction is loop invariant if all of its operands are loop-invariant
|
||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
||||
if (!L->isLoopInvariant(I->getOperand(i)))
|
||||
return false;
|
||||
|
||||
// If we got this far, the instruction is loop invariant!
|
||||
return true;
|
||||
}
|
||||
|
||||
/// IsLoopDead - Determined if a loop is dead. This assumes that we've already
|
||||
/// checked for unique exit and exiting blocks, and that the code is in LCSSA
|
||||
/// form.
|
||||
bool LoopDeletion::IsLoopDead(Loop* L,
|
||||
SmallVector<BasicBlock*, 4>& exitingBlocks,
|
||||
SmallVector<BasicBlock*, 4>& exitBlocks) {
|
||||
SmallVector<BasicBlock*, 4>& exitBlocks,
|
||||
bool &Changed, BasicBlock *Preheader) {
|
||||
BasicBlock* exitingBlock = exitingBlocks[0];
|
||||
BasicBlock* exitBlock = exitBlocks[0];
|
||||
|
||||
@ -122,7 +103,7 @@ bool LoopDeletion::IsLoopDead(Loop* L,
|
||||
while (PHINode* P = dyn_cast<PHINode>(BI)) {
|
||||
Value* incoming = P->getIncomingValueForBlock(exitingBlock);
|
||||
if (Instruction* I = dyn_cast<Instruction>(incoming))
|
||||
if (!IsLoopInvariantInst(I, L))
|
||||
if (!L->makeLoopInvariant(I, Changed, Preheader->getTerminator()))
|
||||
return false;
|
||||
|
||||
BI++;
|
||||
@ -181,15 +162,16 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) {
|
||||
return false;
|
||||
|
||||
// Finally, we have to check that the loop really is dead.
|
||||
if (!IsLoopDead(L, exitingBlocks, exitBlocks))
|
||||
return false;
|
||||
bool Changed = false;
|
||||
if (!IsLoopDead(L, exitingBlocks, exitBlocks, Changed, preheader))
|
||||
return Changed;
|
||||
|
||||
// Don't remove loops for which we can't solve the trip count.
|
||||
// They could be infinite, in which case we'd be changing program behavior.
|
||||
ScalarEvolution& SE = getAnalysis<ScalarEvolution>();
|
||||
const SCEV *S = SE.getBackedgeTakenCount(L);
|
||||
if (isa<SCEVCouldNotCompute>(S))
|
||||
return false;
|
||||
return Changed;
|
||||
|
||||
// Now that we know the removal is safe, remove the loop by changing the
|
||||
// branch from the preheader to go to the single exit block.
|
||||
@ -205,17 +187,6 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) {
|
||||
// to determine what it needs to clean up.
|
||||
SE.forgetLoopBackedgeTakenCount(L);
|
||||
|
||||
// Move simple loop-invariant expressions out of the loop, since they
|
||||
// might be needed by the exit phis.
|
||||
for (Loop::block_iterator LI = L->block_begin(), LE = L->block_end();
|
||||
LI != LE; ++LI)
|
||||
for (BasicBlock::iterator BI = (*LI)->begin(), BE = (*LI)->end();
|
||||
BI != BE; ) {
|
||||
Instruction* I = BI++;
|
||||
if (!I->use_empty() && IsLoopInvariantInst(I, L))
|
||||
I->moveBefore(preheader->getTerminator());
|
||||
}
|
||||
|
||||
// Connect the preheader directly to the exit block.
|
||||
TerminatorInst* TI = preheader->getTerminator();
|
||||
TI->replaceUsesOfWith(L->getHeader(), exitBlock);
|
||||
@ -273,8 +244,9 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) {
|
||||
// The last step is to inform the loop pass manager that we've
|
||||
// eliminated this loop.
|
||||
LPM.deleteLoopFromQueue(L);
|
||||
Changed = true;
|
||||
|
||||
NumDeleted++;
|
||||
|
||||
return true;
|
||||
return Changed;
|
||||
}
|
||||
|
@ -168,13 +168,10 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) {
|
||||
if (isa<Constant>(Cond)) return 0;
|
||||
|
||||
// TODO: Handle: br (VARIANT|INVARIANT).
|
||||
if (L->isLoopInvariant(Cond)) return Cond;
|
||||
|
||||
// Hoist simple values out.
|
||||
if (L->makeLoopInvariant(Cond)) {
|
||||
Changed = true;
|
||||
if (L->makeLoopInvariant(Cond, Changed))
|
||||
return Cond;
|
||||
}
|
||||
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Cond))
|
||||
if (BO->getOpcode() == Instruction::And ||
|
||||
|
@ -93,7 +93,7 @@ namespace {
|
||||
BasicBlock *RewriteLoopExitBlock(Loop *L, BasicBlock *Exit);
|
||||
BasicBlock *InsertPreheaderForLoop(Loop *L);
|
||||
Loop *SeparateNestedLoop(Loop *L);
|
||||
void InsertUniqueBackedgeBlock(Loop *L);
|
||||
void InsertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader);
|
||||
void PlaceSplitBlockCarefully(BasicBlock *NewBB,
|
||||
SmallVectorImpl<BasicBlock*> &SplitPreds,
|
||||
Loop *L);
|
||||
@ -244,7 +244,7 @@ ReprocessLoop:
|
||||
// If we either couldn't, or didn't want to, identify nesting of the loops,
|
||||
// insert a new block that all backedges target, then make it jump to the
|
||||
// loop header.
|
||||
InsertUniqueBackedgeBlock(L);
|
||||
InsertUniqueBackedgeBlock(L, Preheader);
|
||||
NumInserted++;
|
||||
Changed = true;
|
||||
}
|
||||
@ -288,9 +288,8 @@ ReprocessLoop:
|
||||
Instruction *Inst = I++;
|
||||
if (Inst == CI)
|
||||
continue;
|
||||
if (!L->makeLoopInvariant(Inst, Preheader->getTerminator())) {
|
||||
if (!L->makeLoopInvariant(Inst, Changed, Preheader->getTerminator())) {
|
||||
AllInvariant = false;
|
||||
Changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -574,11 +573,10 @@ Loop *LoopSimplify::SeparateNestedLoop(Loop *L) {
|
||||
/// backedges to target a new basic block and have that block branch to the loop
|
||||
/// header. This ensures that loops have exactly one backedge.
|
||||
///
|
||||
void LoopSimplify::InsertUniqueBackedgeBlock(Loop *L) {
|
||||
void LoopSimplify::InsertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader) {
|
||||
assert(L->getNumBackEdges() > 1 && "Must have > 1 backedge!");
|
||||
|
||||
// Get information about the loop
|
||||
BasicBlock *Preheader = L->getLoopPreheader();
|
||||
BasicBlock *Header = L->getHeader();
|
||||
Function *F = Header->getParent();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user