diff options
author | Nate Begeman <natebegeman@mac.com> | 2005-07-30 00:12:19 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2005-07-30 00:12:19 +0000 |
commit | 36f891bdf6cf38fcc655a0930ca18664e18518d4 (patch) | |
tree | 54d8216889ee5f07f9118ad0c686c6e6510521f2 /lib/Transforms/Scalar/IndVarSimplify.cpp | |
parent | 01546c5d500054ba45bda835898f1c96dc8bc502 (diff) |
Break SCEVExpander out of IndVarSimplify into its own .h/.cpp file so that
other passes may use it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22557 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 239 |
1 files changed, 1 insertions, 238 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 5b7e4e1fd9..82bab5acd0 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -42,7 +42,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Type.h" -#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" #include "llvm/Support/GetElementPtrTypeIterator.h" @@ -52,243 +52,6 @@ using namespace llvm; namespace { - /// SCEVExpander - This class uses information about analyze scalars to - /// rewrite expressions in canonical form. - /// - /// Clients should create an instance of this class when rewriting is needed, - /// and destroying it when finished to allow the release of the associated - /// memory. - struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { - ScalarEvolution &SE; - LoopInfo &LI; - std::map<SCEVHandle, Value*> InsertedExpressions; - std::set<Instruction*> InsertedInstructions; - - Instruction *InsertPt; - - friend struct SCEVVisitor<SCEVExpander, Value*>; - public: - SCEVExpander(ScalarEvolution &se, LoopInfo &li) : SE(se), LI(li) {} - - /// isInsertedInstruction - Return true if the specified instruction was - /// inserted by the code rewriter. If so, the client should not modify the - /// instruction. - bool isInsertedInstruction(Instruction *I) const { - return InsertedInstructions.count(I); - } - - /// getOrInsertCanonicalInductionVariable - This method returns the - /// canonical induction variable of the specified type for the specified - /// loop (inserting one if there is none). A canonical induction variable - /// starts at zero and steps by one on each iteration. - Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty){ - assert((Ty->isInteger() || Ty->isFloatingPoint()) && - "Can only insert integer or floating point induction variables!"); - SCEVHandle H = SCEVAddRecExpr::get(SCEVUnknown::getIntegerSCEV(0, Ty), - SCEVUnknown::getIntegerSCEV(1, Ty), L); - return expand(H); - } - - /// addInsertedValue - Remember the specified instruction as being the - /// canonical form for the specified SCEV. - void addInsertedValue(Instruction *I, SCEV *S) { - InsertedExpressions[S] = (Value*)I; - InsertedInstructions.insert(I); - } - - /// expandCodeFor - Insert code to directly compute the specified SCEV - /// expression into the program. The inserted code is inserted into the - /// specified block. - /// - /// If a particular value sign is required, a type may be specified for the - /// result. - Value *expandCodeFor(SCEVHandle SH, Instruction *IP, const Type *Ty = 0) { - // Expand the code for this SCEV. - this->InsertPt = IP; - return expandInTy(SH, Ty); - } - - protected: - Value *expand(SCEV *S) { - // Check to see if we already expanded this. - std::map<SCEVHandle, Value*>::iterator I = InsertedExpressions.find(S); - if (I != InsertedExpressions.end()) - return I->second; - - Value *V = visit(S); - InsertedExpressions[S] = V; - return V; - } - - Value *expandInTy(SCEV *S, const Type *Ty) { - Value *V = expand(S); - if (Ty && V->getType() != Ty) { - // FIXME: keep track of the cast instruction. - if (Constant *C = dyn_cast<Constant>(V)) - return ConstantExpr::getCast(C, Ty); - else if (Instruction *I = dyn_cast<Instruction>(V)) { - // Check to see if there is already a cast. If there is, use it. - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ++UI) { - if ((*UI)->getType() == Ty) - if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI))) { - BasicBlock::iterator It = I; ++It; - if (isa<InvokeInst>(I)) - It = cast<InvokeInst>(I)->getNormalDest()->begin(); - while (isa<PHINode>(It)) ++It; - if (It != BasicBlock::iterator(CI)) { - // Splice the cast immediately after the operand in question. - BasicBlock::InstListType &InstList = - It->getParent()->getInstList(); - InstList.splice(It, CI->getParent()->getInstList(), CI); - } - return CI; - } - } - BasicBlock::iterator IP = I; ++IP; - if (InvokeInst *II = dyn_cast<InvokeInst>(I)) - IP = II->getNormalDest()->begin(); - while (isa<PHINode>(IP)) ++IP; - return new CastInst(V, Ty, V->getName(), IP); - } else { - // FIXME: check to see if there is already a cast! - return new CastInst(V, Ty, V->getName(), InsertPt); - } - } - return V; - } - - Value *visitConstant(SCEVConstant *S) { - return S->getValue(); - } - - Value *visitTruncateExpr(SCEVTruncateExpr *S) { - Value *V = expand(S->getOperand()); - return new CastInst(V, S->getType(), "tmp.", InsertPt); - } - - Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S) { - Value *V = expandInTy(S->getOperand(),S->getType()->getUnsignedVersion()); - return new CastInst(V, S->getType(), "tmp.", InsertPt); - } - - Value *visitAddExpr(SCEVAddExpr *S) { - const Type *Ty = S->getType(); - Value *V = expandInTy(S->getOperand(S->getNumOperands()-1), Ty); - - // Emit a bunch of add instructions - for (int i = S->getNumOperands()-2; i >= 0; --i) - V = BinaryOperator::createAdd(V, expandInTy(S->getOperand(i), Ty), - "tmp.", InsertPt); - return V; - } - - Value *visitMulExpr(SCEVMulExpr *S); - - Value *visitUDivExpr(SCEVUDivExpr *S) { - const Type *Ty = S->getType(); - Value *LHS = expandInTy(S->getLHS(), Ty); - Value *RHS = expandInTy(S->getRHS(), Ty); - return BinaryOperator::createDiv(LHS, RHS, "tmp.", InsertPt); - } - - Value *visitAddRecExpr(SCEVAddRecExpr *S); - - Value *visitUnknown(SCEVUnknown *S) { - return S->getValue(); - } - }; -} - -Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) { - const Type *Ty = S->getType(); - int FirstOp = 0; // Set if we should emit a subtract. - if (SCEVConstant *SC = dyn_cast<SCEVConstant>(S->getOperand(0))) - if (SC->getValue()->isAllOnesValue()) - FirstOp = 1; - - int i = S->getNumOperands()-2; - Value *V = expandInTy(S->getOperand(i+1), Ty); - - // Emit a bunch of multiply instructions - for (; i >= FirstOp; --i) - V = BinaryOperator::createMul(V, expandInTy(S->getOperand(i), Ty), - "tmp.", InsertPt); - // -1 * ... ---> 0 - ... - if (FirstOp == 1) - V = BinaryOperator::createNeg(V, "tmp.", InsertPt); - return V; -} - -Value *SCEVExpander::visitAddRecExpr(SCEVAddRecExpr *S) { - const Type *Ty = S->getType(); - const Loop *L = S->getLoop(); - // We cannot yet do fp recurrences, e.g. the xform of {X,+,F} --> X+{0,+,F} - assert(Ty->isIntegral() && "Cannot expand fp recurrences yet!"); - - // {X,+,F} --> X + {0,+,F} - if (!isa<SCEVConstant>(S->getStart()) || - !cast<SCEVConstant>(S->getStart())->getValue()->isNullValue()) { - Value *Start = expandInTy(S->getStart(), Ty); - std::vector<SCEVHandle> NewOps(S->op_begin(), S->op_end()); - NewOps[0] = SCEVUnknown::getIntegerSCEV(0, Ty); - Value *Rest = expandInTy(SCEVAddRecExpr::get(NewOps, L), Ty); - - // FIXME: look for an existing add to use. - return BinaryOperator::createAdd(Rest, Start, "tmp.", InsertPt); - } - - // {0,+,1} --> Insert a canonical induction variable into the loop! - if (S->getNumOperands() == 2 && - S->getOperand(1) == SCEVUnknown::getIntegerSCEV(1, Ty)) { - // Create and insert the PHI node for the induction variable in the - // specified loop. - BasicBlock *Header = L->getHeader(); - PHINode *PN = new PHINode(Ty, "indvar", Header->begin()); - PN->addIncoming(Constant::getNullValue(Ty), L->getLoopPreheader()); - - pred_iterator HPI = pred_begin(Header); - assert(HPI != pred_end(Header) && "Loop with zero preds???"); - if (!L->contains(*HPI)) ++HPI; - assert(HPI != pred_end(Header) && L->contains(*HPI) && - "No backedge in loop?"); - - // Insert a unit add instruction right before the terminator corresponding - // to the back-edge. - Constant *One = Ty->isFloatingPoint() ? (Constant*)ConstantFP::get(Ty, 1.0) - : ConstantInt::get(Ty, 1); - Instruction *Add = BinaryOperator::createAdd(PN, One, "indvar.next", - (*HPI)->getTerminator()); - - pred_iterator PI = pred_begin(Header); - if (*PI == L->getLoopPreheader()) - ++PI; - PN->addIncoming(Add, *PI); - return PN; - } - - // Get the canonical induction variable I for this loop. - Value *I = getOrInsertCanonicalInductionVariable(L, Ty); - - if (S->getNumOperands() == 2) { // {0,+,F} --> i*F - Value *F = expandInTy(S->getOperand(1), Ty); - return BinaryOperator::createMul(I, F, "tmp.", InsertPt); - } - - // 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 - // simplify the expression without having to build a bunch of special code - // into this folder. - SCEVHandle IH = SCEVUnknown::get(I); // Get I as a "symbolic" SCEV. - - SCEVHandle V = S->evaluateAtIteration(IH); - //std::cerr << "Evaluated: " << *this << "\n to: " << *V << "\n"; - - return expandInTy(V, Ty); -} - - -namespace { Statistic<> NumRemoved ("indvars", "Number of aux indvars removed"); Statistic<> NumPointer ("indvars", "Number of pointer indvars promoted"); Statistic<> NumInserted("indvars", "Number of canonical indvars added"); |