ScalarEvolutionExpressions.h revision d9480d0f6875d8aa3a0d91942d24f0ee416b1ff1
14950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
29769ab22265b313171d201b5928688524a01bd87Misha Brukman//
34950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner//                     The LLVM Compiler Infrastructure
44950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
79769ab22265b313171d201b5928688524a01bd87Misha Brukman//
84950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner//===----------------------------------------------------------------------===//
94950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner//
104950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner// This file defines the classes used to represent and build scalar expressions.
119769ab22265b313171d201b5928688524a01bd87Misha Brukman//
124950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner//===----------------------------------------------------------------------===//
134950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
144950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
154950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
164950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
174950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner#include "llvm/Analysis/ScalarEvolution.h"
184950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
194950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattnernamespace llvm {
204950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  class ConstantInt;
214950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  class ConstantRange;
2235fa43907e2ea751ad35bfbaab8c4d3511422c14Reid Spencer  class APInt;
235a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng  class DominatorTree;
244950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
254950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  enum SCEVTypes {
264950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    // These should be ordered in terms of increasing complexity to make the
274950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    // folders simpler.
28d19534add90a2a894af61523b830887097bb780bDan Gohman    scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
29789558db70d9513a017c11c5be30945839fdff1cNick Lewycky    scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUnknown,
303e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    scCouldNotCompute
314950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
324950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
334950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
344950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// SCEVConstant - This class represents a constant integer value.
354950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
364950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  class SCEVConstant : public SCEV {
37246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
38246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
394950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    ConstantInt *V;
409a6ae965d69b131d692de8fc69545b6c7aaea0b2Dan Gohman    explicit SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {}
419769ab22265b313171d201b5928688524a01bd87Misha Brukman
424950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual ~SCEVConstant();
434950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  public:
444950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    ConstantInt *getValue() const { return V; }
454950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
464950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool isLoopInvariant(const Loop *L) const {
474950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return true;
484950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
494950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
504950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool hasComputableLoopEvolution(const Loop *L) const {
514950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return false;  // Not loop variant
524950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
534950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
544950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual const Type *getType() const;
554950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
56afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
57246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
58246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const {
59afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner      return this;
60afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    }
61afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner
625a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng    bool dominates(BasicBlock *BB, DominatorTree *DT) const {
635a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng      return true;
645a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng    }
655a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng
66b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    virtual void print(raw_ostream &OS) const;
674950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
684950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
694950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVConstant *S) { return true; }
704950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
714950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scConstant;
724950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
734950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
744950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
754950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
7684923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  /// SCEVCastExpr - This is the base class for unary cast operator classes.
774950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
7884923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  class SCEVCastExpr : public SCEV {
7984923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  protected:
804950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    SCEVHandle Op;
814950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const Type *Ty;
8284923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman
8384923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    SCEVCastExpr(unsigned SCEVTy, const SCEVHandle &op, const Type *ty);
8484923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    virtual ~SCEVCastExpr();
8584923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman
864950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  public:
874950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const SCEVHandle &getOperand() const { return Op; }
884950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual const Type *getType() const { return Ty; }
899769ab22265b313171d201b5928688524a01bd87Misha Brukman
904950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool isLoopInvariant(const Loop *L) const {
914950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return Op->isLoopInvariant(L);
924950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
934950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
944950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool hasComputableLoopEvolution(const Loop *L) const {
954950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return Op->hasComputableLoopEvolution(L);
964950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
974950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
9884923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const;
9984923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman
10084923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    /// Methods for support type inquiry through isa, cast, and dyn_cast:
10184923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    static inline bool classof(const SCEVCastExpr *S) { return true; }
10284923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    static inline bool classof(const SCEV *S) {
10384923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman      return S->getSCEVType() == scTruncate ||
10484923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman             S->getSCEVType() == scZeroExtend ||
10584923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman             S->getSCEVType() == scSignExtend;
10684923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    }
10784923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  };
10884923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman
10984923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  //===--------------------------------------------------------------------===//
11084923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  /// SCEVTruncateExpr - This class represents a truncation of an integer value
11184923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  /// to a smaller integer value.
11284923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  ///
11384923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  class SCEVTruncateExpr : public SCEVCastExpr {
11484923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    friend class ScalarEvolution;
11584923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman
11684923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    SCEVTruncateExpr(const SCEVHandle &op, const Type *ty);
11784923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman    virtual ~SCEVTruncateExpr();
11884923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman
11984923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  public:
120afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
121246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
122246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const {
123246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
124afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner      if (H == Op)
125afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner        return this;
126246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      return SE.getTruncateExpr(H, Ty);
127afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    }
128afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner
129b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    virtual void print(raw_ostream &OS) const;
1304950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
1314950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
1324950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVTruncateExpr *S) { return true; }
1334950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
1344950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scTruncate;
1354950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
1364950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
1374950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
1384950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
1394950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// SCEVZeroExtendExpr - This class represents a zero extension of a small
1404950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// integer value to a larger integer value.
1414950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
14284923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  class SCEVZeroExtendExpr : public SCEVCastExpr {
143246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
144246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
1454950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty);
1464950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual ~SCEVZeroExtendExpr();
1474950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
14884923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  public:
149afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
150246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
151246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const {
152246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
153afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner      if (H == Op)
154afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner        return this;
155246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      return SE.getZeroExtendExpr(H, Ty);
156afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    }
157afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner
158b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    virtual void print(raw_ostream &OS) const;
1594950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
1604950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
1614950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
1624950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
1634950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scZeroExtend;
1644950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
1654950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
1664950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
167d19534add90a2a894af61523b830887097bb780bDan Gohman  //===--------------------------------------------------------------------===//
168d19534add90a2a894af61523b830887097bb780bDan Gohman  /// SCEVSignExtendExpr - This class represents a sign extension of a small
169d19534add90a2a894af61523b830887097bb780bDan Gohman  /// integer value to a larger integer value.
170d19534add90a2a894af61523b830887097bb780bDan Gohman  ///
17184923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  class SCEVSignExtendExpr : public SCEVCastExpr {
172246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
173246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
174d19534add90a2a894af61523b830887097bb780bDan Gohman    SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty);
175d19534add90a2a894af61523b830887097bb780bDan Gohman    virtual ~SCEVSignExtendExpr();
176d19534add90a2a894af61523b830887097bb780bDan Gohman
17784923602fdc2a81957e5dee178d5737ad8e72f55Dan Gohman  public:
178d19534add90a2a894af61523b830887097bb780bDan Gohman    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
179246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
180246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const {
181246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
182d19534add90a2a894af61523b830887097bb780bDan Gohman      if (H == Op)
183d19534add90a2a894af61523b830887097bb780bDan Gohman        return this;
184246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      return SE.getSignExtendExpr(H, Ty);
185d19534add90a2a894af61523b830887097bb780bDan Gohman    }
186d19534add90a2a894af61523b830887097bb780bDan Gohman
187b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    virtual void print(raw_ostream &OS) const;
188d19534add90a2a894af61523b830887097bb780bDan Gohman
189d19534add90a2a894af61523b830887097bb780bDan Gohman    /// Methods for support type inquiry through isa, cast, and dyn_cast:
190d19534add90a2a894af61523b830887097bb780bDan Gohman    static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
191d19534add90a2a894af61523b830887097bb780bDan Gohman    static inline bool classof(const SCEV *S) {
192d19534add90a2a894af61523b830887097bb780bDan Gohman      return S->getSCEVType() == scSignExtend;
193d19534add90a2a894af61523b830887097bb780bDan Gohman    }
194d19534add90a2a894af61523b830887097bb780bDan Gohman  };
195d19534add90a2a894af61523b830887097bb780bDan Gohman
1964950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
197d9480d0f6875d8aa3a0d91942d24f0ee416b1ff1Dan Gohman  //===--------------------------------------------------------------------===//
198d9480d0f6875d8aa3a0d91942d24f0ee416b1ff1Dan Gohman  /// SCEVNAryExpr - This node is a base class providing common
199d9480d0f6875d8aa3a0d91942d24f0ee416b1ff1Dan Gohman  /// functionality for n'ary operators.
200d9480d0f6875d8aa3a0d91942d24f0ee416b1ff1Dan Gohman  ///
201ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  class SCEVNAryExpr : public SCEV {
202ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  protected:
2034950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    std::vector<SCEVHandle> Operands;
2044950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
205ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    SCEVNAryExpr(enum SCEVTypes T, const std::vector<SCEVHandle> &ops)
206ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman      : SCEV(T), Operands(ops) {}
207ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    virtual ~SCEVNAryExpr() {}
2084950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
2094950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  public:
21034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng    unsigned getNumOperands() const { return (unsigned)Operands.size(); }
2114950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const SCEVHandle &getOperand(unsigned i) const {
2124950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      assert(i < Operands.size() && "Operand index out of range!");
2134950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return Operands[i];
2144950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
2154950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
2164950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const std::vector<SCEVHandle> &getOperands() const { return Operands; }
2174950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    typedef std::vector<SCEVHandle>::const_iterator op_iterator;
2184950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    op_iterator op_begin() const { return Operands.begin(); }
2194950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    op_iterator op_end() const { return Operands.end(); }
2204950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
2214950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool isLoopInvariant(const Loop *L) const {
2224950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
2234950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner        if (!getOperand(i)->isLoopInvariant(L)) return false;
2244950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return true;
2254950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
2264950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
22739592233304acbbeea8c53bac2b6a822a63a4c4bDan Gohman    // hasComputableLoopEvolution - N-ary expressions have computable loop
228803513b364e27d303285d396fd8ee5b32149962aChris Lattner    // evolutions iff they have at least one operand that varies with the loop,
229803513b364e27d303285d396fd8ee5b32149962aChris Lattner    // but that all varying operands are computable.
2304950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool hasComputableLoopEvolution(const Loop *L) const {
231803513b364e27d303285d396fd8ee5b32149962aChris Lattner      bool HasVarying = false;
2324950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
233ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov        if (!getOperand(i)->isLoopInvariant(L)) {
234803513b364e27d303285d396fd8ee5b32149962aChris Lattner          if (getOperand(i)->hasComputableLoopEvolution(L))
235803513b364e27d303285d396fd8ee5b32149962aChris Lattner            HasVarying = true;
236803513b364e27d303285d396fd8ee5b32149962aChris Lattner          else
237803513b364e27d303285d396fd8ee5b32149962aChris Lattner            return false;
238ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov        }
239803513b364e27d303285d396fd8ee5b32149962aChris Lattner      return HasVarying;
2404950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
2414950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
242ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    bool dominates(BasicBlock *BB, DominatorTree *DT) const;
243ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman
244ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    virtual const Type *getType() const { return getOperand(0)->getType(); }
245ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman
246ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    /// Methods for support type inquiry through isa, cast, and dyn_cast:
247ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    static inline bool classof(const SCEVNAryExpr *S) { return true; }
248ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    static inline bool classof(const SCEV *S) {
249ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman      return S->getSCEVType() == scAddExpr ||
250ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman             S->getSCEVType() == scMulExpr ||
251ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman             S->getSCEVType() == scSMaxExpr ||
252ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman             S->getSCEVType() == scUMaxExpr ||
253ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman             S->getSCEVType() == scAddRecExpr;
254ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    }
255ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  };
256ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman
257ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  //===--------------------------------------------------------------------===//
258ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  /// SCEVCommutativeExpr - This node is the base class for n'ary commutative
259ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  /// operators.
260ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  ///
261ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  class SCEVCommutativeExpr : public SCEVNAryExpr {
262ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  protected:
263ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    SCEVCommutativeExpr(enum SCEVTypes T, const std::vector<SCEVHandle> &ops)
264ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman      : SCEVNAryExpr(T, ops) {}
265ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman    ~SCEVCommutativeExpr();
266ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman
267ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  public:
268afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
269246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
270246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const;
271afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner
2724950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual const char *getOperationStr() const = 0;
2734950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
274b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    virtual void print(raw_ostream &OS) const;
2754950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
2764950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
2774950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
2784950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
2794950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scAddExpr ||
280c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky             S->getSCEVType() == scMulExpr ||
2813e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky             S->getSCEVType() == scSMaxExpr ||
2823e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky             S->getSCEVType() == scUMaxExpr;
2834950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
2844950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
2854950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
2864950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
2874950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
2884950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// SCEVAddExpr - This node represents an addition of some number of SCEVs.
2894950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
2904950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  class SCEVAddExpr : public SCEVCommutativeExpr {
291246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
292246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
293adf3eab7735741926c67e6fc12b952500c45a9baDan Gohman    explicit SCEVAddExpr(const std::vector<SCEVHandle> &ops)
2944950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      : SCEVCommutativeExpr(scAddExpr, ops) {
2954950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
2964950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
2974950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  public:
2984950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual const char *getOperationStr() const { return " + "; }
2994950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3004950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
3014950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVAddExpr *S) { return true; }
3024950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
3034950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scAddExpr;
3044950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
3054950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
3064950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3074950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
3084950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// SCEVMulExpr - This node represents multiplication of some number of SCEVs.
3094950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
3104950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  class SCEVMulExpr : public SCEVCommutativeExpr {
311246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
312246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
313adf3eab7735741926c67e6fc12b952500c45a9baDan Gohman    explicit SCEVMulExpr(const std::vector<SCEVHandle> &ops)
3144950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      : SCEVCommutativeExpr(scMulExpr, ops) {
3154950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
3164950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3174950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  public:
3184950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual const char *getOperationStr() const { return " * "; }
3194950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3204950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
3214950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVMulExpr *S) { return true; }
3224950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
3234950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scMulExpr;
3244950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
3254950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
3264950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3274950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3284950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
329e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz  /// SCEVUDivExpr - This class represents a binary unsigned division operation.
3304950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
331e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz  class SCEVUDivExpr : public SCEV {
332246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
333246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
3344950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    SCEVHandle LHS, RHS;
335e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz    SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs)
336e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz      : SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {}
3374950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
338e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz    virtual ~SCEVUDivExpr();
3394950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  public:
3404950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const SCEVHandle &getLHS() const { return LHS; }
3414950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const SCEVHandle &getRHS() const { return RHS; }
3424950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3434950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool isLoopInvariant(const Loop *L) const {
3444950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
3454950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
3464950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3474950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool hasComputableLoopEvolution(const Loop *L) const {
3484950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return LHS->hasComputableLoopEvolution(L) &&
3494950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner             RHS->hasComputableLoopEvolution(L);
3504950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
3514950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
352afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
353246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
354246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const {
355246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
356246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
357afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner      if (L == LHS && R == RHS)
358afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner        return this;
359afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner      else
360e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz        return SE.getUDivExpr(L, R);
361afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    }
362afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner
3635a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng    bool dominates(BasicBlock *BB, DominatorTree *DT) const;
364afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner
3654950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual const Type *getType() const;
3664950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
367b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    void print(raw_ostream &OS) const;
3684950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3694950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
370e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz    static inline bool classof(const SCEVUDivExpr *S) { return true; }
3714950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
372e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz      return S->getSCEVType() == scUDivExpr;
3734950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
3744950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
3754950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3764950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3774950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
3784950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip
3791e59aa1332b67256dc0e76237eab7f6dd21a25b4Dan Gohman  /// count of the specified loop.  This is the primary focus of the
3801e59aa1332b67256dc0e76237eab7f6dd21a25b4Dan Gohman  /// ScalarEvolution framework; all the other SCEV subclasses are mostly just
3811e59aa1332b67256dc0e76237eab7f6dd21a25b4Dan Gohman  /// supporting infrastructure to allow SCEVAddRecExpr expressions to be
3821e59aa1332b67256dc0e76237eab7f6dd21a25b4Dan Gohman  /// created and analyzed.
3834950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
3844950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// All operands of an AddRec are required to be loop invariant.
3854950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
386ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  class SCEVAddRecExpr : public SCEVNAryExpr {
387246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
388246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
3894950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const Loop *L;
3904950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
3914950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    SCEVAddRecExpr(const std::vector<SCEVHandle> &ops, const Loop *l)
392ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman      : SCEVNAryExpr(scAddRecExpr, ops), L(l) {
39334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      for (size_t i = 0, e = Operands.size(); i != e; ++i)
3944950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner        assert(Operands[i]->isLoopInvariant(l) &&
3954950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner               "Operands of AddRec must be loop-invariant!");
3964950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
3974950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    ~SCEVAddRecExpr();
3984950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
399ecb403a9d3a340009c266d05cfca2bd778c7b156Dan Gohman  public:
4004950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const SCEVHandle &getStart() const { return Operands[0]; }
4014950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    const Loop *getLoop() const { return L; }
4024950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4034950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// getStepRecurrence - This method constructs and returns the recurrence
4044950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// indicating how much this expression steps by.  If this is a polynomial
4054950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// of degree N, it returns a chrec of degree N-1.
406246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    SCEVHandle getStepRecurrence(ScalarEvolution &SE) const {
40717f1972c770dc18f5c7c3c95776b4d62ae9e121dDan Gohman      if (isAffine()) return getOperand(1);
408246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman      return SE.getAddRecExpr(std::vector<SCEVHandle>(op_begin()+1,op_end()),
409246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                              getLoop());
4104950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
4114950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4124950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool hasComputableLoopEvolution(const Loop *QL) const {
4134950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      if (L == QL) return true;
4144950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return false;
4154950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
4164950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4174950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool isLoopInvariant(const Loop *QueryLoop) const;
4184950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4194950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// isAffine - Return true if this is an affine AddRec (i.e., it represents
4204950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// an expressions A+B*x where A and B are loop invariant values.
4214950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    bool isAffine() const {
4224950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      // We know that the start value is invariant.  This expression is thus
4234950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      // affine iff the step is also invariant.
4244950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return getNumOperands() == 2;
4254950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
4264950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4274950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// isQuadratic - Return true if this is an quadratic AddRec (i.e., it
4284950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// represents an expressions A+B*x+C*x^2 where A, B and C are loop
4294950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// invariant values.  This corresponds to an addrec of the form {L,+,M,+,N}
4304950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    bool isQuadratic() const {
4314950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return getNumOperands() == 3;
4324950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
4334950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4344950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// evaluateAtIteration - Return the value of this chain of recurrences at
4354950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// the specified iteration number.
436246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    SCEVHandle evaluateAtIteration(SCEVHandle It, ScalarEvolution &SE) const;
4374950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4384950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// getNumIterationsInRange - Return the number of iterations of this loop
4394950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// that produce values in the specified constant range.  Another way of
4404950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// looking at this is that it returns the first iteration number where the
4414950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// value is not in the condition, thus computing the exit count.  If the
4424950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// iteration count can't be computed, an instance of SCEVCouldNotCompute is
443eefdebe002ede066bf80859e72aec831cfd1d92dNick Lewycky    /// returned.
444246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    SCEVHandle getNumIterationsInRange(ConstantRange Range,
445246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                       ScalarEvolution &SE) const;
4464950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
447afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
448246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
449246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const;
4504950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
451b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    virtual void print(raw_ostream &OS) const;
4524950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
4534950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
4544950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVAddRecExpr *S) { return true; }
4554950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
4564950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scAddRecExpr;
4574950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
4584950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
4594950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
460c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky
461c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky  //===--------------------------------------------------------------------===//
462c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky  /// SCEVSMaxExpr - This class represents a signed maximum selection.
463c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky  ///
464c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky  class SCEVSMaxExpr : public SCEVCommutativeExpr {
465c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    friend class ScalarEvolution;
466c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky
467c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    explicit SCEVSMaxExpr(const std::vector<SCEVHandle> &ops)
468c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky      : SCEVCommutativeExpr(scSMaxExpr, ops) {
469c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    }
470c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky
471c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky  public:
472c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    virtual const char *getOperationStr() const { return " smax "; }
473c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky
474c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    /// Methods for support type inquiry through isa, cast, and dyn_cast:
475c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    static inline bool classof(const SCEVSMaxExpr *S) { return true; }
476c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    static inline bool classof(const SCEV *S) {
477c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky      return S->getSCEVType() == scSMaxExpr;
478c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky    }
479c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky  };
480c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky
481c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky
4824950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  //===--------------------------------------------------------------------===//
4833e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky  /// SCEVUMaxExpr - This class represents an unsigned maximum selection.
4843e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky  ///
4853e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky  class SCEVUMaxExpr : public SCEVCommutativeExpr {
4863e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    friend class ScalarEvolution;
4873e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky
4883e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    explicit SCEVUMaxExpr(const std::vector<SCEVHandle> &ops)
4893e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky      : SCEVCommutativeExpr(scUMaxExpr, ops) {
4903e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    }
4913e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky
4923e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky  public:
4933e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    virtual const char *getOperationStr() const { return " umax "; }
4943e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky
4953e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    /// Methods for support type inquiry through isa, cast, and dyn_cast:
4963e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    static inline bool classof(const SCEVUMaxExpr *S) { return true; }
4973e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    static inline bool classof(const SCEV *S) {
4983e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky      return S->getSCEVType() == scUMaxExpr;
4993e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky    }
5003e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky  };
5013e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky
5023e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky
5033e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky  //===--------------------------------------------------------------------===//
5044950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
5054950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// value, and only represent it as it's LLVM Value.  This is the "bottom"
5064950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  /// value for the analysis.
5074950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  ///
5084950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  class SCEVUnknown : public SCEV {
509246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman    friend class ScalarEvolution;
510246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman
5114950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    Value *V;
512adf3eab7735741926c67e6fc12b952500c45a9baDan Gohman    explicit SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {}
5134950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
5144950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  protected:
5154950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    ~SCEVUnknown();
5164950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  public:
5172cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner    Value *getValue() const { return V; }
5184950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
5194950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool isLoopInvariant(const Loop *L) const;
5204950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual bool hasComputableLoopEvolution(const Loop *QL) const {
5214950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return false; // not computable
5224950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
5234950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
524afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
525246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 const SCEVHandle &Conc,
526246b2564d3bbbafe06ebf6a67745cd24141b5cb4Dan Gohman                                                 ScalarEvolution &SE) const {
527afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner      if (&*Sym == this) return Conc;
528afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner      return this;
529afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner    }
530afc0dc7184cf73ff7ac64e516284fbe0c7023ba4Chris Lattner
5315a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng    bool dominates(BasicBlock *BB, DominatorTree *DT) const;
5325a6c1a840ad343c0ed2fa54a0edb50b61f828f0fEvan Cheng
5334950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    virtual const Type *getType() const;
5344950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
535b7ef72963b2215ca23c27fa8ea777bada06994d0Dan Gohman    virtual void print(raw_ostream &OS) const;
5364950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
5374950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    /// Methods for support type inquiry through isa, cast, and dyn_cast:
5384950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEVUnknown *S) { return true; }
5394950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    static inline bool classof(const SCEV *S) {
5404950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner      return S->getSCEVType() == scUnknown;
5414950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner    }
5424950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner  };
5432cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner
5442cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner  /// SCEVVisitor - This class defines a simple visitor class that may be used
5452cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner  /// for various SCEV analysis purposes.
5462cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner  template<typename SC, typename RetVal=void>
5472cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner  struct SCEVVisitor {
548890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman    RetVal visit(const SCEV *S) {
5492cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      switch (S->getSCEVType()) {
5502cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scConstant:
551890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitConstant((const SCEVConstant*)S);
5522cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scTruncate:
553890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitTruncateExpr((const SCEVTruncateExpr*)S);
5542cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scZeroExtend:
555890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr*)S);
556d19534add90a2a894af61523b830887097bb780bDan Gohman      case scSignExtend:
557890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitSignExtendExpr((const SCEVSignExtendExpr*)S);
5582cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scAddExpr:
559890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitAddExpr((const SCEVAddExpr*)S);
5602cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scMulExpr:
561890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitMulExpr((const SCEVMulExpr*)S);
562e3320a1bcce3f6653e109cc86ee1011b0a61d808Wojciech Matyjewicz      case scUDivExpr:
563890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitUDivExpr((const SCEVUDivExpr*)S);
5642cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scAddRecExpr:
565890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitAddRecExpr((const SCEVAddRecExpr*)S);
566c54c561c9f7270c055dd7ba75a3a003b771a42d9Nick Lewycky      case scSMaxExpr:
567890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
5683e6307698084e7adfc10b739442ae29742beefd0Nick Lewycky      case scUMaxExpr:
569890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
5702cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scUnknown:
571890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
5722cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      case scCouldNotCompute:
573890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman        return ((SC*)this)->visitCouldNotCompute((const SCEVCouldNotCompute*)S);
5742cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      default:
5752cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner        assert(0 && "Unknown SCEV type!");
5760ebf428e48ab258012d94d8efa05a4ae5932e2dbChris Lattner        abort();
5772cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      }
5782cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner    }
5792cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner
580890f92b744fb074465bc2b7006ee753a181f62a4Dan Gohman    RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S) {
5812cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      assert(0 && "Invalid use of SCEVCouldNotCompute!");
5822cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      abort();
5832cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner      return RetVal();
5842cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner    }
5852cdf0a7a32f08674562b0cf6b071b96b36421f87Chris Lattner  };
5864950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner}
5874950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner
5884950e88e0fa7c44c0b54e2f64ddf57415ed83d40Chris Lattner#endif
589