summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-06-24 01:18:18 +0000
committerDan Gohman <gohman@apple.com>2009-06-24 01:18:18 +0000
commitf19aeec3f573e00627eda03d92d6b446660a8819 (patch)
treeb4c9847c61ff86b754fdc557999b76fe0bfd7301 /llvm/lib/Analysis/ScalarEvolutionExpander.cpp
parent33420090ae83aca1155917d6834f5e1ec53407c2 (diff)
downloadbcm5719-llvm-f19aeec3f573e00627eda03d92d6b446660a8819.tar.gz
bcm5719-llvm-f19aeec3f573e00627eda03d92d6b446660a8819.zip
Extend ScalarEvolution's multiple-exit support to compute exact
trip counts in more cases. Generalize ScalarEvolution's isLoopGuardedByCond code to recognize And and Or conditions, splitting the code out into an isNecessaryCond helper function so that it can evaluate Ands and Ors recursively, and make SCEVExpander be much more aggressive about hoisting instructions out of loops. test/CodeGen/X86/pr3495.ll has an additional instruction now, but it appears to be due to an arbitrary register allocation difference. llvm-svn: 74048
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolutionExpander.cpp104
1 files changed, 58 insertions, 46 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
index c5591d70273..6d7abc02ebe 100644
--- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -51,21 +51,26 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
if (Argument *A = dyn_cast<Argument>(V)) {
// Check to see if there is already a cast!
for (Value::use_iterator UI = A->use_begin(), E = A->use_end();
- UI != E; ++UI) {
+ UI != E; ++UI)
if ((*UI)->getType() == Ty)
if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI)))
if (CI->getOpcode() == opcode) {
// If the cast isn't the first instruction of the function, move it.
- if (BasicBlock::iterator(CI) !=
+ if (BasicBlock::iterator(CI) !=
A->getParent()->getEntryBlock().begin()) {
- // If the CastInst is the insert point, change the insert point.
- if (CI == InsertPt) ++InsertPt;
- // Splice the cast at the beginning of the entry block.
- CI->moveBefore(A->getParent()->getEntryBlock().begin());
+ // Recreate the cast at the beginning of the entry block.
+ // The old cast is left in place in case it is being used
+ // as an insert point.
+ Instruction *NewCI =
+ CastInst::Create(opcode, V, Ty, "",
+ A->getParent()->getEntryBlock().begin());
+ NewCI->takeName(CI);
+ CI->replaceAllUsesWith(NewCI);
+ return NewCI;
}
return CI;
}
- }
+
Instruction *I = CastInst::Create(opcode, V, Ty, V->getName(),
A->getParent()->getEntryBlock().begin());
InsertedValues.insert(I);
@@ -85,10 +90,13 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
It = cast<InvokeInst>(I)->getNormalDest()->begin();
while (isa<PHINode>(It)) ++It;
if (It != BasicBlock::iterator(CI)) {
- // If the CastInst is the insert point, change the insert point.
- if (CI == InsertPt) ++InsertPt;
- // Splice the cast immediately after the operand in question.
- CI->moveBefore(It);
+ // Recreate the cast at the beginning of the entry block.
+ // The old cast is left in place in case it is being used
+ // as an insert point.
+ Instruction *NewCI = CastInst::Create(opcode, V, Ty, "", It);
+ NewCI->takeName(CI);
+ CI->replaceAllUsesWith(NewCI);
+ return NewCI;
}
return CI;
}
@@ -497,8 +505,9 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
}
}
- Value *RestV = expand(Rest);
- return expand(SE.getAddExpr(S->getStart(), SE.getUnknown(RestV)));
+ // Just do a normal add. Pre-expand the operands to suppress folding.
+ return expand(SE.getAddExpr(SE.getUnknown(expand(S->getStart())),
+ SE.getUnknown(expand(Rest))));
}
// {0,+,1} --> Insert a canonical induction variable into the loop!
@@ -546,36 +555,13 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
getOrInsertCanonicalInductionVariable(L, Ty);
// If this is a simple linear addrec, emit it now as a special case.
- if (S->isAffine()) { // {0,+,F} --> i*F
- Value *F = expandCodeFor(S->getOperand(1), Ty);
-
- // If the insert point is directly inside of the loop, emit the multiply at
- // the insert point. Otherwise, L is a loop that is a parent of the insert
- // point loop. If we can, move the multiply to the outer most loop that it
- // is safe to be in.
- BasicBlock::iterator MulInsertPt = getInsertionPoint();
- Loop *InsertPtLoop = SE.LI->getLoopFor(MulInsertPt->getParent());
- if (InsertPtLoop != L && InsertPtLoop &&
- L->contains(InsertPtLoop->getHeader())) {
- do {
- // If we cannot hoist the multiply out of this loop, don't.
- if (!InsertPtLoop->isLoopInvariant(F)) break;
-
- BasicBlock *InsertPtLoopPH = InsertPtLoop->getLoopPreheader();
-
- // If this loop hasn't got a preheader, we aren't able to hoist the
- // multiply.
- if (!InsertPtLoopPH)
- break;
-
- // Otherwise, move the insert point to the preheader.
- MulInsertPt = InsertPtLoopPH->getTerminator();
- InsertPtLoop = InsertPtLoop->getParentLoop();
- } while (InsertPtLoop != L);
- }
-
- return InsertBinop(Instruction::Mul, I, F, MulInsertPt);
- }
+ if (S->isAffine()) // {0,+,F} --> i*F
+ return
+ expand(SE.getTruncateOrNoop(
+ SE.getMulExpr(SE.getUnknown(I),
+ SE.getNoopOrAnyExtend(S->getOperand(1),
+ I->getType())),
+ Ty));
// If this is a chain of recurrences, turn it into a closed form, using the
// folders, then expandCodeFor the closed form. This allows the folders to
@@ -671,8 +657,31 @@ Value *SCEVExpander::expand(const SCEV *S) {
InsertedExpressions.find(S);
if (I != InsertedExpressions.end())
return I->second;
-
+
+ // Compute an insertion point for this SCEV object. Hoist the instructions
+ // as far out in the loop nest as possible.
+ BasicBlock::iterator InsertPt = getInsertionPoint();
+ BasicBlock::iterator SaveInsertPt = InsertPt;
+ for (Loop *L = SE.LI->getLoopFor(InsertPt->getParent()); ;
+ L = L->getParentLoop())
+ if (S->isLoopInvariant(L)) {
+ if (!L) break;
+ if (BasicBlock *Preheader = L->getLoopPreheader())
+ InsertPt = Preheader->getTerminator();
+ } else {
+ // If the SCEV is computable at this level, insert it into the header
+ // after the PHIs (and after any other instructions that we've inserted
+ // there) so that it is guaranteed to dominate any user inside the loop.
+ if (L && S->hasComputableLoopEvolution(L))
+ InsertPt = L->getHeader()->getFirstNonPHI();
+ while (isInsertedInstruction(InsertPt)) ++InsertPt;
+ break;
+ }
+ setInsertionPoint(InsertPt);
+
Value *V = visit(S);
+
+ setInsertionPoint(SaveInsertPt);
InsertedExpressions[S] = V;
return V;
}
@@ -686,6 +695,9 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
const Type *Ty) {
assert(Ty->isInteger() && "Can only insert integer induction variables!");
const SCEV* H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
- SE.getIntegerSCEV(1, Ty), L);
- return expand(H);
+ SE.getIntegerSCEV(1, Ty), L);
+ BasicBlock::iterator SaveInsertPt = getInsertionPoint();
+ Value *V = expandCodeFor(H, 0, L->getHeader()->begin());
+ setInsertionPoint(SaveInsertPt);
+ return V;
}
OpenPOWER on IntegriCloud