diff options
author | Ed Schouten <ed@FreeBSD.org> | 2009-06-14 09:23:33 +0000 |
---|---|---|
committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-14 09:23:33 +0000 |
commit | 600c6fa13de5c407dc36dbb0ab73807868741ae0 (patch) | |
tree | 49817b316c4fdaa56d9d16ebf2555303d1a990e0 /lib/Analysis/ScalarEvolutionExpander.cpp | |
parent | 93338c197185f946619794ce011ec27b5b6250e2 (diff) | |
download | src-600c6fa13de5c407dc36dbb0ab73807868741ae0.tar.gz src-600c6fa13de5c407dc36dbb0ab73807868741ae0.zip |
Import LLVM r73340.vendor/llvm/llvm-r73340
Notes
Notes:
svn path=/vendor/llvm/dist/; revision=194178
svn path=/vendor/llvm/llvm-r73340/; revision=194180; tag=vendor/llvm/llvm-r73340
Diffstat (limited to 'lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r-- | lib/Analysis/ScalarEvolutionExpander.cpp | 104 |
1 files changed, 68 insertions, 36 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index ef77e46fc99a..e1f8fa421f5a 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -16,6 +16,7 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Target/TargetData.h" +#include "llvm/ADT/STLExtras.h" using namespace llvm; /// InsertCastOfTo - Insert a cast of V to the specified type, doing what @@ -319,8 +320,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEVHandle *op_begin, if (!AnyNonZeroIndices) { V = InsertNoopCastOfTo(V, Type::Int8Ty->getPointerTo(PTy->getAddressSpace())); - Value *Idx = expand(SE.getAddExpr(Ops)); - Idx = InsertNoopCastOfTo(Idx, Ty); + Value *Idx = expandCodeFor(SE.getAddExpr(Ops), Ty); // Fold a GEP with constant operands. if (Constant *CLHS = dyn_cast<Constant>(V)) @@ -374,8 +374,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { // Emit a bunch of add instructions for (int i = S->getNumOperands()-2; i >= 0; --i) { - Value *W = expand(S->getOperand(i)); - W = InsertNoopCastOfTo(W, Ty); + Value *W = expandCodeFor(S->getOperand(i), Ty); V = InsertBinop(Instruction::Add, V, W, InsertPt); } return V; @@ -389,13 +388,11 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { FirstOp = 1; int i = S->getNumOperands()-2; - Value *V = expand(S->getOperand(i+1)); - V = InsertNoopCastOfTo(V, Ty); + Value *V = expandCodeFor(S->getOperand(i+1), Ty); // Emit a bunch of multiply instructions for (; i >= FirstOp; --i) { - Value *W = expand(S->getOperand(i)); - W = InsertNoopCastOfTo(W, Ty); + Value *W = expandCodeFor(S->getOperand(i), Ty); V = InsertBinop(Instruction::Mul, V, W, InsertPt); } @@ -408,8 +405,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) { const Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *LHS = expand(S->getLHS()); - LHS = InsertNoopCastOfTo(LHS, Ty); + Value *LHS = expandCodeFor(S->getLHS(), Ty); if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(S->getRHS())) { const APInt &RHS = SC->getValue()->getValue(); if (RHS.isPowerOf2()) @@ -418,8 +414,7 @@ Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) { InsertPt); } - Value *RHS = expand(S->getRHS()); - RHS = InsertNoopCastOfTo(RHS, Ty); + Value *RHS = expandCodeFor(S->getRHS(), Ty); return InsertBinop(Instruction::UDiv, LHS, RHS, InsertPt); } @@ -448,6 +443,34 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { const Type *Ty = SE.getEffectiveSCEVType(S->getType()); const Loop *L = S->getLoop(); + // First check for an existing canonical IV in a suitable type. + PHINode *CanonicalIV = 0; + if (PHINode *PN = L->getCanonicalInductionVariable()) + if (SE.isSCEVable(PN->getType()) && + isa<IntegerType>(SE.getEffectiveSCEVType(PN->getType())) && + SE.getTypeSizeInBits(PN->getType()) >= SE.getTypeSizeInBits(Ty)) + CanonicalIV = PN; + + // Rewrite an AddRec in terms of the canonical induction variable, if + // its type is more narrow. + if (CanonicalIV && + SE.getTypeSizeInBits(CanonicalIV->getType()) > + SE.getTypeSizeInBits(Ty)) { + SCEVHandle Start = SE.getAnyExtendExpr(S->getStart(), + CanonicalIV->getType()); + SCEVHandle Step = SE.getAnyExtendExpr(S->getStepRecurrence(SE), + CanonicalIV->getType()); + Value *V = expand(SE.getAddRecExpr(Start, Step, S->getLoop())); + BasicBlock::iterator SaveInsertPt = getInsertionPoint(); + BasicBlock::iterator NewInsertPt = + next(BasicBlock::iterator(cast<Instruction>(V))); + while (isa<PHINode>(NewInsertPt)) ++NewInsertPt; + V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), 0, + NewInsertPt); + setInsertionPoint(SaveInsertPt); + return V; + } + // {X,+,F} --> X + {0,+,F} if (!S->getStart()->isZero()) { std::vector<SCEVHandle> NewOps(S->getOperands()); @@ -481,6 +504,14 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { // {0,+,1} --> Insert a canonical induction variable into the loop! if (S->isAffine() && S->getOperand(1) == SE.getIntegerSCEV(1, Ty)) { + // If there's a canonical IV, just use it. + if (CanonicalIV) { + assert(Ty == SE.getEffectiveSCEVType(CanonicalIV->getType()) && + "IVs with types different from the canonical IV should " + "already have been handled!"); + return CanonicalIV; + } + // Create and insert the PHI node for the induction variable in the // specified loop. BasicBlock *Header = L->getHeader(); @@ -508,19 +539,16 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { return PN; } + // {0,+,F} --> {0,+,1} * F // Get the canonical induction variable I for this loop. - Value *I = getOrInsertCanonicalInductionVariable(L, Ty); + Value *I = CanonicalIV ? + CanonicalIV : + 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 = expand(S->getOperand(1)); - F = InsertNoopCastOfTo(F, Ty); - - // IF the step is by one, just return the inserted IV. - if (ConstantInt *CI = dyn_cast<ConstantInt>(F)) - if (CI->getValue() == 1) - return I; - + 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 @@ -555,16 +583,24 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { // into this folder. SCEVHandle IH = SE.getUnknown(I); // Get I as a "symbolic" SCEV. - SCEVHandle V = S->evaluateAtIteration(IH, SE); + // Promote S up to the canonical IV type, if the cast is foldable. + SCEVHandle NewS = S; + SCEVHandle Ext = SE.getNoopOrAnyExtend(S, I->getType()); + if (isa<SCEVAddRecExpr>(Ext)) + NewS = Ext; + + SCEVHandle V = cast<SCEVAddRecExpr>(NewS)->evaluateAtIteration(IH, SE); //cerr << "Evaluated: " << *this << "\n to: " << *V << "\n"; + // Truncate the result down to the original type, if needed. + SCEVHandle T = SE.getTruncateOrNoop(V, Ty); return expand(V); } Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) { const Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *V = expand(S->getOperand()); - V = InsertNoopCastOfTo(V, SE.getEffectiveSCEVType(V->getType())); + Value *V = expandCodeFor(S->getOperand(), + SE.getEffectiveSCEVType(S->getOperand()->getType())); Instruction *I = new TruncInst(V, Ty, "tmp.", InsertPt); InsertedValues.insert(I); return I; @@ -572,8 +608,8 @@ Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) { Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) { const Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *V = expand(S->getOperand()); - V = InsertNoopCastOfTo(V, SE.getEffectiveSCEVType(V->getType())); + Value *V = expandCodeFor(S->getOperand(), + SE.getEffectiveSCEVType(S->getOperand()->getType())); Instruction *I = new ZExtInst(V, Ty, "tmp.", InsertPt); InsertedValues.insert(I); return I; @@ -581,8 +617,8 @@ Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) { Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) { const Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *V = expand(S->getOperand()); - V = InsertNoopCastOfTo(V, SE.getEffectiveSCEVType(V->getType())); + Value *V = expandCodeFor(S->getOperand(), + SE.getEffectiveSCEVType(S->getOperand()->getType())); Instruction *I = new SExtInst(V, Ty, "tmp.", InsertPt); InsertedValues.insert(I); return I; @@ -590,11 +626,9 @@ Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) { Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) { const Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *LHS = expand(S->getOperand(0)); - LHS = InsertNoopCastOfTo(LHS, Ty); + Value *LHS = expandCodeFor(S->getOperand(0), Ty); for (unsigned i = 1; i < S->getNumOperands(); ++i) { - Value *RHS = expand(S->getOperand(i)); - RHS = InsertNoopCastOfTo(RHS, Ty); + Value *RHS = expandCodeFor(S->getOperand(i), Ty); Instruction *ICmp = new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS, "tmp", InsertPt); InsertedValues.insert(ICmp); @@ -607,11 +641,9 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) { Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) { const Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *LHS = expand(S->getOperand(0)); - LHS = InsertNoopCastOfTo(LHS, Ty); + Value *LHS = expandCodeFor(S->getOperand(0), Ty); for (unsigned i = 1; i < S->getNumOperands(); ++i) { - Value *RHS = expand(S->getOperand(i)); - RHS = InsertNoopCastOfTo(RHS, Ty); + Value *RHS = expandCodeFor(S->getOperand(i), Ty); Instruction *ICmp = new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS, "tmp", InsertPt); InsertedValues.insert(ICmp); |