LLVM API Documentation

ScalarEvolutionExpressions.h

Go to the documentation of this file.
00001 //===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the classes used to represent and build scalar expressions.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
00015 #define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
00016 
00017 #include "llvm/Analysis/ScalarEvolution.h"
00018 
00019 namespace llvm {
00020   class ConstantInt;
00021   class ConstantRange;
00022   class APInt;
00023 
00024   enum SCEVTypes {
00025     // These should be ordered in terms of increasing complexity to make the
00026     // folders simpler.
00027     scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
00028     scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUnknown,
00029     scCouldNotCompute
00030   };
00031 
00032   //===--------------------------------------------------------------------===//
00033   /// SCEVConstant - This class represents a constant integer value.
00034   ///
00035   class SCEVConstant : public SCEV {
00036     friend class ScalarEvolution;
00037 
00038     ConstantInt *V;
00039     explicit SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {}
00040 
00041     virtual ~SCEVConstant();
00042   public:
00043     ConstantInt *getValue() const { return V; }
00044 
00045     virtual bool isLoopInvariant(const Loop *L) const {
00046       return true;
00047     }
00048 
00049     virtual bool hasComputableLoopEvolution(const Loop *L) const {
00050       return false;  // Not loop variant
00051     }
00052 
00053     virtual const Type *getType() const;
00054 
00055     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00056                                                  const SCEVHandle &Conc,
00057                                                  ScalarEvolution &SE) const {
00058       return this;
00059     }
00060 
00061     virtual void print(std::ostream &OS) const;
00062     void print(std::ostream *OS) const { if (OS) print(*OS); }
00063 
00064     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00065     static inline bool classof(const SCEVConstant *S) { return true; }
00066     static inline bool classof(const SCEV *S) {
00067       return S->getSCEVType() == scConstant;
00068     }
00069   };
00070 
00071   //===--------------------------------------------------------------------===//
00072   /// SCEVTruncateExpr - This class represents a truncation of an integer value
00073   /// to a smaller integer value.
00074   ///
00075   class SCEVTruncateExpr : public SCEV {
00076     friend class ScalarEvolution;
00077 
00078     SCEVHandle Op;
00079     const Type *Ty;
00080     SCEVTruncateExpr(const SCEVHandle &op, const Type *ty);
00081     virtual ~SCEVTruncateExpr();
00082   public:
00083     const SCEVHandle &getOperand() const { return Op; }
00084     virtual const Type *getType() const { return Ty; }
00085 
00086     virtual bool isLoopInvariant(const Loop *L) const {
00087       return Op->isLoopInvariant(L);
00088     }
00089 
00090     virtual bool hasComputableLoopEvolution(const Loop *L) const {
00091       return Op->hasComputableLoopEvolution(L);
00092     }
00093 
00094     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00095                                                  const SCEVHandle &Conc,
00096                                                  ScalarEvolution &SE) const {
00097       SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
00098       if (H == Op)
00099         return this;
00100       return SE.getTruncateExpr(H, Ty);
00101     }
00102 
00103     virtual void print(std::ostream &OS) const;
00104     void print(std::ostream *OS) const { if (OS) print(*OS); }
00105 
00106     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00107     static inline bool classof(const SCEVTruncateExpr *S) { return true; }
00108     static inline bool classof(const SCEV *S) {
00109       return S->getSCEVType() == scTruncate;
00110     }
00111   };
00112 
00113   //===--------------------------------------------------------------------===//
00114   /// SCEVZeroExtendExpr - This class represents a zero extension of a small
00115   /// integer value to a larger integer value.
00116   ///
00117   class SCEVZeroExtendExpr : public SCEV {
00118     friend class ScalarEvolution;
00119 
00120     SCEVHandle Op;
00121     const Type *Ty;
00122     SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty);
00123     virtual ~SCEVZeroExtendExpr();
00124   public:
00125     const SCEVHandle &getOperand() const { return Op; }
00126     virtual const Type *getType() const { return Ty; }
00127 
00128     virtual bool isLoopInvariant(const Loop *L) const {
00129       return Op->isLoopInvariant(L);
00130     }
00131 
00132     virtual bool hasComputableLoopEvolution(const Loop *L) const {
00133       return Op->hasComputableLoopEvolution(L);
00134     }
00135 
00136     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00137                                                  const SCEVHandle &Conc,
00138                                                  ScalarEvolution &SE) const {
00139       SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
00140       if (H == Op)
00141         return this;
00142       return SE.getZeroExtendExpr(H, Ty);
00143     }
00144 
00145     virtual void print(std::ostream &OS) const;
00146     void print(std::ostream *OS) const { if (OS) print(*OS); }
00147 
00148     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00149     static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
00150     static inline bool classof(const SCEV *S) {
00151       return S->getSCEVType() == scZeroExtend;
00152     }
00153   };
00154 
00155   //===--------------------------------------------------------------------===//
00156   /// SCEVSignExtendExpr - This class represents a sign extension of a small
00157   /// integer value to a larger integer value.
00158   ///
00159   class SCEVSignExtendExpr : public SCEV {
00160     friend class ScalarEvolution;
00161 
00162     SCEVHandle Op;
00163     const Type *Ty;
00164     SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty);
00165     virtual ~SCEVSignExtendExpr();
00166   public:
00167     const SCEVHandle &getOperand() const { return Op; }
00168     virtual const Type *getType() const { return Ty; }
00169 
00170     virtual bool isLoopInvariant(const Loop *L) const {
00171       return Op->isLoopInvariant(L);
00172     }
00173 
00174     virtual bool hasComputableLoopEvolution(const Loop *L) const {
00175       return Op->hasComputableLoopEvolution(L);
00176     }
00177 
00178     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00179                                                  const SCEVHandle &Conc,
00180                                                  ScalarEvolution &SE) const {
00181       SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
00182       if (H == Op)
00183         return this;
00184       return SE.getSignExtendExpr(H, Ty);
00185     }
00186 
00187     virtual void print(std::ostream &OS) const;
00188     void print(std::ostream *OS) const { if (OS) print(*OS); }
00189 
00190     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00191     static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
00192     static inline bool classof(const SCEV *S) {
00193       return S->getSCEVType() == scSignExtend;
00194     }
00195   };
00196 
00197 
00198   //===--------------------------------------------------------------------===//
00199   /// SCEVCommutativeExpr - This node is the base class for n'ary commutative
00200   /// operators.
00201   ///
00202   class SCEVCommutativeExpr : public SCEV {
00203     friend class ScalarEvolution;
00204 
00205     std::vector<SCEVHandle> Operands;
00206 
00207   protected:
00208     SCEVCommutativeExpr(enum SCEVTypes T, const std::vector<SCEVHandle> &ops)
00209       : SCEV(T) {
00210       Operands.reserve(ops.size());
00211       Operands.insert(Operands.end(), ops.begin(), ops.end());
00212     }
00213     ~SCEVCommutativeExpr();
00214 
00215   public:
00216     unsigned getNumOperands() const { return (unsigned)Operands.size(); }
00217     const SCEVHandle &getOperand(unsigned i) const {
00218       assert(i < Operands.size() && "Operand index out of range!");
00219       return Operands[i];
00220     }
00221 
00222     const std::vector<SCEVHandle> &getOperands() const { return Operands; }
00223     typedef std::vector<SCEVHandle>::const_iterator op_iterator;
00224     op_iterator op_begin() const { return Operands.begin(); }
00225     op_iterator op_end() const { return Operands.end(); }
00226 
00227 
00228     virtual bool isLoopInvariant(const Loop *L) const {
00229       for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
00230         if (!getOperand(i)->isLoopInvariant(L)) return false;
00231       return true;
00232     }
00233 
00234     // hasComputableLoopEvolution - Commutative expressions have computable loop
00235     // evolutions iff they have at least one operand that varies with the loop,
00236     // but that all varying operands are computable.
00237     virtual bool hasComputableLoopEvolution(const Loop *L) const {
00238       bool HasVarying = false;
00239       for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
00240         if (!getOperand(i)->isLoopInvariant(L)) {
00241           if (getOperand(i)->hasComputableLoopEvolution(L))
00242             HasVarying = true;
00243           else
00244             return false;
00245         }
00246       return HasVarying;
00247     }
00248 
00249     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00250                                                  const SCEVHandle &Conc,
00251                                                  ScalarEvolution &SE) const;
00252 
00253     virtual const char *getOperationStr() const = 0;
00254 
00255     virtual const Type *getType() const { return getOperand(0)->getType(); }
00256     virtual void print(std::ostream &OS) const;
00257     void print(std::ostream *OS) const { if (OS) print(*OS); }
00258 
00259     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00260     static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
00261     static inline bool classof(const SCEV *S) {
00262       return S->getSCEVType() == scAddExpr ||
00263              S->getSCEVType() == scMulExpr ||
00264              S->getSCEVType() == scSMaxExpr ||
00265              S->getSCEVType() == scUMaxExpr;
00266     }
00267   };
00268 
00269 
00270   //===--------------------------------------------------------------------===//
00271   /// SCEVAddExpr - This node represents an addition of some number of SCEVs.
00272   ///
00273   class SCEVAddExpr : public SCEVCommutativeExpr {
00274     friend class ScalarEvolution;
00275 
00276     explicit SCEVAddExpr(const std::vector<SCEVHandle> &ops)
00277       : SCEVCommutativeExpr(scAddExpr, ops) {
00278     }
00279 
00280   public:
00281     virtual const char *getOperationStr() const { return " + "; }
00282 
00283     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00284     static inline bool classof(const SCEVAddExpr *S) { return true; }
00285     static inline bool classof(const SCEV *S) {
00286       return S->getSCEVType() == scAddExpr;
00287     }
00288   };
00289 
00290   //===--------------------------------------------------------------------===//
00291   /// SCEVMulExpr - This node represents multiplication of some number of SCEVs.
00292   ///
00293   class SCEVMulExpr : public SCEVCommutativeExpr {
00294     friend class ScalarEvolution;
00295 
00296     explicit SCEVMulExpr(const std::vector<SCEVHandle> &ops)
00297       : SCEVCommutativeExpr(scMulExpr, ops) {
00298     }
00299 
00300   public:
00301     virtual const char *getOperationStr() const { return " * "; }
00302 
00303     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00304     static inline bool classof(const SCEVMulExpr *S) { return true; }
00305     static inline bool classof(const SCEV *S) {
00306       return S->getSCEVType() == scMulExpr;
00307     }
00308   };
00309 
00310 
00311   //===--------------------------------------------------------------------===//
00312   /// SCEVUDivExpr - This class represents a binary unsigned division operation.
00313   ///
00314   class SCEVUDivExpr : public SCEV {
00315     friend class ScalarEvolution;
00316 
00317     SCEVHandle LHS, RHS;
00318     SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs)
00319       : SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {}
00320 
00321     virtual ~SCEVUDivExpr();
00322   public:
00323     const SCEVHandle &getLHS() const { return LHS; }
00324     const SCEVHandle &getRHS() const { return RHS; }
00325 
00326     virtual bool isLoopInvariant(const Loop *L) const {
00327       return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
00328     }
00329 
00330     virtual bool hasComputableLoopEvolution(const Loop *L) const {
00331       return LHS->hasComputableLoopEvolution(L) &&
00332              RHS->hasComputableLoopEvolution(L);
00333     }
00334 
00335     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00336                                                  const SCEVHandle &Conc,
00337                                                  ScalarEvolution &SE) const {
00338       SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
00339       SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
00340       if (L == LHS && R == RHS)
00341         return this;
00342       else
00343         return SE.getUDivExpr(L, R);
00344     }
00345 
00346 
00347     virtual const Type *getType() const;
00348 
00349     void print(std::ostream &OS) const;
00350     void print(std::ostream *OS) const { if (OS) print(*OS); }
00351 
00352     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00353     static inline bool classof(const SCEVUDivExpr *S) { return true; }
00354     static inline bool classof(const SCEV *S) {
00355       return S->getSCEVType() == scUDivExpr;
00356     }
00357   };
00358 
00359 
00360   //===--------------------------------------------------------------------===//
00361   /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip
00362   /// count of the specified loop.
00363   ///
00364   /// All operands of an AddRec are required to be loop invariant.
00365   ///
00366   class SCEVAddRecExpr : public SCEV {
00367     friend class ScalarEvolution;
00368 
00369     std::vector<SCEVHandle> Operands;
00370     const Loop *L;
00371 
00372     SCEVAddRecExpr(const std::vector<SCEVHandle> &ops, const Loop *l)
00373       : SCEV(scAddRecExpr), Operands(ops), L(l) {
00374       for (size_t i = 0, e = Operands.size(); i != e; ++i)
00375         assert(Operands[i]->isLoopInvariant(l) &&
00376                "Operands of AddRec must be loop-invariant!");
00377     }
00378     ~SCEVAddRecExpr();
00379   public:
00380     typedef std::vector<SCEVHandle>::const_iterator op_iterator;
00381     op_iterator op_begin() const { return Operands.begin(); }
00382     op_iterator op_end() const { return Operands.end(); }
00383 
00384     unsigned getNumOperands() const { return (unsigned)Operands.size(); }
00385     const SCEVHandle &getOperand(unsigned i) const { return Operands[i]; }
00386     const SCEVHandle &getStart() const { return Operands[0]; }
00387     const Loop *getLoop() const { return L; }
00388 
00389 
00390     /// getStepRecurrence - This method constructs and returns the recurrence
00391     /// indicating how much this expression steps by.  If this is a polynomial
00392     /// of degree N, it returns a chrec of degree N-1.
00393     SCEVHandle getStepRecurrence(ScalarEvolution &SE) const {
00394       if (isAffine()) return getOperand(1);
00395       return SE.getAddRecExpr(std::vector<SCEVHandle>(op_begin()+1,op_end()),
00396                               getLoop());
00397     }
00398 
00399     virtual bool hasComputableLoopEvolution(const Loop *QL) const {
00400       if (L == QL) return true;
00401       return false;
00402     }
00403 
00404     virtual bool isLoopInvariant(const Loop *QueryLoop) const;
00405 
00406     virtual const Type *getType() const { return Operands[0]->getType(); }
00407 
00408     /// isAffine - Return true if this is an affine AddRec (i.e., it represents
00409     /// an expressions A+B*x where A and B are loop invariant values.
00410     bool isAffine() const {
00411       // We know that the start value is invariant.  This expression is thus
00412       // affine iff the step is also invariant.
00413       return getNumOperands() == 2;
00414     }
00415 
00416     /// isQuadratic - Return true if this is an quadratic AddRec (i.e., it
00417     /// represents an expressions A+B*x+C*x^2 where A, B and C are loop
00418     /// invariant values.  This corresponds to an addrec of the form {L,+,M,+,N}
00419     bool isQuadratic() const {
00420       return getNumOperands() == 3;
00421     }
00422 
00423     /// evaluateAtIteration - Return the value of this chain of recurrences at
00424     /// the specified iteration number.
00425     SCEVHandle evaluateAtIteration(SCEVHandle It, ScalarEvolution &SE) const;
00426 
00427     /// getNumIterationsInRange - Return the number of iterations of this loop
00428     /// that produce values in the specified constant range.  Another way of
00429     /// looking at this is that it returns the first iteration number where the
00430     /// value is not in the condition, thus computing the exit count.  If the
00431     /// iteration count can't be computed, an instance of SCEVCouldNotCompute is
00432     /// returned.
00433     SCEVHandle getNumIterationsInRange(ConstantRange Range,
00434                                        ScalarEvolution &SE) const;
00435 
00436     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00437                                                  const SCEVHandle &Conc,
00438                                                  ScalarEvolution &SE) const;
00439 
00440     virtual void print(std::ostream &OS) const;
00441     void print(std::ostream *OS) const { if (OS) print(*OS); }
00442 
00443     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00444     static inline bool classof(const SCEVAddRecExpr *S) { return true; }
00445     static inline bool classof(const SCEV *S) {
00446       return S->getSCEVType() == scAddRecExpr;
00447     }
00448   };
00449 
00450 
00451   //===--------------------------------------------------------------------===//
00452   /// SCEVSMaxExpr - This class represents a signed maximum selection.
00453   ///
00454   class SCEVSMaxExpr : public SCEVCommutativeExpr {
00455     friend class ScalarEvolution;
00456 
00457     explicit SCEVSMaxExpr(const std::vector<SCEVHandle> &ops)
00458       : SCEVCommutativeExpr(scSMaxExpr, ops) {
00459     }
00460 
00461   public:
00462     virtual const char *getOperationStr() const { return " smax "; }
00463 
00464     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00465     static inline bool classof(const SCEVSMaxExpr *S) { return true; }
00466     static inline bool classof(const SCEV *S) {
00467       return S->getSCEVType() == scSMaxExpr;
00468     }
00469   };
00470 
00471 
00472   //===--------------------------------------------------------------------===//
00473   /// SCEVUMaxExpr - This class represents an unsigned maximum selection.
00474   ///
00475   class SCEVUMaxExpr : public SCEVCommutativeExpr {
00476     friend class ScalarEvolution;
00477 
00478     explicit SCEVUMaxExpr(const std::vector<SCEVHandle> &ops)
00479       : SCEVCommutativeExpr(scUMaxExpr, ops) {
00480     }
00481 
00482   public:
00483     virtual const char *getOperationStr() const { return " umax "; }
00484 
00485     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00486     static inline bool classof(const SCEVUMaxExpr *S) { return true; }
00487     static inline bool classof(const SCEV *S) {
00488       return S->getSCEVType() == scUMaxExpr;
00489     }
00490   };
00491 
00492 
00493   //===--------------------------------------------------------------------===//
00494   /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
00495   /// value, and only represent it as it's LLVM Value.  This is the "bottom"
00496   /// value for the analysis.
00497   ///
00498   class SCEVUnknown : public SCEV {
00499     friend class ScalarEvolution;
00500 
00501     Value *V;
00502     explicit SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {}
00503 
00504   protected:
00505     ~SCEVUnknown();
00506   public:
00507     Value *getValue() const { return V; }
00508 
00509     virtual bool isLoopInvariant(const Loop *L) const;
00510     virtual bool hasComputableLoopEvolution(const Loop *QL) const {
00511       return false; // not computable
00512     }
00513 
00514     SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
00515                                                  const SCEVHandle &Conc,
00516                                                  ScalarEvolution &SE) const {
00517       if (&*Sym == this) return Conc;
00518       return this;
00519     }
00520 
00521     virtual const Type *getType() const;
00522 
00523     virtual void print(std::ostream &OS) const;
00524     void print(std::ostream *OS) const { if (OS) print(*OS); }
00525 
00526     /// Methods for support type inquiry through isa, cast, and dyn_cast:
00527     static inline bool classof(const SCEVUnknown *S) { return true; }
00528     static inline bool classof(const SCEV *S) {
00529       return S->getSCEVType() == scUnknown;
00530     }
00531   };
00532 
00533   /// SCEVVisitor - This class defines a simple visitor class that may be used
00534   /// for various SCEV analysis purposes.
00535   template<typename SC, typename RetVal=void>
00536   struct SCEVVisitor {
00537     RetVal visit(SCEV *S) {
00538       switch (S->getSCEVType()) {
00539       case scConstant:
00540         return ((SC*)this)->visitConstant((SCEVConstant*)S);
00541       case scTruncate:
00542         return ((SC*)this)->visitTruncateExpr((SCEVTruncateExpr*)S);
00543       case scZeroExtend:
00544         return ((SC*)this)->visitZeroExtendExpr((SCEVZeroExtendExpr*)S);
00545       case scSignExtend:
00546         return ((SC*)this)->visitSignExtendExpr((SCEVSignExtendExpr*)S);
00547       case scAddExpr:
00548         return ((SC*)this)->visitAddExpr((SCEVAddExpr*)S);
00549       case scMulExpr:
00550         return ((SC*)this)->visitMulExpr((SCEVMulExpr*)S);
00551       case scUDivExpr:
00552         return ((SC*)this)->visitUDivExpr((SCEVUDivExpr*)S);
00553       case scAddRecExpr:
00554         return ((SC*)this)->visitAddRecExpr((SCEVAddRecExpr*)S);
00555       case scSMaxExpr:
00556         return ((SC*)this)->visitSMaxExpr((SCEVSMaxExpr*)S);
00557       case scUMaxExpr:
00558         return ((SC*)this)->visitUMaxExpr((SCEVUMaxExpr*)S);
00559       case scUnknown:
00560         return ((SC*)this)->visitUnknown((SCEVUnknown*)S);
00561       case scCouldNotCompute:
00562         return ((SC*)this)->visitCouldNotCompute((SCEVCouldNotCompute*)S);
00563       default:
00564         assert(0 && "Unknown SCEV type!");
00565         abort();
00566       }
00567     }
00568 
00569     RetVal visitCouldNotCompute(SCEVCouldNotCompute *S) {
00570       assert(0 && "Invalid use of SCEVCouldNotCompute!");
00571       abort();
00572       return RetVal();
00573     }
00574   };
00575 }
00576 
00577 #endif



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.