[llvm-commits] CVS: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h

Nate Begeman natebegeman at mac.com
Fri Jul 29 17:12:31 PDT 2005



Changes in directory llvm/include/llvm/Analysis:

ScalarEvolutionExpander.h added (r1.1)
---
Log message:

Break SCEVExpander out of IndVarSimplify into its own .h/.cpp file so that
other passes may use it.


---
Diffs of the changes:  (+180 -0)

 ScalarEvolutionExpander.h |  180 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 180 insertions(+)


Index: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h
diff -c /dev/null llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.1
*** /dev/null	Fri Jul 29 19:12:29 2005
--- llvm/include/llvm/Analysis/ScalarEvolutionExpander.h	Fri Jul 29 19:12:19 2005
***************
*** 0 ****
--- 1,180 ----
+ //===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines the classes used to generate code from scalar expressions.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+ #define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+ 
+ #include "llvm/BasicBlock.h"
+ #include "llvm/Constants.h"
+ #include "llvm/Instructions.h"
+ #include "llvm/Type.h"
+ #include "llvm/Analysis/ScalarEvolution.h"
+ #include "llvm/Analysis/ScalarEvolutionExpressions.h"
+ #include "llvm/Support/CFG.h"
+ 
+ namespace llvm {
+   /// 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) {}
+ 
+     /// clear - Erase the contents of the InsertedExpressions map so that users
+     /// trying to expand the same expression into multiple BasicBlocks or 
+     /// different places within the same BasicBlock can do so.
+     void clear() { InsertedExpressions.clear(); }
+     
+     /// 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();
+     }
+   };
+ }
+ 
+ #endif
+ 






More information about the llvm-commits mailing list