LLVM 24.0.0git
ScalarEvolutionExpressions.h
Go to the documentation of this file.
1//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the classes used to represent and build scalar expressions.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
14#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
15
16#include "llvm/ADT/DenseMap.h"
20#include "llvm/IR/Constants.h"
21#include "llvm/IR/ValueHandle.h"
25#include <cassert>
26#include <cstddef>
27
28namespace llvm {
29
30class APInt;
31class Constant;
32class ConstantInt;
33class ConstantRange;
34class Loop;
35class Type;
36class Value;
37
59
60/// This class represents a constant integer value.
61class SCEVConstant : public SCEV {
62 friend class ScalarEvolution;
63
64 ConstantInt *V;
65
66 SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v)
67 : SCEV(ID, scConstant, 1, v->getType()), V(v) {}
68
69public:
70 ConstantInt *getValue() const { return V; }
71 const APInt &getAPInt() const { return getValue()->getValue(); }
72
73 /// Methods for support type inquiry through isa, cast, and dyn_cast:
74 static bool classof(const SCEV *S) { return S->getSCEVType() == scConstant; }
75};
76
77/// This class represents the value of vscale, as used when defining the length
78/// of a scalable vector or returned by the llvm.vscale() intrinsic.
79class SCEVVScale : public SCEV {
80 friend class ScalarEvolution;
81
82 SCEVVScale(const FoldingSetNodeIDRef ID, Type *ty)
83 : SCEV(ID, scVScale, 0, ty) {}
84
85public:
86 /// Methods for support type inquiry through isa, cast, and dyn_cast:
87 static bool classof(const SCEV *S) { return S->getSCEVType() == scVScale; }
88};
89
90inline unsigned short computeExpressionSize(ArrayRef<SCEVUse> Args) {
91 APInt Size(16, 1);
92 for (const SCEV *Arg : Args)
93 Size = Size.uadd_sat(APInt(16, Arg->getExpressionSize()));
94 return (unsigned short)Size.getZExtValue();
95}
96
97/// This is the base class for unary cast operator classes.
98class SCEVCastExpr : public SCEV {
99protected:
101
103 SCEVUse op, Type *ty);
104
105public:
106 SCEVUse getOperand() const { return Op; }
107 SCEVUse getOperand(unsigned i) const {
108 assert(i == 0 && "Operand index out of range!");
109 return Op;
110 }
111 ArrayRef<SCEVUse> operands() const { return Op; }
112 size_t getNumOperands() const { return 1; }
113
114 /// Methods for support type inquiry through isa, cast, and dyn_cast:
115 static bool classof(const SCEV *S) {
116 return S->getSCEVType() == scPtrToAddr || S->getSCEVType() == scTruncate ||
118 }
119};
120
121/// This class represents a cast from a pointer to a pointer-sized integer
122/// value, without capturing the provenance of the pointer.
123class SCEVPtrToAddrExpr : public SCEVCastExpr {
124 friend class ScalarEvolution;
125
126 SCEVPtrToAddrExpr(const FoldingSetNodeIDRef ID, const SCEV *Op, Type *ITy);
127
128public:
129 /// Methods for support type inquiry through isa, cast, and dyn_cast:
130 static bool classof(const SCEV *S) { return S->getSCEVType() == scPtrToAddr; }
131};
132
133/// This is the base class for unary integral cast operator classes.
135protected:
137 SCEVUse op, Type *ty);
138
139public:
140 /// Methods for support type inquiry through isa, cast, and dyn_cast:
141 static bool classof(const SCEV *S) {
142 return S->getSCEVType() == scTruncate || S->getSCEVType() == scZeroExtend ||
144 }
145};
146
147/// This class represents a truncation of an integer value to a
148/// smaller integer value.
149class SCEVTruncateExpr : public SCEVIntegralCastExpr {
150 friend class ScalarEvolution;
151
152 SCEVTruncateExpr(const FoldingSetNodeIDRef ID, SCEVUse op, Type *ty);
153
154public:
155 /// Methods for support type inquiry through isa, cast, and dyn_cast:
156 static bool classof(const SCEV *S) { return S->getSCEVType() == scTruncate; }
157};
158
159/// This class represents a zero extension of a small integer value
160/// to a larger integer value.
161class SCEVZeroExtendExpr : public SCEVIntegralCastExpr {
162 friend class ScalarEvolution;
163
164 SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID, SCEVUse op, Type *ty);
165
166public:
167 /// Methods for support type inquiry through isa, cast, and dyn_cast:
168 static bool classof(const SCEV *S) {
169 return S->getSCEVType() == scZeroExtend;
170 }
171};
172
173/// This class represents a sign extension of a small integer value
174/// to a larger integer value.
175class SCEVSignExtendExpr : public SCEVIntegralCastExpr {
176 friend class ScalarEvolution;
177
178 SCEVSignExtendExpr(const FoldingSetNodeIDRef ID, SCEVUse op, Type *ty);
179
180public:
181 /// Methods for support type inquiry through isa, cast, and dyn_cast:
182 static bool classof(const SCEV *S) {
183 return S->getSCEVType() == scSignExtend;
184 }
185};
186
187/// This node is a base class providing common functionality for
188/// n'ary operators.
189class SCEVNAryExpr : public SCEV {
190protected:
191 // Since SCEVs are immutable, ScalarEvolution allocates operand
192 // arrays with its SCEVAllocator, so this class just needs a simple
193 // pointer rather than a more elaborate vector-like data structure.
194 // This also avoids the need for a non-trivial destructor.
197
199 size_t N, Type *Ty)
200 : SCEV(ID, T, computeExpressionSize(ArrayRef(O, N)), Ty), Operands(O),
201 NumOperands(N) {}
202
203public:
204 size_t getNumOperands() const { return NumOperands; }
205
206 SCEVUse getOperand(unsigned i) const {
207 assert(i < NumOperands && "Operand index out of range!");
208 return Operands[i];
209 }
210
212
214 return static_cast<NoWrapFlags>(SubclassData) & Mask;
215 }
216
217 bool hasNoUnsignedWrap() const {
219 }
220
221 bool hasNoSignedWrap() const {
223 }
224
225 bool hasNoSelfWrap() const { return getNoWrapFlags(FlagNW) != FlagAnyWrap; }
226
227 /// Methods for support type inquiry through isa, cast, and dyn_cast:
228 static bool classof(const SCEV *S) {
229 return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
230 S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
231 S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr ||
234 }
235 static bool classof(const SCEVUse *U) { return classof(U->getPointer()); }
236};
237
238/// This node is the base class for n'ary commutative operators.
240protected:
242 const SCEVUse *O, size_t N, Type *Ty)
243 : SCEVNAryExpr(ID, T, O, N, Ty) {}
244
245public:
246 /// Methods for support type inquiry through isa, cast, and dyn_cast:
247 static bool classof(const SCEV *S) {
248 return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
249 S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
250 S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr;
251 }
252
253 /// Set flags for a non-recurrence without clearing previously set flags.
255 SubclassData |= static_cast<unsigned short>(Flags);
256 }
257};
258
259/// This node represents an addition of some number of SCEVs.
260class SCEVAddExpr : public SCEVCommutativeExpr {
261 friend class ScalarEvolution;
262
263 /// The type of an add is the type of its first pointer-typed operand, if
264 /// any, otherwise the type of operand 0.
265 static Type *computeType(const SCEVUse *O, size_t N) {
267 auto *FirstPointerTypedOp =
268 find_if(Ops, [](SCEVUse Op) { return Op->getType()->isPointerTy(); });
269 if (FirstPointerTypedOp != Ops.end())
270 return (*FirstPointerTypedOp)->getType();
271 return Ops[0]->getType();
272 }
273
274 SCEVAddExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
275 : SCEVCommutativeExpr(ID, scAddExpr, O, N, computeType(O, N)) {}
276
277public:
278 /// Methods for support type inquiry through isa, cast, and dyn_cast:
279 static bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr; }
280 static bool classof(const SCEVUse *U) { return classof(U->getPointer()); }
281};
282
283/// This node represents multiplication of some number of SCEVs.
284class SCEVMulExpr : public SCEVCommutativeExpr {
285 friend class ScalarEvolution;
286
287 SCEVMulExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
288 : SCEVCommutativeExpr(ID, scMulExpr, O, N, O[0]->getType()) {}
289
290public:
291 /// Methods for support type inquiry through isa, cast, and dyn_cast:
292 static bool classof(const SCEV *S) { return S->getSCEVType() == scMulExpr; }
293 static bool classof(const SCEVUse *U) { return classof(U->getPointer()); }
294};
295
296/// This class represents a binary unsigned division operation.
297class SCEVUDivExpr : public SCEV {
298 friend class ScalarEvolution;
299
300 std::array<SCEVUse, 2> Operands;
301
302 SCEVUDivExpr(const FoldingSetNodeIDRef ID, SCEVUse lhs, SCEVUse rhs)
303 : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs}),
304 lhs->getType()) {
305 Operands[0] = lhs;
306 Operands[1] = rhs;
307 }
308
309public:
310 SCEVUse getLHS() const { return Operands[0]; }
311 SCEVUse getRHS() const { return Operands[1]; }
312 size_t getNumOperands() const { return 2; }
313 SCEVUse getOperand(unsigned i) const {
314 assert((i == 0 || i == 1) && "Operand index out of range!");
315 return i == 0 ? getLHS() : getRHS();
316 }
317
318 ArrayRef<SCEVUse> operands() const { return Operands; }
319
320 /// Methods for support type inquiry through isa, cast, and dyn_cast:
321 static bool classof(const SCEV *S) { return S->getSCEVType() == scUDivExpr; }
322};
323
324/// This node represents a polynomial recurrence on the trip count
325/// of the specified loop. This is the primary focus of the
326/// ScalarEvolution framework; all the other SCEV subclasses are
327/// mostly just supporting infrastructure to allow SCEVAddRecExpr
328/// expressions to be created and analyzed.
329///
330/// All operands of an AddRec are required to be loop invariant.
331///
332class SCEVAddRecExpr : public SCEVNAryExpr {
333 friend class ScalarEvolution;
334
335 const Loop *L;
336
337 SCEVAddRecExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N,
338 const Loop *l)
339 : SCEVNAryExpr(ID, scAddRecExpr, O, N, O[0]->getType()), L(l) {}
340
341public:
342 SCEVUse getStart() const { return Operands[0]; }
343 const Loop *getLoop() const { return L; }
344
345 /// Constructs and returns the recurrence indicating how much this
346 /// expression steps by. If this is a polynomial of degree N, it
347 /// returns a chrec of degree N-1. We cannot determine whether
348 /// the step recurrence has self-wraparound.
350 if (isAffine())
351 return getOperand(1);
352 return SE.getAddRecExpr(SmallVector<SCEVUse, 3>(operands().drop_front()),
354 }
355
356 /// Return true if this represents an expression A + B*x where A
357 /// and B are loop invariant values.
358 bool isAffine() const {
359 // We know that the start value is invariant. This expression is thus
360 // affine iff the step is also invariant.
361 return getNumOperands() == 2;
362 }
363
364 /// Return true if this represents an expression A + B*x + C*x^2
365 /// where A, B and C are loop invariant values. This corresponds
366 /// to an addrec of the form {L,+,M,+,N}
367 bool isQuadratic() const { return getNumOperands() == 3; }
368
369 /// Set flags for a recurrence without clearing any previously set flags.
370 /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
371 /// to make it easier to propagate flags.
373 if (any(Flags & (FlagNUW | FlagNSW)))
374 Flags = ScalarEvolution::setFlags(Flags, FlagNW);
375 SubclassData |= static_cast<unsigned short>(Flags);
376 }
377
378 /// Return the value of this chain of recurrences at the specified
379 /// iteration number.
380 LLVM_ABI const SCEV *evaluateAtIteration(const SCEV *It,
381 ScalarEvolution &SE) const;
382
383 /// Return the value of this chain of recurrences at the specified iteration
384 /// number. Takes an explicit list of operands to represent an AddRec.
385 LLVM_ABI static SCEVUse
387 ScalarEvolution &SE,
389
390 /// Return the value of this recurrences when its loop exits, i.e. its value
391 /// at the loop's exact backedge-taken count, or SCEVCouldNotCompute if that
392 /// count cannot be computed.
394
395 /// Return the number of iterations of this loop that produce
396 /// values in the specified constant range. Another way of
397 /// looking at this is that it returns the first iteration number
398 /// where the value is not in the condition, thus computing the
399 /// exit count. If the iteration count can't be computed, an
400 /// instance of SCEVCouldNotCompute is returned.
402 ScalarEvolution &SE) const;
403
404 /// Return an expression representing the value of this expression
405 /// one iteration of the loop ahead.
407
408 /// Methods for support type inquiry through isa, cast, and dyn_cast:
409 static bool classof(const SCEV *S) {
410 return S->getSCEVType() == scAddRecExpr;
411 }
412};
413
414/// This node is the base class min/max selections.
416 friend class ScalarEvolution;
417
418 static bool isMinMaxType(enum SCEVTypes T) {
419 return T == scSMaxExpr || T == scUMaxExpr || T == scSMinExpr ||
420 T == scUMinExpr;
421 }
422
423protected:
424 /// Note: Constructing subclasses via this constructor is allowed
426 const SCEVUse *O, size_t N)
427 : SCEVCommutativeExpr(ID, T, O, N, O[0]->getType()) {
428 assert(isMinMaxType(T));
429 // Min and max never overflow
431 }
432
433public:
434 static bool classof(const SCEV *S) { return isMinMaxType(S->getSCEVType()); }
435
436 static enum SCEVTypes negate(enum SCEVTypes T) {
437 switch (T) {
438 case scSMaxExpr:
439 return scSMinExpr;
440 case scSMinExpr:
441 return scSMaxExpr;
442 case scUMaxExpr:
443 return scUMinExpr;
444 case scUMinExpr:
445 return scUMaxExpr;
446 default:
447 llvm_unreachable("Not a min or max SCEV type!");
448 }
449 }
450};
451
452/// This class represents a signed maximum selection.
453class SCEVSMaxExpr : public SCEVMinMaxExpr {
454 friend class ScalarEvolution;
455
456 SCEVSMaxExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
457 : SCEVMinMaxExpr(ID, scSMaxExpr, O, N) {}
458
459public:
460 /// Methods for support type inquiry through isa, cast, and dyn_cast:
461 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMaxExpr; }
462};
463
464/// This class represents an unsigned maximum selection.
465class SCEVUMaxExpr : public SCEVMinMaxExpr {
466 friend class ScalarEvolution;
467
468 SCEVUMaxExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
469 : SCEVMinMaxExpr(ID, scUMaxExpr, O, N) {}
470
471public:
472 /// Methods for support type inquiry through isa, cast, and dyn_cast:
473 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMaxExpr; }
474};
475
476/// This class represents a signed minimum selection.
477class SCEVSMinExpr : public SCEVMinMaxExpr {
478 friend class ScalarEvolution;
479
480 SCEVSMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
481 : SCEVMinMaxExpr(ID, scSMinExpr, O, N) {}
482
483public:
484 /// Methods for support type inquiry through isa, cast, and dyn_cast:
485 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMinExpr; }
486};
487
488/// This class represents an unsigned minimum selection.
489class SCEVUMinExpr : public SCEVMinMaxExpr {
490 friend class ScalarEvolution;
491
492 SCEVUMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
493 : SCEVMinMaxExpr(ID, scUMinExpr, O, N) {}
494
495public:
496 /// Methods for support type inquiry through isa, cast, and dyn_cast:
497 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMinExpr; }
498};
499
500/// This node is the base class for sequential/in-order min/max selections.
501/// Note that their fundamental difference from SCEVMinMaxExpr's is that they
502/// are early-returning upon reaching saturation point.
503/// I.e. given `0 umin_seq poison`, the result will be `0`, while the result of
504/// `0 umin poison` is `poison`. When returning early, later expressions are not
505/// executed, so `0 umin_seq (%x u/ 0)` does not result in undefined behavior.
507 friend class ScalarEvolution;
508
509 static bool isSequentialMinMaxType(enum SCEVTypes T) {
510 return T == scSequentialUMinExpr;
511 }
512
513 /// Set flags for a non-recurrence without clearing previously set flags.
514 void setNoWrapFlags(NoWrapFlags Flags) {
515 SubclassData |= static_cast<unsigned short>(Flags);
516 }
517
518protected:
519 /// Note: Constructing subclasses via this constructor is allowed
521 const SCEVUse *O, size_t N)
522 : SCEVNAryExpr(ID, T, O, N, O[0]->getType()) {
523 assert(isSequentialMinMaxType(T));
524 // Min and max never overflow
525 setNoWrapFlags(FlagNUW | FlagNSW);
526 }
527
528public:
530 assert(isSequentialMinMaxType(Ty));
531 switch (Ty) {
533 return scUMinExpr;
534 default:
535 llvm_unreachable("Not a sequential min/max type.");
536 }
537 }
538
542
543 static bool classof(const SCEV *S) {
544 return isSequentialMinMaxType(S->getSCEVType());
545 }
546 static bool classof(const SCEVUse *U) { return classof(U->getPointer()); }
547};
548
549/// This class represents a sequential/in-order unsigned minimum selection.
550class SCEVSequentialUMinExpr : public SCEVSequentialMinMaxExpr {
551 friend class ScalarEvolution;
552
553 SCEVSequentialUMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O,
554 size_t N)
556
557public:
558 /// Methods for support type inquiry through isa, cast, and dyn_cast:
559 static bool classof(const SCEV *S) {
560 return S->getSCEVType() == scSequentialUMinExpr;
561 }
562};
563
564/// This means that we are dealing with an entirely unknown SCEV
565/// value, and only represent it as its LLVM Value. This is the
566/// "bottom" value for the analysis.
567class LLVM_ABI SCEVUnknown final : public SCEV, private CallbackVH {
568 friend class ScalarEvolution;
569
570 /// The parent ScalarEvolution value. This is used to update the
571 /// parent's maps when the value associated with a SCEVUnknown is
572 /// deleted or RAUW'd.
573 ScalarEvolution *SE;
574
575 /// The next pointer in the linked list of all SCEVUnknown
576 /// instances owned by a ScalarEvolution.
577 SCEVUnknown *Next;
578
579 SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V, ScalarEvolution *se,
580 SCEVUnknown *next)
581 : SCEV(ID, scUnknown, 1, V->getType()), CallbackVH(V), SE(se),
582 Next(next) {}
583
584 // Implement CallbackVH.
585 void deleted() override;
586 void allUsesReplacedWith(Value *New) override;
587
588public:
589 Value *getValue() const { return getValPtr(); }
590
591 /// Methods for support type inquiry through isa, cast, and dyn_cast:
592 static bool classof(const SCEV *S) { return S->getSCEVType() == scUnknown; }
593};
594
595/// This class defines a simple visitor class that may be used for
596/// various SCEV analysis purposes.
597template <typename SC, typename RetVal = void> struct SCEVVisitor {
598 RetVal visit(const SCEV *S) {
599 switch (S->getSCEVType()) {
600 case scConstant:
601 return ((SC *)this)->visitConstant((const SCEVConstant *)S);
602 case scVScale:
603 return ((SC *)this)->visitVScale((const SCEVVScale *)S);
604 case scPtrToAddr:
605 return ((SC *)this)->visitPtrToAddrExpr((const SCEVPtrToAddrExpr *)S);
606 case scTruncate:
607 return ((SC *)this)->visitTruncateExpr((const SCEVTruncateExpr *)S);
608 case scZeroExtend:
609 return ((SC *)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr *)S);
610 case scSignExtend:
611 return ((SC *)this)->visitSignExtendExpr((const SCEVSignExtendExpr *)S);
612 case scAddExpr:
613 return ((SC *)this)->visitAddExpr((const SCEVAddExpr *)S);
614 case scMulExpr:
615 return ((SC *)this)->visitMulExpr((const SCEVMulExpr *)S);
616 case scUDivExpr:
617 return ((SC *)this)->visitUDivExpr((const SCEVUDivExpr *)S);
618 case scAddRecExpr:
619 return ((SC *)this)->visitAddRecExpr((const SCEVAddRecExpr *)S);
620 case scSMaxExpr:
621 return ((SC *)this)->visitSMaxExpr((const SCEVSMaxExpr *)S);
622 case scUMaxExpr:
623 return ((SC *)this)->visitUMaxExpr((const SCEVUMaxExpr *)S);
624 case scSMinExpr:
625 return ((SC *)this)->visitSMinExpr((const SCEVSMinExpr *)S);
626 case scUMinExpr:
627 return ((SC *)this)->visitUMinExpr((const SCEVUMinExpr *)S);
629 return ((SC *)this)
630 ->visitSequentialUMinExpr((const SCEVSequentialUMinExpr *)S);
631 case scUnknown:
632 return ((SC *)this)->visitUnknown((const SCEVUnknown *)S);
634 return ((SC *)this)->visitCouldNotCompute((const SCEVCouldNotCompute *)S);
635 }
636 llvm_unreachable("Unknown SCEV kind!");
637 }
638
640 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
641 }
642};
643
644/// A visitor class for SCEVUse.
645template <typename SC, typename RetVal = void> struct SCEVUseVisitor {
646 RetVal visit(SCEVUse S) {
647 switch (S->getSCEVType()) {
648 case scConstant:
649 return ((SC *)this)
650 ->visitConstant(cast<SCEVUseT<const SCEVConstant *>>(S));
651 case scVScale:
652 return ((SC *)this)->visitVScale(cast<SCEVUseT<const SCEVVScale *>>(S));
653 case scPtrToAddr:
654 return ((SC *)this)
655 ->visitPtrToAddrExpr(cast<SCEVUseT<const SCEVPtrToAddrExpr *>>(S));
656 case scTruncate:
657 return ((SC *)this)
658 ->visitTruncateExpr(cast<SCEVUseT<const SCEVTruncateExpr *>>(S));
659 case scZeroExtend:
660 return ((SC *)this)
661 ->visitZeroExtendExpr(cast<SCEVUseT<const SCEVZeroExtendExpr *>>(S));
662 case scSignExtend:
663 return ((SC *)this)
664 ->visitSignExtendExpr(cast<SCEVUseT<const SCEVSignExtendExpr *>>(S));
665 case scAddExpr:
666 return ((SC *)this)->visitAddExpr(cast<SCEVUseT<const SCEVAddExpr *>>(S));
667 case scMulExpr:
668 return ((SC *)this)->visitMulExpr(cast<SCEVUseT<const SCEVMulExpr *>>(S));
669 case scUDivExpr:
670 return ((SC *)this)
671 ->visitUDivExpr(cast<SCEVUseT<const SCEVUDivExpr *>>(S));
672 case scAddRecExpr:
673 return ((SC *)this)
674 ->visitAddRecExpr(cast<SCEVUseT<const SCEVAddRecExpr *>>(S));
675 case scSMaxExpr:
676 return ((SC *)this)
677 ->visitSMaxExpr(cast<SCEVUseT<const SCEVSMaxExpr *>>(S));
678 case scUMaxExpr:
679 return ((SC *)this)
680 ->visitUMaxExpr(cast<SCEVUseT<const SCEVUMaxExpr *>>(S));
681 case scSMinExpr:
682 return ((SC *)this)
683 ->visitSMinExpr(cast<SCEVUseT<const SCEVSMinExpr *>>(S));
684 case scUMinExpr:
685 return ((SC *)this)
686 ->visitUMinExpr(cast<SCEVUseT<const SCEVUMinExpr *>>(S));
688 return ((SC *)this)
689 ->visitSequentialUMinExpr(
691 case scUnknown:
692 return ((SC *)this)->visitUnknown(cast<SCEVUseT<const SCEVUnknown *>>(S));
694 return ((SC *)this)
695 ->visitCouldNotCompute(
697 }
698 llvm_unreachable("Unknown SCEV kind!");
699 }
700
702 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
703 }
704};
705
706/// Visit all nodes in the expression tree using worklist traversal.
707///
708/// Visitor implements:
709/// // return true to follow this node.
710/// bool follow(const SCEV *S);
711/// // return true to terminate the search.
712/// bool isDone();
713template <typename SV> class SCEVTraversal {
714 SV &Visitor;
717
718 void push(const SCEV *S) {
719 if (Visited.insert(S).second && Visitor.follow(S))
720 Worklist.push_back(S);
721 }
722
723public:
724 SCEVTraversal(SV &V) : Visitor(V) {}
725
726 void visitAll(const SCEV *Root) {
727 push(Root);
728 while (!Worklist.empty() && !Visitor.isDone()) {
729 const SCEV *S = Worklist.pop_back_val();
730
731 switch (S->getSCEVType()) {
732 case scConstant:
733 case scVScale:
734 case scUnknown:
735 continue;
736 case scPtrToAddr:
737 case scTruncate:
738 case scZeroExtend:
739 case scSignExtend:
740 case scAddExpr:
741 case scMulExpr:
742 case scUDivExpr:
743 case scSMaxExpr:
744 case scUMaxExpr:
745 case scSMinExpr:
746 case scUMinExpr:
748 case scAddRecExpr:
749 for (const SCEV *Op : S->operands()) {
750 push(Op);
751 if (Visitor.isDone())
752 break;
753 }
754 continue;
756 llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
757 }
758 llvm_unreachable("Unknown SCEV kind!");
759 }
760 }
761};
762
763/// Use SCEVTraversal to visit all nodes in the given expression tree.
764template <typename SV> void visitAll(const SCEV *Root, SV &Visitor) {
765 SCEVTraversal<SV> T(Visitor);
766 T.visitAll(Root);
767}
768
769/// Return true if any node in \p Root satisfies the predicate \p Pred.
770template <typename PredTy>
771bool SCEVExprContains(const SCEV *Root, PredTy Pred) {
772 struct FindClosure {
773 bool Found = false;
774 PredTy Pred;
775
776 FindClosure(PredTy Pred) : Pred(Pred) {}
777
778 bool follow(const SCEV *S) {
779 if (!Pred(S))
780 return true;
781
782 Found = true;
783 return false;
784 }
785
786 bool isDone() const { return Found; }
787 };
788
789 FindClosure FC(Pred);
790 visitAll(Root, FC);
791 return FC.Found;
792}
793
794/// This visitor recursively visits a SCEV expression and re-writes it.
795/// The result from each visit is cached, so it will return the same
796/// SCEV for the same input.
797template <typename SC>
798class SCEVRewriteVisitor : public SCEVVisitor<SC, const SCEV *> {
799protected:
801 // Memoize the result of each visit so that we only compute once for
802 // the same input SCEV. This is to avoid redundant computations when
803 // a SCEV is referenced by multiple SCEVs. Without memoization, this
804 // visit algorithm would have exponential time complexity in the worst
805 // case, causing the compiler to hang on certain tests.
807
808public:
810
811 const SCEV *visit(const SCEV *S) {
812 auto It = RewriteResults.find(S);
813 if (It != RewriteResults.end())
814 return It->second;
815 auto *Visited = SCEVVisitor<SC, const SCEV *>::visit(S);
816 auto Result = RewriteResults.try_emplace(S, Visited);
817 assert(Result.second && "Should insert a new entry");
818 return Result.first->second;
819 }
820
822
823 const SCEV *visitVScale(const SCEVVScale *VScale) { return VScale; }
824
826 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
827 return Operand == Expr->getOperand() ? Expr : SE.getPtrToAddrExpr(Operand);
828 }
829
831 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
832 return Operand == Expr->getOperand()
833 ? Expr
834 : SE.getTruncateExpr(Operand, Expr->getType());
835 }
836
838 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
839 return Operand == Expr->getOperand()
840 ? Expr
841 : SE.getZeroExtendExpr(Operand, Expr->getType());
842 }
843
845 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
846 return Operand == Expr->getOperand()
847 ? Expr
848 : SE.getSignExtendExpr(Operand, Expr->getType());
849 }
850
851 const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
853 bool Changed = false;
854 for (const SCEV *Op : Expr->operands()) {
855 Operands.push_back(((SC *)this)->visit(Op));
856 Changed |= Op != Operands.back();
857 }
858 return !Changed ? Expr : SE.getAddExpr(Operands);
859 }
860
861 const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
863 bool Changed = false;
864 for (const SCEV *Op : Expr->operands()) {
865 Operands.push_back(((SC *)this)->visit(Op));
866 Changed |= Op != Operands.back();
867 }
868 return !Changed ? Expr : SE.getMulExpr(Operands);
869 }
870
871 const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
872 auto *LHS = ((SC *)this)->visit(Expr->getLHS());
873 auto *RHS = ((SC *)this)->visit(Expr->getRHS());
874 bool Changed = LHS != Expr->getLHS() || RHS != Expr->getRHS();
875 return !Changed ? Expr : SE.getUDivExpr(LHS, RHS);
876 }
877
878 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
880 bool Changed = false;
881 for (const SCEV *Op : Expr->operands()) {
882 Operands.push_back(((SC *)this)->visit(Op));
883 Changed |= Op != Operands.back();
884 }
885 return !Changed ? Expr
886 : SE.getAddRecExpr(Operands, Expr->getLoop(),
887 Expr->getNoWrapFlags());
888 }
889
890 const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
892 bool Changed = false;
893 for (const SCEV *Op : Expr->operands()) {
894 Operands.push_back(((SC *)this)->visit(Op));
895 Changed |= Op != Operands.back();
896 }
897 return !Changed ? Expr : SE.getSMaxExpr(Operands);
898 }
899
900 const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
902 bool Changed = false;
903 for (const SCEV *Op : Expr->operands()) {
904 Operands.push_back(((SC *)this)->visit(Op));
905 Changed |= Op != Operands.back();
906 }
907 return !Changed ? Expr : SE.getUMaxExpr(Operands);
908 }
909
910 const SCEV *visitSMinExpr(const SCEVSMinExpr *Expr) {
912 bool Changed = false;
913 for (const SCEV *Op : Expr->operands()) {
914 Operands.push_back(((SC *)this)->visit(Op));
915 Changed |= Op != Operands.back();
916 }
917 return !Changed ? Expr : SE.getSMinExpr(Operands);
918 }
919
920 const SCEV *visitUMinExpr(const SCEVUMinExpr *Expr) {
922 bool Changed = false;
923 for (const SCEV *Op : Expr->operands()) {
924 Operands.push_back(((SC *)this)->visit(Op));
925 Changed |= Op != Operands.back();
926 }
927 return !Changed ? Expr : SE.getUMinExpr(Operands);
928 }
929
932 bool Changed = false;
933 for (const SCEV *Op : Expr->operands()) {
934 Operands.push_back(((SC *)this)->visit(Op));
935 Changed |= Op != Operands.back();
936 }
937 return !Changed ? Expr : SE.getUMinExpr(Operands, /*Sequential=*/true);
938 }
939
940 const SCEV *visitUnknown(const SCEVUnknown *Expr) { return Expr; }
941
943 return Expr;
944 }
945};
946
949
950/// The SCEVParameterRewriter takes a scalar evolution expression and updates
951/// the SCEVUnknown components following the Map (Value -> SCEV).
952class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> {
953public:
954 static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
955 ValueToSCEVMapTy &Map) {
957 return Rewriter.visit(Scev);
958 }
959
962
963 const SCEV *visitUnknown(const SCEVUnknown *Expr) {
964 auto I = Map.find(Expr->getValue());
965 if (I == Map.end())
966 return Expr;
967 return I->second;
968 }
969
970private:
971 ValueToSCEVMapTy &Map;
972};
973
975
976/// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies
977/// the Map (Loop -> SCEV) to all AddRecExprs.
979 : public SCEVRewriteVisitor<SCEVLoopAddRecRewriter> {
980public:
983
984 static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
987 return Rewriter.visit(Scev);
988 }
989
990 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
992 for (SCEVUse Op : Expr->operands())
993 Operands.push_back(visit(Op));
994
995 const Loop *L = Expr->getLoop();
996 auto It = Map.find(L);
997 if (It == Map.end())
998 return SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
999
1000 return SCEVAddRecExpr::evaluateAtIteration(Operands, It->second, SE);
1001 }
1002
1003private:
1004 LoopToScevMapT &Map;
1005};
1006
1007template <typename SCEVPtrT>
1009 : Base(S, 0) {
1010 if (any(Flags)) {
1012 "use flags require an expression that can carry no-wrap flags");
1013 // Drop flags already present on S.
1014 Flags &= ~cast<SCEVNAryExpr>(S)->getNoWrapFlags();
1015 }
1016 Base::setInt(static_cast<unsigned>(Flags) >> 1);
1017}
1018
1019template <typename SCEVPtrT>
1020inline SCEVNoWrapFlags
1023 if (auto *NAry = dyn_cast<SCEVNAryExpr>(Base::getPointer()))
1024 Flags = NAry->getNoWrapFlags();
1025 return (Flags | getUseNoWrapFlags()) & Mask;
1026}
1027
1028} // end namespace llvm
1029
1030#endif // LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:215
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
#define op(i)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
SI Fold Operands
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Virtual Register Rewriter
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
CallbackVH(const CallbackVH &)=default
This is the shared class of boolean and integer constants.
Definition Constants.h:87
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This class represents a range of values.
This is an important base class in LLVM.
Definition Constant.h:43
This class describes a reference to an interned FoldingSetNodeID, which can be a useful to store node...
Definition FoldingSet.h:123
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
This node represents an addition of some number of SCEVs.
static bool classof(const SCEVUse *U)
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This node represents a polynomial recurrence on the trip count of the specified loop.
LLVM_ABI SCEVUse getExitValue(ScalarEvolution &SE) const
Return the value of this recurrences when its loop exits, i.e.
LLVM_ABI const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
void setNoWrapFlags(NoWrapFlags Flags)
Set flags for a recurrence without clearing any previously set flags.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
bool isQuadratic() const
Return true if this represents an expression A + B*x + C*x^2 where A, B and C are loop invariant valu...
LLVM_ABI const SCEV * getNumIterationsInRange(const ConstantRange &Range, ScalarEvolution &SE) const
Return the number of iterations of this loop that produce values in the specified constant range.
LLVM_ABI const SCEVAddRecExpr * getPostIncExpr(ScalarEvolution &SE) const
Return an expression representing the value of this expression one iteration of the loop ahead.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
SCEVUse getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
ArrayRef< SCEVUse > operands() const
SCEVUse getOperand(unsigned i) const
LLVM_ABI SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, SCEVUse op, Type *ty)
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
SCEVCommutativeExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T, const SCEVUse *O, size_t N, Type *Ty)
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
void setNoWrapFlags(NoWrapFlags Flags)
Set flags for a non-recurrence without clearing previously set flags.
This class represents a constant integer value.
ConstantInt * getValue() const
const APInt & getAPInt() const
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
LLVM_ABI SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, SCEVUse op, Type *ty)
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
static const SCEV * rewrite(const SCEV *Scev, LoopToScevMapT &Map, ScalarEvolution &SE)
const SCEV * visitAddRecExpr(const SCEVAddRecExpr *Expr)
SCEVLoopAddRecRewriter(ScalarEvolution &SE, LoopToScevMapT &M)
static enum SCEVTypes negate(enum SCEVTypes T)
SCEVMinMaxExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T, const SCEVUse *O, size_t N)
Note: Constructing subclasses via this constructor is allowed.
static bool classof(const SCEV *S)
This node represents multiplication of some number of SCEVs.
static bool classof(const SCEVUse *U)
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
ArrayRef< SCEVUse > operands() const
SCEVNAryExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T, const SCEVUse *O, size_t N, Type *Ty)
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask=NoWrapMask) const
SCEVUse getOperand(unsigned i) const
static bool classof(const SCEVUse *U)
const SCEV * visitUnknown(const SCEVUnknown *Expr)
static const SCEV * rewrite(const SCEV *Scev, ScalarEvolution &SE, ValueToSCEVMapTy &Map)
SCEVParameterRewriter(ScalarEvolution &SE, ValueToSCEVMapTy &M)
This class represents a cast from a pointer to a pointer-sized integer value, without capturing the p...
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
const SCEV * visitPtrToAddrExpr(const SCEVPtrToAddrExpr *Expr)
const SCEV * visitSignExtendExpr(const SCEVSignExtendExpr *Expr)
const SCEV * visit(const SCEV *S)
const SCEV * visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr)
const SCEV * visitUnknown(const SCEVUnknown *Expr)
const SCEV * visitSMinExpr(const SCEVSMinExpr *Expr)
const SCEV * visitSequentialUMinExpr(const SCEVSequentialUMinExpr *Expr)
const SCEV * visitAddExpr(const SCEVAddExpr *Expr)
const SCEV * visitUMinExpr(const SCEVUMinExpr *Expr)
const SCEV * visitMulExpr(const SCEVMulExpr *Expr)
SmallDenseMap< const SCEV *, const SCEV * > RewriteResults
const SCEV * visitTruncateExpr(const SCEVTruncateExpr *Expr)
const SCEV * visitUMaxExpr(const SCEVUMaxExpr *Expr)
const SCEV * visitSMaxExpr(const SCEVSMaxExpr *Expr)
const SCEV * visitUDivExpr(const SCEVUDivExpr *Expr)
const SCEV * visitCouldNotCompute(const SCEVCouldNotCompute *Expr)
const SCEV * visitVScale(const SCEVVScale *VScale)
const SCEV * visitAddRecExpr(const SCEVAddRecExpr *Expr)
const SCEV * visitConstant(const SCEVConstant *Constant)
This class represents a signed maximum selection.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This class represents a signed minimum selection.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEVUse *U)
static SCEVTypes getEquivalentNonSequentialSCEVType(SCEVTypes Ty)
SCEVSequentialMinMaxExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T, const SCEVUse *O, size_t N)
Note: Constructing subclasses via this constructor is allowed.
This class represents a sequential/in-order unsigned minimum selection.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This class represents a sign extension of a small integer value to a larger integer value.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
Visit all nodes in the expression tree using worklist traversal.
void visitAll(const SCEV *Root)
This class represents a truncation of an integer value to a smaller integer value.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This class represents a binary unsigned division operation.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
ArrayRef< SCEVUse > operands() const
SCEVUse getOperand(unsigned i) const
This class represents an unsigned maximum selection.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This class represents an unsigned minimum selection.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This class represents the value of vscale, as used when defining the length of a scalable vector or r...
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This class represents a zero extension of a small integer value to a larger integer value.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
This class represents an analyzed expression in the program.
static constexpr auto NoWrapMask
SCEVNoWrapFlags NoWrapFlags
SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, unsigned short ExpressionSize, Type *Ty)
static constexpr auto FlagNUW
static constexpr auto FlagAnyWrap
Type *const Ty
Immutable type of the SCEV.
static constexpr auto FlagNSW
LLVM_ABI ArrayRef< SCEVUse > operands() const
Return operands of this SCEV expression.
Type * getType() const
Return the LLVM type of this SCEV expression.
SCEVTypes getSCEVType() const
unsigned short SubclassData
This field is initialized to zero and may be used in subclasses to store miscellaneous information.
static constexpr auto FlagNW
The main scalar evolution driver.
LLVM_ABI const SCEV * getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags, SCEV::NoWrapFlags OnFlags)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Value * getValPtr() const
LLVM Value Representation.
Definition Value.h:75
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
void visitAll(const SCEV *Root, SV &Visitor)
Use SCEVTraversal to visit all nodes in the given expression tree.
DenseMap< const Value *, const SCEV * > ValueToSCEVMapTy
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
DenseMap< const Loop *, const SCEV * > LoopToScevMapT
SCEVNoWrapFlags
NoWrapFlags are bitfield indices into SCEV's SubclassData.
unsigned short computeExpressionSize(ArrayRef< SCEVUse > Args)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
DenseMap< const Value *, Value * > ValueToValueMap
SCEVUseT< const SCEV * > SCEVUse
bool SCEVExprContains(const SCEV *Root, PredTy Pred)
Return true if any node in Root satisfies the predicate Pred.
#define N
An object of this class is returned by queries that could not be answered.
SCEVNoWrapFlags getUseNoWrapFlags() const
Return only the use-specific no-wrap flags (NUW/NSW) without the underlying SCEV's flags.
SCEVNoWrapFlags getNoWrapFlags(SCEVNoWrapFlags Mask=SCEVNoWrapFlags::NoWrapMask) const
Return the no-wrap flags for this SCEVUse, which is the union of the use-specific flags and the under...
PointerIntPair< SCEVPtrT, 2 > Base
A visitor class for SCEVUse.
RetVal visitCouldNotCompute(SCEVUseT< const SCEVCouldNotCompute * > S)
This class defines a simple visitor class that may be used for various SCEV analysis purposes.
RetVal visit(const SCEV *S)
RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S)