ScalarEvolutionExpressions.h revision 75144f93eb7e4dbf22d308d21581ae255dd520c6
1//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the classes used to represent and build scalar expressions.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
15#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
16
17#include "llvm/Analysis/ScalarEvolution.h"
18#include "llvm/Support/ErrorHandling.h"
19
20namespace llvm {
21  class ConstantInt;
22  class ConstantRange;
23  class DominatorTree;
24
25  enum SCEVTypes {
26    // These should be ordered in terms of increasing complexity to make the
27    // folders simpler.
28    scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
29    scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
30    scFieldOffset, scAllocSize, scUnknown, scCouldNotCompute
31  };
32
33  //===--------------------------------------------------------------------===//
34  /// SCEVConstant - This class represents a constant integer value.
35  ///
36  class SCEVConstant : public SCEV {
37    friend class ScalarEvolution;
38
39    ConstantInt *V;
40    SCEVConstant(const FoldingSetNodeID &ID, ConstantInt *v) :
41      SCEV(ID, scConstant), V(v) {}
42  public:
43    ConstantInt *getValue() const { return V; }
44
45    virtual bool isLoopInvariant(const Loop *L) const {
46      return true;
47    }
48
49    virtual bool hasComputableLoopEvolution(const Loop *L) const {
50      return false;  // Not loop variant
51    }
52
53    virtual const Type *getType() const;
54
55    virtual bool hasOperand(const SCEV *) const {
56      return false;
57    }
58
59    bool dominates(BasicBlock *BB, DominatorTree *DT) const {
60      return true;
61    }
62
63    virtual void print(raw_ostream &OS) const;
64
65    /// Methods for support type inquiry through isa, cast, and dyn_cast:
66    static inline bool classof(const SCEVConstant *S) { return true; }
67    static inline bool classof(const SCEV *S) {
68      return S->getSCEVType() == scConstant;
69    }
70  };
71
72  //===--------------------------------------------------------------------===//
73  /// SCEVCastExpr - This is the base class for unary cast operator classes.
74  ///
75  class SCEVCastExpr : public SCEV {
76  protected:
77    const SCEV *Op;
78    const Type *Ty;
79
80    SCEVCastExpr(const FoldingSetNodeID &ID,
81                 unsigned SCEVTy, const SCEV *op, const Type *ty);
82
83  public:
84    const SCEV *getOperand() const { return Op; }
85    virtual const Type *getType() const { return Ty; }
86
87    virtual bool isLoopInvariant(const Loop *L) const {
88      return Op->isLoopInvariant(L);
89    }
90
91    virtual bool hasComputableLoopEvolution(const Loop *L) const {
92      return Op->hasComputableLoopEvolution(L);
93    }
94
95    virtual bool hasOperand(const SCEV *O) const {
96      return Op == O || Op->hasOperand(O);
97    }
98
99    virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const;
100
101    /// Methods for support type inquiry through isa, cast, and dyn_cast:
102    static inline bool classof(const SCEVCastExpr *S) { return true; }
103    static inline bool classof(const SCEV *S) {
104      return S->getSCEVType() == scTruncate ||
105             S->getSCEVType() == scZeroExtend ||
106             S->getSCEVType() == scSignExtend;
107    }
108  };
109
110  //===--------------------------------------------------------------------===//
111  /// SCEVTruncateExpr - This class represents a truncation of an integer value
112  /// to a smaller integer value.
113  ///
114  class SCEVTruncateExpr : public SCEVCastExpr {
115    friend class ScalarEvolution;
116
117    SCEVTruncateExpr(const FoldingSetNodeID &ID,
118                     const SCEV *op, const Type *ty);
119
120  public:
121    virtual void print(raw_ostream &OS) const;
122
123    /// Methods for support type inquiry through isa, cast, and dyn_cast:
124    static inline bool classof(const SCEVTruncateExpr *S) { return true; }
125    static inline bool classof(const SCEV *S) {
126      return S->getSCEVType() == scTruncate;
127    }
128  };
129
130  //===--------------------------------------------------------------------===//
131  /// SCEVZeroExtendExpr - This class represents a zero extension of a small
132  /// integer value to a larger integer value.
133  ///
134  class SCEVZeroExtendExpr : public SCEVCastExpr {
135    friend class ScalarEvolution;
136
137    SCEVZeroExtendExpr(const FoldingSetNodeID &ID,
138                       const SCEV *op, const Type *ty);
139
140  public:
141    virtual void print(raw_ostream &OS) const;
142
143    /// Methods for support type inquiry through isa, cast, and dyn_cast:
144    static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
145    static inline bool classof(const SCEV *S) {
146      return S->getSCEVType() == scZeroExtend;
147    }
148  };
149
150  //===--------------------------------------------------------------------===//
151  /// SCEVSignExtendExpr - This class represents a sign extension of a small
152  /// integer value to a larger integer value.
153  ///
154  class SCEVSignExtendExpr : public SCEVCastExpr {
155    friend class ScalarEvolution;
156
157    SCEVSignExtendExpr(const FoldingSetNodeID &ID,
158                       const SCEV *op, const Type *ty);
159
160  public:
161    virtual void print(raw_ostream &OS) const;
162
163    /// Methods for support type inquiry through isa, cast, and dyn_cast:
164    static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
165    static inline bool classof(const SCEV *S) {
166      return S->getSCEVType() == scSignExtend;
167    }
168  };
169
170
171  //===--------------------------------------------------------------------===//
172  /// SCEVNAryExpr - This node is a base class providing common
173  /// functionality for n'ary operators.
174  ///
175  class SCEVNAryExpr : public SCEV {
176  protected:
177    SmallVector<const SCEV *, 8> Operands;
178
179    SCEVNAryExpr(const FoldingSetNodeID &ID,
180                 enum SCEVTypes T, const SmallVectorImpl<const SCEV *> &ops)
181      : SCEV(ID, T), Operands(ops.begin(), ops.end()) {}
182
183  public:
184    unsigned getNumOperands() const { return (unsigned)Operands.size(); }
185    const SCEV *getOperand(unsigned i) const {
186      assert(i < Operands.size() && "Operand index out of range!");
187      return Operands[i];
188    }
189
190    const SmallVectorImpl<const SCEV *> &getOperands() const {
191      return Operands;
192    }
193    typedef SmallVectorImpl<const SCEV *>::const_iterator op_iterator;
194    op_iterator op_begin() const { return Operands.begin(); }
195    op_iterator op_end() const { return Operands.end(); }
196
197    virtual bool isLoopInvariant(const Loop *L) const {
198      for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
199        if (!getOperand(i)->isLoopInvariant(L)) return false;
200      return true;
201    }
202
203    // hasComputableLoopEvolution - N-ary expressions have computable loop
204    // evolutions iff they have at least one operand that varies with the loop,
205    // but that all varying operands are computable.
206    virtual bool hasComputableLoopEvolution(const Loop *L) const {
207      bool HasVarying = false;
208      for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
209        if (!getOperand(i)->isLoopInvariant(L)) {
210          if (getOperand(i)->hasComputableLoopEvolution(L))
211            HasVarying = true;
212          else
213            return false;
214        }
215      return HasVarying;
216    }
217
218    virtual bool hasOperand(const SCEV *O) const {
219      for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
220        if (O == getOperand(i) || getOperand(i)->hasOperand(O))
221          return true;
222      return false;
223    }
224
225    bool dominates(BasicBlock *BB, DominatorTree *DT) const;
226
227    virtual const Type *getType() const { return getOperand(0)->getType(); }
228
229    /// Methods for support type inquiry through isa, cast, and dyn_cast:
230    static inline bool classof(const SCEVNAryExpr *S) { return true; }
231    static inline bool classof(const SCEV *S) {
232      return S->getSCEVType() == scAddExpr ||
233             S->getSCEVType() == scMulExpr ||
234             S->getSCEVType() == scSMaxExpr ||
235             S->getSCEVType() == scUMaxExpr ||
236             S->getSCEVType() == scAddRecExpr;
237    }
238  };
239
240  //===--------------------------------------------------------------------===//
241  /// SCEVCommutativeExpr - This node is the base class for n'ary commutative
242  /// operators.
243  ///
244  class SCEVCommutativeExpr : public SCEVNAryExpr {
245  protected:
246    SCEVCommutativeExpr(const FoldingSetNodeID &ID,
247                        enum SCEVTypes T,
248                        const SmallVectorImpl<const SCEV *> &ops)
249      : SCEVNAryExpr(ID, T, ops) {}
250
251  public:
252    virtual const char *getOperationStr() const = 0;
253
254    virtual void print(raw_ostream &OS) const;
255
256    /// Methods for support type inquiry through isa, cast, and dyn_cast:
257    static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
258    static inline bool classof(const SCEV *S) {
259      return S->getSCEVType() == scAddExpr ||
260             S->getSCEVType() == scMulExpr ||
261             S->getSCEVType() == scSMaxExpr ||
262             S->getSCEVType() == scUMaxExpr;
263    }
264  };
265
266
267  //===--------------------------------------------------------------------===//
268  /// SCEVAddExpr - This node represents an addition of some number of SCEVs.
269  ///
270  class SCEVAddExpr : public SCEVCommutativeExpr {
271    friend class ScalarEvolution;
272
273    SCEVAddExpr(const FoldingSetNodeID &ID,
274                const SmallVectorImpl<const SCEV *> &ops)
275      : SCEVCommutativeExpr(ID, scAddExpr, ops) {
276    }
277
278  public:
279    virtual const char *getOperationStr() const { return " + "; }
280
281    /// Methods for support type inquiry through isa, cast, and dyn_cast:
282    static inline bool classof(const SCEVAddExpr *S) { return true; }
283    static inline bool classof(const SCEV *S) {
284      return S->getSCEVType() == scAddExpr;
285    }
286  };
287
288  //===--------------------------------------------------------------------===//
289  /// SCEVMulExpr - This node represents multiplication of some number of SCEVs.
290  ///
291  class SCEVMulExpr : public SCEVCommutativeExpr {
292    friend class ScalarEvolution;
293
294    SCEVMulExpr(const FoldingSetNodeID &ID,
295                const SmallVectorImpl<const SCEV *> &ops)
296      : SCEVCommutativeExpr(ID, scMulExpr, ops) {
297    }
298
299  public:
300    virtual const char *getOperationStr() const { return " * "; }
301
302    /// Methods for support type inquiry through isa, cast, and dyn_cast:
303    static inline bool classof(const SCEVMulExpr *S) { return true; }
304    static inline bool classof(const SCEV *S) {
305      return S->getSCEVType() == scMulExpr;
306    }
307  };
308
309
310  //===--------------------------------------------------------------------===//
311  /// SCEVUDivExpr - This class represents a binary unsigned division operation.
312  ///
313  class SCEVUDivExpr : public SCEV {
314    friend class ScalarEvolution;
315
316    const SCEV *LHS;
317    const SCEV *RHS;
318    SCEVUDivExpr(const FoldingSetNodeID &ID, const SCEV *lhs, const SCEV *rhs)
319      : SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {}
320
321  public:
322    const SCEV *getLHS() const { return LHS; }
323    const SCEV *getRHS() const { return RHS; }
324
325    virtual bool isLoopInvariant(const Loop *L) const {
326      return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
327    }
328
329    virtual bool hasComputableLoopEvolution(const Loop *L) const {
330      return LHS->hasComputableLoopEvolution(L) &&
331             RHS->hasComputableLoopEvolution(L);
332    }
333
334    virtual bool hasOperand(const SCEV *O) const {
335      return O == LHS || O == RHS || LHS->hasOperand(O) || RHS->hasOperand(O);
336    }
337
338    bool dominates(BasicBlock *BB, DominatorTree *DT) const;
339
340    virtual const Type *getType() const;
341
342    void print(raw_ostream &OS) const;
343
344    /// Methods for support type inquiry through isa, cast, and dyn_cast:
345    static inline bool classof(const SCEVUDivExpr *S) { return true; }
346    static inline bool classof(const SCEV *S) {
347      return S->getSCEVType() == scUDivExpr;
348    }
349  };
350
351
352  //===--------------------------------------------------------------------===//
353  /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip
354  /// count of the specified loop.  This is the primary focus of the
355  /// ScalarEvolution framework; all the other SCEV subclasses are mostly just
356  /// supporting infrastructure to allow SCEVAddRecExpr expressions to be
357  /// created and analyzed.
358  ///
359  /// All operands of an AddRec are required to be loop invariant.
360  ///
361  class SCEVAddRecExpr : public SCEVNAryExpr {
362    friend class ScalarEvolution;
363
364    const Loop *L;
365
366    SCEVAddRecExpr(const FoldingSetNodeID &ID,
367                   const SmallVectorImpl<const SCEV *> &ops, const Loop *l)
368      : SCEVNAryExpr(ID, scAddRecExpr, ops), L(l) {
369      for (size_t i = 0, e = Operands.size(); i != e; ++i)
370        assert(Operands[i]->isLoopInvariant(l) &&
371               "Operands of AddRec must be loop-invariant!");
372    }
373
374  public:
375    const SCEV *getStart() const { return Operands[0]; }
376    const Loop *getLoop() const { return L; }
377
378    /// getStepRecurrence - This method constructs and returns the recurrence
379    /// indicating how much this expression steps by.  If this is a polynomial
380    /// of degree N, it returns a chrec of degree N-1.
381    const SCEV *getStepRecurrence(ScalarEvolution &SE) const {
382      if (isAffine()) return getOperand(1);
383      return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1,
384                                                           op_end()),
385                              getLoop());
386    }
387
388    virtual bool hasComputableLoopEvolution(const Loop *QL) const {
389      if (L == QL) return true;
390      return false;
391    }
392
393    virtual bool isLoopInvariant(const Loop *QueryLoop) const;
394
395    /// isAffine - Return true if this is an affine AddRec (i.e., it represents
396    /// an expressions A+B*x where A and B are loop invariant values.
397    bool isAffine() const {
398      // We know that the start value is invariant.  This expression is thus
399      // affine iff the step is also invariant.
400      return getNumOperands() == 2;
401    }
402
403    /// isQuadratic - Return true if this is an quadratic AddRec (i.e., it
404    /// represents an expressions A+B*x+C*x^2 where A, B and C are loop
405    /// invariant values.  This corresponds to an addrec of the form {L,+,M,+,N}
406    bool isQuadratic() const {
407      return getNumOperands() == 3;
408    }
409
410    /// evaluateAtIteration - Return the value of this chain of recurrences at
411    /// the specified iteration number.
412    const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
413
414    /// getNumIterationsInRange - Return the number of iterations of this loop
415    /// that produce values in the specified constant range.  Another way of
416    /// looking at this is that it returns the first iteration number where the
417    /// value is not in the condition, thus computing the exit count.  If the
418    /// iteration count can't be computed, an instance of SCEVCouldNotCompute is
419    /// returned.
420    const SCEV *getNumIterationsInRange(ConstantRange Range,
421                                       ScalarEvolution &SE) const;
422
423    /// getPostIncExpr - Return an expression representing the value of
424    /// this expression one iteration of the loop ahead.
425    const SCEVAddRecExpr *getPostIncExpr(ScalarEvolution &SE) const {
426      return cast<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
427    }
428
429    bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); }
430    void setHasNoUnsignedWrap(bool B) {
431      SubclassData = (SubclassData & ~(1 << 0)) | (B << 0);
432    }
433    bool hasNoSignedWrap() const { return SubclassData & (1 << 1); }
434    void setHasNoSignedWrap(bool B) {
435      SubclassData = (SubclassData & ~(1 << 1)) | (B << 1);
436    }
437
438    virtual void print(raw_ostream &OS) const;
439
440    /// Methods for support type inquiry through isa, cast, and dyn_cast:
441    static inline bool classof(const SCEVAddRecExpr *S) { return true; }
442    static inline bool classof(const SCEV *S) {
443      return S->getSCEVType() == scAddRecExpr;
444    }
445  };
446
447
448  //===--------------------------------------------------------------------===//
449  /// SCEVSMaxExpr - This class represents a signed maximum selection.
450  ///
451  class SCEVSMaxExpr : public SCEVCommutativeExpr {
452    friend class ScalarEvolution;
453
454    SCEVSMaxExpr(const FoldingSetNodeID &ID,
455                 const SmallVectorImpl<const SCEV *> &ops)
456      : SCEVCommutativeExpr(ID, scSMaxExpr, ops) {
457    }
458
459  public:
460    virtual const char *getOperationStr() const { return " smax "; }
461
462    /// Methods for support type inquiry through isa, cast, and dyn_cast:
463    static inline bool classof(const SCEVSMaxExpr *S) { return true; }
464    static inline bool classof(const SCEV *S) {
465      return S->getSCEVType() == scSMaxExpr;
466    }
467  };
468
469
470  //===--------------------------------------------------------------------===//
471  /// SCEVUMaxExpr - This class represents an unsigned maximum selection.
472  ///
473  class SCEVUMaxExpr : public SCEVCommutativeExpr {
474    friend class ScalarEvolution;
475
476    SCEVUMaxExpr(const FoldingSetNodeID &ID,
477                 const SmallVectorImpl<const SCEV *> &ops)
478      : SCEVCommutativeExpr(ID, scUMaxExpr, ops) {
479    }
480
481  public:
482    virtual const char *getOperationStr() const { return " umax "; }
483
484    /// Methods for support type inquiry through isa, cast, and dyn_cast:
485    static inline bool classof(const SCEVUMaxExpr *S) { return true; }
486    static inline bool classof(const SCEV *S) {
487      return S->getSCEVType() == scUMaxExpr;
488    }
489  };
490
491  //===--------------------------------------------------------------------===//
492  /// SCEVTargetDataConstant - This node is the base class for representing
493  /// target-dependent values in a target-independent way.
494  ///
495  class SCEVTargetDataConstant : public SCEV {
496  protected:
497    const Type *Ty;
498    SCEVTargetDataConstant(const FoldingSetNodeID &ID, enum SCEVTypes T,
499                           const Type *ty) :
500      SCEV(ID, T), Ty(ty) {}
501
502  public:
503    virtual bool isLoopInvariant(const Loop *) const { return true; }
504    virtual bool hasComputableLoopEvolution(const Loop *) const {
505      return false; // not computable
506    }
507
508    virtual bool hasOperand(const SCEV *) const {
509      return false;
510    }
511
512    bool dominates(BasicBlock *, DominatorTree *) const {
513      return true;
514    }
515
516    virtual const Type *getType() const { return Ty; }
517
518    /// Methods for support type inquiry through isa, cast, and dyn_cast:
519    static inline bool classof(const SCEVTargetDataConstant *S) { return true; }
520    static inline bool classof(const SCEV *S) {
521      return S->getSCEVType() == scFieldOffset ||
522             S->getSCEVType() == scAllocSize;
523    }
524  };
525
526  //===--------------------------------------------------------------------===//
527  /// SCEVFieldOffsetExpr - This node represents an offsetof expression.
528  ///
529  class SCEVFieldOffsetExpr : public SCEVTargetDataConstant {
530    friend class ScalarEvolution;
531
532    const StructType *STy;
533    unsigned FieldNo;
534    SCEVFieldOffsetExpr(const FoldingSetNodeID &ID, const Type *ty,
535                        const StructType *sty, unsigned fieldno) :
536      SCEVTargetDataConstant(ID, scFieldOffset, ty),
537      STy(sty), FieldNo(fieldno) {}
538
539  public:
540    const StructType *getStructType() const { return STy; }
541    unsigned getFieldNo() const { return FieldNo; }
542
543    virtual void print(raw_ostream &OS) const;
544
545    /// Methods for support type inquiry through isa, cast, and dyn_cast:
546    static inline bool classof(const SCEVFieldOffsetExpr *S) { return true; }
547    static inline bool classof(const SCEV *S) {
548      return S->getSCEVType() == scFieldOffset;
549    }
550  };
551
552  //===--------------------------------------------------------------------===//
553  /// SCEVAllocSize - This node represents a sizeof expression.
554  ///
555  class SCEVAllocSizeExpr : public SCEVTargetDataConstant {
556    friend class ScalarEvolution;
557
558    const Type *AllocTy;
559    SCEVAllocSizeExpr(const FoldingSetNodeID &ID,
560                      const Type *ty, const Type *allocty) :
561      SCEVTargetDataConstant(ID, scAllocSize, ty),
562      AllocTy(allocty) {}
563
564  public:
565    const Type *getAllocType() const { return AllocTy; }
566
567    virtual void print(raw_ostream &OS) const;
568
569    /// Methods for support type inquiry through isa, cast, and dyn_cast:
570    static inline bool classof(const SCEVAllocSizeExpr *S) { return true; }
571    static inline bool classof(const SCEV *S) {
572      return S->getSCEVType() == scAllocSize;
573    }
574  };
575
576  //===--------------------------------------------------------------------===//
577  /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
578  /// value, and only represent it as its LLVM Value.  This is the "bottom"
579  /// value for the analysis.
580  ///
581  class SCEVUnknown : public SCEV {
582    friend class ScalarEvolution;
583
584    Value *V;
585    SCEVUnknown(const FoldingSetNodeID &ID, Value *v) :
586      SCEV(ID, scUnknown), V(v) {}
587
588  public:
589    Value *getValue() const { return V; }
590
591    virtual bool isLoopInvariant(const Loop *L) const;
592    virtual bool hasComputableLoopEvolution(const Loop *QL) const {
593      return false; // not computable
594    }
595
596    virtual bool hasOperand(const SCEV *) const {
597      return false;
598    }
599
600    bool dominates(BasicBlock *BB, DominatorTree *DT) const;
601
602    virtual const Type *getType() const;
603
604    virtual void print(raw_ostream &OS) const;
605
606    /// Methods for support type inquiry through isa, cast, and dyn_cast:
607    static inline bool classof(const SCEVUnknown *S) { return true; }
608    static inline bool classof(const SCEV *S) {
609      return S->getSCEVType() == scUnknown;
610    }
611  };
612
613  /// SCEVVisitor - This class defines a simple visitor class that may be used
614  /// for various SCEV analysis purposes.
615  template<typename SC, typename RetVal=void>
616  struct SCEVVisitor {
617    RetVal visit(const SCEV *S) {
618      switch (S->getSCEVType()) {
619      case scConstant:
620        return ((SC*)this)->visitConstant((const SCEVConstant*)S);
621      case scTruncate:
622        return ((SC*)this)->visitTruncateExpr((const SCEVTruncateExpr*)S);
623      case scZeroExtend:
624        return ((SC*)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr*)S);
625      case scSignExtend:
626        return ((SC*)this)->visitSignExtendExpr((const SCEVSignExtendExpr*)S);
627      case scAddExpr:
628        return ((SC*)this)->visitAddExpr((const SCEVAddExpr*)S);
629      case scMulExpr:
630        return ((SC*)this)->visitMulExpr((const SCEVMulExpr*)S);
631      case scUDivExpr:
632        return ((SC*)this)->visitUDivExpr((const SCEVUDivExpr*)S);
633      case scAddRecExpr:
634        return ((SC*)this)->visitAddRecExpr((const SCEVAddRecExpr*)S);
635      case scSMaxExpr:
636        return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
637      case scUMaxExpr:
638        return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
639      case scFieldOffset:
640        return ((SC*)this)->visitFieldOffsetExpr((const SCEVFieldOffsetExpr*)S);
641      case scAllocSize:
642        return ((SC*)this)->visitAllocSizeExpr((const SCEVAllocSizeExpr*)S);
643      case scUnknown:
644        return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
645      case scCouldNotCompute:
646        return ((SC*)this)->visitCouldNotCompute((const SCEVCouldNotCompute*)S);
647      default:
648        llvm_unreachable("Unknown SCEV type!");
649      }
650    }
651
652    RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S) {
653      llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
654      return RetVal();
655    }
656  };
657}
658
659#endif
660