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 | 2bca4d9b7b42fc0b68dd2e0897a0d40b4ab4517a (patch) | |
| tree | f0d64211704e3771577a3d51a3a9358af0dc422e /llvm/lib/Transforms/Scalar | |
| parent | 4738d1b5cdb90561311940869f8b23e3ea09c6ae (diff) | |
| download | bcm5719-llvm-2bca4d9b7b42fc0b68dd2e0897a0d40b4ab4517a.tar.gz bcm5719-llvm-2bca4d9b7b42fc0b68dd2e0897a0d40b4ab4517a.zip | |
Break SCEVExpander out of IndVarSimplify into its own .h/.cpp file so that
other passes may use it.
llvm-svn: 22557
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 239 | 
1 files changed, 1 insertions, 238 deletions
| diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 5b7e4e1fd9e..82bab5acd0f 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/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"); | 

