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
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.
386 const SCEV *It,
387 ScalarEvolution &SE);
388
389 /// Return the number of iterations of this loop that produce
390 /// values in the specified constant range. Another way of
391 /// looking at this is that it returns the first iteration number
392 /// where the value is not in the condition, thus computing the
393 /// exit count. If the iteration count can't be computed, an
394 /// instance of SCEVCouldNotCompute is returned.
396 ScalarEvolution &SE) const;
397
398 /// Return an expression representing the value of this expression
399 /// one iteration of the loop ahead.
401
402 /// Methods for support type inquiry through isa, cast, and dyn_cast:
403 static bool classof(const SCEV *S) {
404 return S->getSCEVType() == scAddRecExpr;
405 }
406};
407
408/// This node is the base class min/max selections.
410 friend class ScalarEvolution;
411
412 static bool isMinMaxType(enum SCEVTypes T) {
413 return T == scSMaxExpr || T == scUMaxExpr || T == scSMinExpr ||
414 T == scUMinExpr;
415 }
416
417protected:
418 /// Note: Constructing subclasses via this constructor is allowed
420 const SCEVUse *O, size_t N)
421 : SCEVCommutativeExpr(ID, T, O, N, O[0]->getType()) {
422 assert(isMinMaxType(T));
423 // Min and max never overflow
425 }
426
427public:
428 static bool classof(const SCEV *S) { return isMinMaxType(S->getSCEVType()); }
429
430 static enum SCEVTypes negate(enum SCEVTypes T) {
431 switch (T) {
432 case scSMaxExpr:
433 return scSMinExpr;
434 case scSMinExpr:
435 return scSMaxExpr;
436 case scUMaxExpr:
437 return scUMinExpr;
438 case scUMinExpr:
439 return scUMaxExpr;
440 default:
441 llvm_unreachable("Not a min or max SCEV type!");
442 }
443 }
444};
445
446/// This class represents a signed maximum selection.
447class SCEVSMaxExpr : public SCEVMinMaxExpr {
448 friend class ScalarEvolution;
449
450 SCEVSMaxExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
451 : SCEVMinMaxExpr(ID, scSMaxExpr, O, N) {}
452
453public:
454 /// Methods for support type inquiry through isa, cast, and dyn_cast:
455 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMaxExpr; }
456};
457
458/// This class represents an unsigned maximum selection.
459class SCEVUMaxExpr : public SCEVMinMaxExpr {
460 friend class ScalarEvolution;
461
462 SCEVUMaxExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
463 : SCEVMinMaxExpr(ID, scUMaxExpr, O, N) {}
464
465public:
466 /// Methods for support type inquiry through isa, cast, and dyn_cast:
467 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMaxExpr; }
468};
469
470/// This class represents a signed minimum selection.
471class SCEVSMinExpr : public SCEVMinMaxExpr {
472 friend class ScalarEvolution;
473
474 SCEVSMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
475 : SCEVMinMaxExpr(ID, scSMinExpr, O, N) {}
476
477public:
478 /// Methods for support type inquiry through isa, cast, and dyn_cast:
479 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMinExpr; }
480};
481
482/// This class represents an unsigned minimum selection.
483class SCEVUMinExpr : public SCEVMinMaxExpr {
484 friend class ScalarEvolution;
485
486 SCEVUMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
487 : SCEVMinMaxExpr(ID, scUMinExpr, O, N) {}
488
489public:
490 /// Methods for support type inquiry through isa, cast, and dyn_cast:
491 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMinExpr; }
492};
493
494/// This node is the base class for sequential/in-order min/max selections.
495/// Note that their fundamental difference from SCEVMinMaxExpr's is that they
496/// are early-returning upon reaching saturation point.
497/// I.e. given `0 umin_seq poison`, the result will be `0`, while the result of
498/// `0 umin poison` is `poison`. When returning early, later expressions are not
499/// executed, so `0 umin_seq (%x u/ 0)` does not result in undefined behavior.
501 friend class ScalarEvolution;
502
503 static bool isSequentialMinMaxType(enum SCEVTypes T) {
504 return T == scSequentialUMinExpr;
505 }
506
507 /// Set flags for a non-recurrence without clearing previously set flags.
508 void setNoWrapFlags(NoWrapFlags Flags) {
509 SubclassData |= static_cast<unsigned short>(Flags);
510 }
511
512protected:
513 /// Note: Constructing subclasses via this constructor is allowed
515 const SCEVUse *O, size_t N)
516 : SCEVNAryExpr(ID, T, O, N, O[0]->getType()) {
517 assert(isSequentialMinMaxType(T));
518 // Min and max never overflow
519 setNoWrapFlags(FlagNUW | FlagNSW);
520 }
521
522public:
524 assert(isSequentialMinMaxType(Ty));
525 switch (Ty) {
527 return scUMinExpr;
528 default:
529 llvm_unreachable("Not a sequential min/max type.");
530 }
531 }
532
536
537 static bool classof(const SCEV *S) {
538 return isSequentialMinMaxType(S->getSCEVType());
539 }
540 static bool classof(const SCEVUse *U) { return classof(U->getPointer()); }
541};
542
543/// This class represents a sequential/in-order unsigned minimum selection.
544class SCEVSequentialUMinExpr : public SCEVSequentialMinMaxExpr {
545 friend class ScalarEvolution;
546
547 SCEVSequentialUMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O,
548 size_t N)
550
551public:
552 /// Methods for support type inquiry through isa, cast, and dyn_cast:
553 static bool classof(const SCEV *S) {
554 return S->getSCEVType() == scSequentialUMinExpr;
555 }
556};
557
558/// This means that we are dealing with an entirely unknown SCEV
559/// value, and only represent it as its LLVM Value. This is the
560/// "bottom" value for the analysis.
561class LLVM_ABI SCEVUnknown final : public SCEV, private CallbackVH {
562 friend class ScalarEvolution;
563
564 /// The parent ScalarEvolution value. This is used to update the
565 /// parent's maps when the value associated with a SCEVUnknown is
566 /// deleted or RAUW'd.
567 ScalarEvolution *SE;
568
569 /// The next pointer in the linked list of all SCEVUnknown
570 /// instances owned by a ScalarEvolution.
571 SCEVUnknown *Next;
572
573 SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V, ScalarEvolution *se,
574 SCEVUnknown *next)
575 : SCEV(ID, scUnknown, 1, V->getType()), CallbackVH(V), SE(se),
576 Next(next) {}
577
578 // Implement CallbackVH.
579 void deleted() override;
580 void allUsesReplacedWith(Value *New) override;
581
582public:
583 Value *getValue() const { return getValPtr(); }
584
585 /// Methods for support type inquiry through isa, cast, and dyn_cast:
586 static bool classof(const SCEV *S) { return S->getSCEVType() == scUnknown; }
587};
588
589/// This class defines a simple visitor class that may be used for
590/// various SCEV analysis purposes.
591template <typename SC, typename RetVal = void> struct SCEVVisitor {
592 RetVal visit(const SCEV *S) {
593 switch (S->getSCEVType()) {
594 case scConstant:
595 return ((SC *)this)->visitConstant((const SCEVConstant *)S);
596 case scVScale:
597 return ((SC *)this)->visitVScale((const SCEVVScale *)S);
598 case scPtrToAddr:
599 return ((SC *)this)->visitPtrToAddrExpr((const SCEVPtrToAddrExpr *)S);
600 case scTruncate:
601 return ((SC *)this)->visitTruncateExpr((const SCEVTruncateExpr *)S);
602 case scZeroExtend:
603 return ((SC *)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr *)S);
604 case scSignExtend:
605 return ((SC *)this)->visitSignExtendExpr((const SCEVSignExtendExpr *)S);
606 case scAddExpr:
607 return ((SC *)this)->visitAddExpr((const SCEVAddExpr *)S);
608 case scMulExpr:
609 return ((SC *)this)->visitMulExpr((const SCEVMulExpr *)S);
610 case scUDivExpr:
611 return ((SC *)this)->visitUDivExpr((const SCEVUDivExpr *)S);
612 case scAddRecExpr:
613 return ((SC *)this)->visitAddRecExpr((const SCEVAddRecExpr *)S);
614 case scSMaxExpr:
615 return ((SC *)this)->visitSMaxExpr((const SCEVSMaxExpr *)S);
616 case scUMaxExpr:
617 return ((SC *)this)->visitUMaxExpr((const SCEVUMaxExpr *)S);
618 case scSMinExpr:
619 return ((SC *)this)->visitSMinExpr((const SCEVSMinExpr *)S);
620 case scUMinExpr:
621 return ((SC *)this)->visitUMinExpr((const SCEVUMinExpr *)S);
623 return ((SC *)this)
624 ->visitSequentialUMinExpr((const SCEVSequentialUMinExpr *)S);
625 case scUnknown:
626 return ((SC *)this)->visitUnknown((const SCEVUnknown *)S);
628 return ((SC *)this)->visitCouldNotCompute((const SCEVCouldNotCompute *)S);
629 }
630 llvm_unreachable("Unknown SCEV kind!");
631 }
632
634 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
635 }
636};
637
638/// A visitor class for SCEVUse.
639template <typename SC, typename RetVal = void> struct SCEVUseVisitor {
640 RetVal visit(SCEVUse S) {
641 switch (S->getSCEVType()) {
642 case scConstant:
643 return ((SC *)this)
644 ->visitConstant(cast<SCEVUseT<const SCEVConstant *>>(S));
645 case scVScale:
646 return ((SC *)this)->visitVScale(cast<SCEVUseT<const SCEVVScale *>>(S));
647 case scPtrToAddr:
648 return ((SC *)this)
649 ->visitPtrToAddrExpr(cast<SCEVUseT<const SCEVPtrToAddrExpr *>>(S));
650 case scTruncate:
651 return ((SC *)this)
652 ->visitTruncateExpr(cast<SCEVUseT<const SCEVTruncateExpr *>>(S));
653 case scZeroExtend:
654 return ((SC *)this)
655 ->visitZeroExtendExpr(cast<SCEVUseT<const SCEVZeroExtendExpr *>>(S));
656 case scSignExtend:
657 return ((SC *)this)
658 ->visitSignExtendExpr(cast<SCEVUseT<const SCEVSignExtendExpr *>>(S));
659 case scAddExpr:
660 return ((SC *)this)->visitAddExpr(cast<SCEVUseT<const SCEVAddExpr *>>(S));
661 case scMulExpr:
662 return ((SC *)this)->visitMulExpr(cast<SCEVUseT<const SCEVMulExpr *>>(S));
663 case scUDivExpr:
664 return ((SC *)this)
665 ->visitUDivExpr(cast<SCEVUseT<const SCEVUDivExpr *>>(S));
666 case scAddRecExpr:
667 return ((SC *)this)
668 ->visitAddRecExpr(cast<SCEVUseT<const SCEVAddRecExpr *>>(S));
669 case scSMaxExpr:
670 return ((SC *)this)
671 ->visitSMaxExpr(cast<SCEVUseT<const SCEVSMaxExpr *>>(S));
672 case scUMaxExpr:
673 return ((SC *)this)
674 ->visitUMaxExpr(cast<SCEVUseT<const SCEVUMaxExpr *>>(S));
675 case scSMinExpr:
676 return ((SC *)this)
677 ->visitSMinExpr(cast<SCEVUseT<const SCEVSMinExpr *>>(S));
678 case scUMinExpr:
679 return ((SC *)this)
680 ->visitUMinExpr(cast<SCEVUseT<const SCEVUMinExpr *>>(S));
682 return ((SC *)this)
683 ->visitSequentialUMinExpr(
685 case scUnknown:
686 return ((SC *)this)->visitUnknown(cast<SCEVUseT<const SCEVUnknown *>>(S));
688 return ((SC *)this)
689 ->visitCouldNotCompute(
691 }
692 llvm_unreachable("Unknown SCEV kind!");
693 }
694
696 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
697 }
698};
699
700/// Visit all nodes in the expression tree using worklist traversal.
701///
702/// Visitor implements:
703/// // return true to follow this node.
704/// bool follow(const SCEV *S);
705/// // return true to terminate the search.
706/// bool isDone();
707template <typename SV> class SCEVTraversal {
708 SV &Visitor;
711
712 void push(const SCEV *S) {
713 if (Visited.insert(S).second && Visitor.follow(S))
714 Worklist.push_back(S);
715 }
716
717public:
718 SCEVTraversal(SV &V) : Visitor(V) {}
719
720 void visitAll(const SCEV *Root) {
721 push(Root);
722 while (!Worklist.empty() && !Visitor.isDone()) {
723 const SCEV *S = Worklist.pop_back_val();
724
725 switch (S->getSCEVType()) {
726 case scConstant:
727 case scVScale:
728 case scUnknown:
729 continue;
730 case scPtrToAddr:
731 case scTruncate:
732 case scZeroExtend:
733 case scSignExtend:
734 case scAddExpr:
735 case scMulExpr:
736 case scUDivExpr:
737 case scSMaxExpr:
738 case scUMaxExpr:
739 case scSMinExpr:
740 case scUMinExpr:
742 case scAddRecExpr:
743 for (const SCEV *Op : S->operands()) {
744 push(Op);
745 if (Visitor.isDone())
746 break;
747 }
748 continue;
750 llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
751 }
752 llvm_unreachable("Unknown SCEV kind!");
753 }
754 }
755};
756
757/// Use SCEVTraversal to visit all nodes in the given expression tree.
758template <typename SV> void visitAll(const SCEV *Root, SV &Visitor) {
759 SCEVTraversal<SV> T(Visitor);
760 T.visitAll(Root);
761}
762
763/// Return true if any node in \p Root satisfies the predicate \p Pred.
764template <typename PredTy>
765bool SCEVExprContains(const SCEV *Root, PredTy Pred) {
766 struct FindClosure {
767 bool Found = false;
768 PredTy Pred;
769
770 FindClosure(PredTy Pred) : Pred(Pred) {}
771
772 bool follow(const SCEV *S) {
773 if (!Pred(S))
774 return true;
775
776 Found = true;
777 return false;
778 }
779
780 bool isDone() const { return Found; }
781 };
782
783 FindClosure FC(Pred);
784 visitAll(Root, FC);
785 return FC.Found;
786}
787
788/// This visitor recursively visits a SCEV expression and re-writes it.
789/// The result from each visit is cached, so it will return the same
790/// SCEV for the same input.
791template <typename SC>
792class SCEVRewriteVisitor : public SCEVVisitor<SC, const SCEV *> {
793protected:
795 // Memoize the result of each visit so that we only compute once for
796 // the same input SCEV. This is to avoid redundant computations when
797 // a SCEV is referenced by multiple SCEVs. Without memoization, this
798 // visit algorithm would have exponential time complexity in the worst
799 // case, causing the compiler to hang on certain tests.
801
802public:
804
805 const SCEV *visit(const SCEV *S) {
806 auto It = RewriteResults.find(S);
807 if (It != RewriteResults.end())
808 return It->second;
809 auto *Visited = SCEVVisitor<SC, const SCEV *>::visit(S);
810 auto Result = RewriteResults.try_emplace(S, Visited);
811 assert(Result.second && "Should insert a new entry");
812 return Result.first->second;
813 }
814
816
817 const SCEV *visitVScale(const SCEVVScale *VScale) { return VScale; }
818
820 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
821 return Operand == Expr->getOperand() ? Expr : SE.getPtrToAddrExpr(Operand);
822 }
823
825 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
826 return Operand == Expr->getOperand()
827 ? Expr
828 : SE.getTruncateExpr(Operand, Expr->getType());
829 }
830
832 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
833 return Operand == Expr->getOperand()
834 ? Expr
835 : SE.getZeroExtendExpr(Operand, Expr->getType());
836 }
837
839 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
840 return Operand == Expr->getOperand()
841 ? Expr
842 : SE.getSignExtendExpr(Operand, Expr->getType());
843 }
844
845 const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
847 bool Changed = false;
848 for (const SCEV *Op : Expr->operands()) {
849 Operands.push_back(((SC *)this)->visit(Op));
850 Changed |= Op != Operands.back();
851 }
852 return !Changed ? Expr : SE.getAddExpr(Operands);
853 }
854
855 const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
857 bool Changed = false;
858 for (const SCEV *Op : Expr->operands()) {
859 Operands.push_back(((SC *)this)->visit(Op));
860 Changed |= Op != Operands.back();
861 }
862 return !Changed ? Expr : SE.getMulExpr(Operands);
863 }
864
865 const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
866 auto *LHS = ((SC *)this)->visit(Expr->getLHS());
867 auto *RHS = ((SC *)this)->visit(Expr->getRHS());
868 bool Changed = LHS != Expr->getLHS() || RHS != Expr->getRHS();
869 return !Changed ? Expr : SE.getUDivExpr(LHS, RHS);
870 }
871
872 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
874 bool Changed = false;
875 for (const SCEV *Op : Expr->operands()) {
876 Operands.push_back(((SC *)this)->visit(Op));
877 Changed |= Op != Operands.back();
878 }
879 return !Changed ? Expr
880 : SE.getAddRecExpr(Operands, Expr->getLoop(),
881 Expr->getNoWrapFlags());
882 }
883
884 const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
886 bool Changed = false;
887 for (const SCEV *Op : Expr->operands()) {
888 Operands.push_back(((SC *)this)->visit(Op));
889 Changed |= Op != Operands.back();
890 }
891 return !Changed ? Expr : SE.getSMaxExpr(Operands);
892 }
893
894 const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
896 bool Changed = false;
897 for (const SCEV *Op : Expr->operands()) {
898 Operands.push_back(((SC *)this)->visit(Op));
899 Changed |= Op != Operands.back();
900 }
901 return !Changed ? Expr : SE.getUMaxExpr(Operands);
902 }
903
904 const SCEV *visitSMinExpr(const SCEVSMinExpr *Expr) {
906 bool Changed = false;
907 for (const SCEV *Op : Expr->operands()) {
908 Operands.push_back(((SC *)this)->visit(Op));
909 Changed |= Op != Operands.back();
910 }
911 return !Changed ? Expr : SE.getSMinExpr(Operands);
912 }
913
914 const SCEV *visitUMinExpr(const SCEVUMinExpr *Expr) {
916 bool Changed = false;
917 for (const SCEV *Op : Expr->operands()) {
918 Operands.push_back(((SC *)this)->visit(Op));
919 Changed |= Op != Operands.back();
920 }
921 return !Changed ? Expr : SE.getUMinExpr(Operands);
922 }
923
926 bool Changed = false;
927 for (const SCEV *Op : Expr->operands()) {
928 Operands.push_back(((SC *)this)->visit(Op));
929 Changed |= Op != Operands.back();
930 }
931 return !Changed ? Expr : SE.getUMinExpr(Operands, /*Sequential=*/true);
932 }
933
934 const SCEV *visitUnknown(const SCEVUnknown *Expr) { return Expr; }
935
937 return Expr;
938 }
939};
940
943
944/// The SCEVParameterRewriter takes a scalar evolution expression and updates
945/// the SCEVUnknown components following the Map (Value -> SCEV).
946class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> {
947public:
948 static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
949 ValueToSCEVMapTy &Map) {
951 return Rewriter.visit(Scev);
952 }
953
956
957 const SCEV *visitUnknown(const SCEVUnknown *Expr) {
958 auto I = Map.find(Expr->getValue());
959 if (I == Map.end())
960 return Expr;
961 return I->second;
962 }
963
964private:
965 ValueToSCEVMapTy &Map;
966};
967
969
970/// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies
971/// the Map (Loop -> SCEV) to all AddRecExprs.
973 : public SCEVRewriteVisitor<SCEVLoopAddRecRewriter> {
974public:
977
978 static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
981 return Rewriter.visit(Scev);
982 }
983
984 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
986 for (SCEVUse Op : Expr->operands())
987 Operands.push_back(visit(Op));
988
989 const Loop *L = Expr->getLoop();
990 auto It = Map.find(L);
991 if (It == Map.end())
992 return SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
993
994 return SCEVAddRecExpr::evaluateAtIteration(Operands, It->second, SE);
995 }
996
997private:
998 LoopToScevMapT &Map;
999};
1000
1001template <typename SCEVPtrT>
1002inline SCEVNoWrapFlags
1005 if (auto *NAry = dyn_cast<SCEVNAryExpr>(Base::getPointer()))
1006 Flags = NAry->getNoWrapFlags();
1007 return (Flags | getUseNoWrapFlags()) & Mask;
1008}
1009
1010} // end namespace llvm
1011
1012#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))
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:171
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 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.
void push_back(const T &Elt)
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)
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...
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)