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<SCEVFlags>(SubclassData) & Mask & SCEV::FlagsNoWrapMask;
215 }
216
218
219 bool hasNoSignedWrap() const { return getNoWrapFlags(FlagNSW) != FlagNone; }
220
221 bool hasNoSelfWrap() const { return getNoWrapFlags(FlagNW) != FlagNone; }
222
223 /// Methods for support type inquiry through isa, cast, and dyn_cast:
224 static bool classof(const SCEV *S) {
225 return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
226 S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
227 S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr ||
230 }
231};
232
233/// This node is the base class for n'ary commutative operators.
235protected:
237 const SCEVUse *O, size_t N, Type *Ty)
238 : SCEVNAryExpr(ID, T, O, N, Ty) {}
239
240public:
241 /// Methods for support type inquiry through isa, cast, and dyn_cast:
242 static bool classof(const SCEV *S) {
243 return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
244 S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
245 S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr;
246 }
247
248 /// Set flags for a non-recurrence without clearing previously set flags.
249 void setFlags(SCEVFlags Flags) {
250 SubclassData |= static_cast<unsigned short>(Flags);
251 }
254 }
255};
256
257/// This node represents an addition of some number of SCEVs.
258class SCEVAddExpr : public SCEVCommutativeExpr {
259 friend class ScalarEvolution;
260
261 /// The type of an add is the type of its first pointer-typed operand, if
262 /// any, otherwise the type of operand 0.
263 static Type *computeType(const SCEVUse *O, size_t N) {
265 auto *FirstPointerTypedOp =
266 find_if(Ops, [](SCEVUse Op) { return Op->getType()->isPointerTy(); });
267 if (FirstPointerTypedOp != Ops.end())
268 return (*FirstPointerTypedOp)->getType();
269 return Ops[0]->getType();
270 }
271
272 SCEVAddExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
273 : SCEVCommutativeExpr(ID, scAddExpr, O, N, computeType(O, N)) {}
274
275public:
276 /// Methods for support type inquiry through isa, cast, and dyn_cast:
277 static bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr; }
278};
279
280/// This node represents multiplication of some number of SCEVs.
281class SCEVMulExpr : public SCEVCommutativeExpr {
282 friend class ScalarEvolution;
283
284 SCEVMulExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
285 : SCEVCommutativeExpr(ID, scMulExpr, O, N, O[0]->getType()) {}
286
287public:
288 /// Methods for support type inquiry through isa, cast, and dyn_cast:
289 static bool classof(const SCEV *S) { return S->getSCEVType() == scMulExpr; }
290};
291
292/// This class represents a binary unsigned division operation.
293class SCEVUDivExpr : public SCEV {
294 friend class ScalarEvolution;
295
296 std::array<SCEVUse, 2> Operands;
297
298 SCEVUDivExpr(const FoldingSetNodeIDRef ID, SCEVUse lhs, SCEVUse rhs)
299 : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs}),
300 lhs->getType()) {
301 Operands[0] = lhs;
302 Operands[1] = rhs;
303 }
304
305public:
306 SCEVUse getLHS() const { return Operands[0]; }
307 SCEVUse getRHS() const { return Operands[1]; }
308 size_t getNumOperands() const { return 2; }
309 SCEVUse getOperand(unsigned i) const {
310 assert((i == 0 || i == 1) && "Operand index out of range!");
311 return i == 0 ? getLHS() : getRHS();
312 }
313
314 ArrayRef<SCEVUse> operands() const { return Operands; }
315
316 /// Methods for support type inquiry through isa, cast, and dyn_cast:
317 static bool classof(const SCEV *S) { return S->getSCEVType() == scUDivExpr; }
318};
319
320/// This node represents a polynomial recurrence on the trip count
321/// of the specified loop. This is the primary focus of the
322/// ScalarEvolution framework; all the other SCEV subclasses are
323/// mostly just supporting infrastructure to allow SCEVAddRecExpr
324/// expressions to be created and analyzed.
325///
326/// All operands of an AddRec are required to be loop invariant.
327///
328class SCEVAddRecExpr : public SCEVNAryExpr {
329 friend class ScalarEvolution;
330
331 const Loop *L;
332
333 SCEVAddRecExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N,
334 const Loop *l)
335 : SCEVNAryExpr(ID, scAddRecExpr, O, N, O[0]->getType()), L(l) {}
336
337public:
338 SCEVUse getStart() const { return Operands[0]; }
339 const Loop *getLoop() const { return L; }
340
341 /// Constructs and returns the recurrence indicating how much this
342 /// expression steps by. If this is a polynomial of degree N, it
343 /// returns a chrec of degree N-1. We cannot determine whether
344 /// the step recurrence has self-wraparound.
346 if (isAffine())
347 return getOperand(1);
348 return SE.getAddRecExpr(SmallVector<SCEVUse, 3>(operands().drop_front()),
349 getLoop(), FlagNone);
350 }
351
352 /// Return true if this represents an expression A + B*x where A
353 /// and B are loop invariant values.
354 bool isAffine() const {
355 // We know that the start value is invariant. This expression is thus
356 // affine iff the step is also invariant.
357 return getNumOperands() == 2;
358 }
359
360 /// Return true if this represents an expression A + B*x + C*x^2
361 /// where A, B and C are loop invariant values. This corresponds
362 /// to an addrec of the form {L,+,M,+,N}
363 bool isQuadratic() const { return getNumOperands() == 3; }
364
365 /// Set flags for a recurrence without clearing any previously set flags.
366 /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
367 /// to make it easier to propagate flags.
369 if (!any(Flags & FlagsNoWrapMask))
370 return;
371 if (any(Flags & (FlagNUW | FlagNSW)))
372 Flags = ScalarEvolution::setFlags(Flags, FlagNW);
373 SubclassData |= static_cast<unsigned short>(Flags);
374 }
375
376 /// Return the value of this chain of recurrences at the specified
377 /// iteration number.
378 LLVM_ABI const SCEV *evaluateAtIteration(const SCEV *It,
379 ScalarEvolution &SE) const;
380
381 /// Return the value of this chain of recurrences at the specified iteration
382 /// number. Takes an explicit list of operands to represent an AddRec.
383 LLVM_ABI static SCEVUse
386
387 /// Return the value of this recurrences when its loop exits, i.e. its value
388 /// at the loop's exact backedge-taken count, or SCEVCouldNotCompute if that
389 /// count cannot be computed.
391
392 /// Return the number of iterations of this loop that produce
393 /// values in the specified constant range. Another way of
394 /// looking at this is that it returns the first iteration number
395 /// where the value is not in the condition, thus computing the
396 /// exit count. If the iteration count can't be computed, an
397 /// instance of SCEVCouldNotCompute is returned.
399 ScalarEvolution &SE) const;
400
401 /// Return an expression representing the value of this expression
402 /// one iteration of the loop ahead.
404
405 /// Methods for support type inquiry through isa, cast, and dyn_cast:
406 static bool classof(const SCEV *S) {
407 return S->getSCEVType() == scAddRecExpr;
408 }
409};
410
411/// This node is the base class min/max selections.
413 friend class ScalarEvolution;
414
415 static bool isMinMaxType(enum SCEVTypes T) {
416 return T == scSMaxExpr || T == scUMaxExpr || T == scSMinExpr ||
417 T == scUMinExpr;
418 }
419
420protected:
421 /// Note: Constructing subclasses via this constructor is allowed
423 const SCEVUse *O, size_t N)
424 : SCEVCommutativeExpr(ID, T, O, N, O[0]->getType()) {
425 assert(isMinMaxType(T));
426 // Min and max never overflow
428 }
429
430public:
431 static bool classof(const SCEV *S) { return isMinMaxType(S->getSCEVType()); }
432
433 static enum SCEVTypes negate(enum SCEVTypes T) {
434 switch (T) {
435 case scSMaxExpr:
436 return scSMinExpr;
437 case scSMinExpr:
438 return scSMaxExpr;
439 case scUMaxExpr:
440 return scUMinExpr;
441 case scUMinExpr:
442 return scUMaxExpr;
443 default:
444 llvm_unreachable("Not a min or max SCEV type!");
445 }
446 }
447};
448
449/// This class represents a signed maximum selection.
450class SCEVSMaxExpr : public SCEVMinMaxExpr {
451 friend class ScalarEvolution;
452
453 SCEVSMaxExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
454 : SCEVMinMaxExpr(ID, scSMaxExpr, O, N) {}
455
456public:
457 /// Methods for support type inquiry through isa, cast, and dyn_cast:
458 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMaxExpr; }
459};
460
461/// This class represents an unsigned maximum selection.
462class SCEVUMaxExpr : public SCEVMinMaxExpr {
463 friend class ScalarEvolution;
464
465 SCEVUMaxExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
466 : SCEVMinMaxExpr(ID, scUMaxExpr, O, N) {}
467
468public:
469 /// Methods for support type inquiry through isa, cast, and dyn_cast:
470 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMaxExpr; }
471};
472
473/// This class represents a signed minimum selection.
474class SCEVSMinExpr : public SCEVMinMaxExpr {
475 friend class ScalarEvolution;
476
477 SCEVSMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
478 : SCEVMinMaxExpr(ID, scSMinExpr, O, N) {}
479
480public:
481 /// Methods for support type inquiry through isa, cast, and dyn_cast:
482 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMinExpr; }
483};
484
485/// This class represents an unsigned minimum selection.
486class SCEVUMinExpr : public SCEVMinMaxExpr {
487 friend class ScalarEvolution;
488
489 SCEVUMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O, size_t N)
490 : SCEVMinMaxExpr(ID, scUMinExpr, O, N) {}
491
492public:
493 /// Methods for support type inquiry through isa, cast, and dyn_cast:
494 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMinExpr; }
495};
496
497/// This node is the base class for sequential/in-order min/max selections.
498/// Note that their fundamental difference from SCEVMinMaxExpr's is that they
499/// are early-returning upon reaching saturation point.
500/// I.e. given `0 umin_seq poison`, the result will be `0`, while the result of
501/// `0 umin poison` is `poison`. When returning early, later expressions are not
502/// executed, so `0 umin_seq (%x u/ 0)` does not result in undefined behavior.
504 friend class ScalarEvolution;
505
506 static bool isSequentialMinMaxType(enum SCEVTypes T) {
507 return T == scSequentialUMinExpr;
508 }
509
510 /// Set flags for a non-recurrence without clearing previously set flags.
511 void setFlags(SCEVFlags Flags) {
512 SubclassData |= static_cast<unsigned short>(Flags);
513 }
514 void setNoWrapFlags(SCEVFlags Flags) {
515 setFlags(Flags & SCEV::FlagsNoWrapMask);
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};
547
548/// This class represents a sequential/in-order unsigned minimum selection.
549class SCEVSequentialUMinExpr : public SCEVSequentialMinMaxExpr {
550 friend class ScalarEvolution;
551
552 SCEVSequentialUMinExpr(const FoldingSetNodeIDRef ID, const SCEVUse *O,
553 size_t N)
555
556public:
557 /// Methods for support type inquiry through isa, cast, and dyn_cast:
558 static bool classof(const SCEV *S) {
559 return S->getSCEVType() == scSequentialUMinExpr;
560 }
561};
562
563/// This means that we are dealing with an entirely unknown SCEV
564/// value, and only represent it as its LLVM Value. This is the
565/// "bottom" value for the analysis.
566class LLVM_ABI SCEVUnknown final : public SCEV, private CallbackVH {
567 friend class ScalarEvolution;
568
569 /// The parent ScalarEvolution value. This is used to update the
570 /// parent's maps when the value associated with a SCEVUnknown is
571 /// deleted or RAUW'd.
572 ScalarEvolution *SE;
573
574 /// The next pointer in the linked list of all SCEVUnknown
575 /// instances owned by a ScalarEvolution.
576 SCEVUnknown *Next;
577
578 SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V, ScalarEvolution *se,
579 SCEVUnknown *next)
580 : SCEV(ID, scUnknown, 1, V->getType()), CallbackVH(V), SE(se),
581 Next(next) {}
582
583 // Implement CallbackVH.
584 void deleted() override;
585 void allUsesReplacedWith(Value *New) override;
586
587public:
588 Value *getValue() const { return getValPtr(); }
589
590 /// Methods for support type inquiry through isa, cast, and dyn_cast:
591 static bool classof(const SCEV *S) { return S->getSCEVType() == scUnknown; }
592};
593
594/// This class defines a simple visitor class that may be used for
595/// various SCEV analysis purposes.
596template <typename SC, typename RetVal = void> struct SCEVVisitor {
597 RetVal visit(const SCEV *S) {
598 switch (S->getSCEVType()) {
599 case scConstant:
600 return ((SC *)this)->visitConstant((const SCEVConstant *)S);
601 case scVScale:
602 return ((SC *)this)->visitVScale((const SCEVVScale *)S);
603 case scPtrToAddr:
604 return ((SC *)this)->visitPtrToAddrExpr((const SCEVPtrToAddrExpr *)S);
605 case scTruncate:
606 return ((SC *)this)->visitTruncateExpr((const SCEVTruncateExpr *)S);
607 case scZeroExtend:
608 return ((SC *)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr *)S);
609 case scSignExtend:
610 return ((SC *)this)->visitSignExtendExpr((const SCEVSignExtendExpr *)S);
611 case scAddExpr:
612 return ((SC *)this)->visitAddExpr((const SCEVAddExpr *)S);
613 case scMulExpr:
614 return ((SC *)this)->visitMulExpr((const SCEVMulExpr *)S);
615 case scUDivExpr:
616 return ((SC *)this)->visitUDivExpr((const SCEVUDivExpr *)S);
617 case scAddRecExpr:
618 return ((SC *)this)->visitAddRecExpr((const SCEVAddRecExpr *)S);
619 case scSMaxExpr:
620 return ((SC *)this)->visitSMaxExpr((const SCEVSMaxExpr *)S);
621 case scUMaxExpr:
622 return ((SC *)this)->visitUMaxExpr((const SCEVUMaxExpr *)S);
623 case scSMinExpr:
624 return ((SC *)this)->visitSMinExpr((const SCEVSMinExpr *)S);
625 case scUMinExpr:
626 return ((SC *)this)->visitUMinExpr((const SCEVUMinExpr *)S);
628 return ((SC *)this)
629 ->visitSequentialUMinExpr((const SCEVSequentialUMinExpr *)S);
630 case scUnknown:
631 return ((SC *)this)->visitUnknown((const SCEVUnknown *)S);
633 return ((SC *)this)->visitCouldNotCompute((const SCEVCouldNotCompute *)S);
634 }
635 llvm_unreachable("Unknown SCEV kind!");
636 }
637
639 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
640 }
641};
642
643/// A visitor class for SCEVUse.
644template <typename SC, typename RetVal = void> struct SCEVUseVisitor {
645 RetVal visit(SCEVUse S) {
646 switch (S->getSCEVType()) {
647 case scConstant:
648 return ((SC *)this)
649 ->visitConstant(cast<SCEVUseT<const SCEVConstant *>>(S));
650 case scVScale:
651 return ((SC *)this)->visitVScale(cast<SCEVUseT<const SCEVVScale *>>(S));
652 case scPtrToAddr:
653 return ((SC *)this)
654 ->visitPtrToAddrExpr(cast<SCEVUseT<const SCEVPtrToAddrExpr *>>(S));
655 case scTruncate:
656 return ((SC *)this)
657 ->visitTruncateExpr(cast<SCEVUseT<const SCEVTruncateExpr *>>(S));
658 case scZeroExtend:
659 return ((SC *)this)
660 ->visitZeroExtendExpr(cast<SCEVUseT<const SCEVZeroExtendExpr *>>(S));
661 case scSignExtend:
662 return ((SC *)this)
663 ->visitSignExtendExpr(cast<SCEVUseT<const SCEVSignExtendExpr *>>(S));
664 case scAddExpr:
665 return ((SC *)this)->visitAddExpr(cast<SCEVUseT<const SCEVAddExpr *>>(S));
666 case scMulExpr:
667 return ((SC *)this)->visitMulExpr(cast<SCEVUseT<const SCEVMulExpr *>>(S));
668 case scUDivExpr:
669 return ((SC *)this)
670 ->visitUDivExpr(cast<SCEVUseT<const SCEVUDivExpr *>>(S));
671 case scAddRecExpr:
672 return ((SC *)this)
673 ->visitAddRecExpr(cast<SCEVUseT<const SCEVAddRecExpr *>>(S));
674 case scSMaxExpr:
675 return ((SC *)this)
676 ->visitSMaxExpr(cast<SCEVUseT<const SCEVSMaxExpr *>>(S));
677 case scUMaxExpr:
678 return ((SC *)this)
679 ->visitUMaxExpr(cast<SCEVUseT<const SCEVUMaxExpr *>>(S));
680 case scSMinExpr:
681 return ((SC *)this)
682 ->visitSMinExpr(cast<SCEVUseT<const SCEVSMinExpr *>>(S));
683 case scUMinExpr:
684 return ((SC *)this)
685 ->visitUMinExpr(cast<SCEVUseT<const SCEVUMinExpr *>>(S));
687 return ((SC *)this)
688 ->visitSequentialUMinExpr(
690 case scUnknown:
691 return ((SC *)this)->visitUnknown(cast<SCEVUseT<const SCEVUnknown *>>(S));
693 return ((SC *)this)
694 ->visitCouldNotCompute(
696 }
697 llvm_unreachable("Unknown SCEV kind!");
698 }
699
701 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
702 }
703};
704
705/// Visit all nodes in the expression tree using worklist traversal.
706///
707/// Visitor implements:
708/// // return true to follow this node.
709/// bool follow(const SCEV *S);
710/// // return true to terminate the search.
711/// bool isDone();
712template <typename SV> class SCEVTraversal {
713 SV &Visitor;
716
717 void push(const SCEV *S) {
718 if (Visited.insert(S).second && Visitor.follow(S))
719 Worklist.push_back(S);
720 }
721
722public:
723 SCEVTraversal(SV &V) : Visitor(V) {}
724
725 void visitAll(const SCEV *Root) {
726 push(Root);
727 while (!Worklist.empty() && !Visitor.isDone()) {
728 const SCEV *S = Worklist.pop_back_val();
729
730 switch (S->getSCEVType()) {
731 case scConstant:
732 case scVScale:
733 case scUnknown:
734 continue;
735 case scPtrToAddr:
736 case scTruncate:
737 case scZeroExtend:
738 case scSignExtend:
739 case scAddExpr:
740 case scMulExpr:
741 case scUDivExpr:
742 case scSMaxExpr:
743 case scUMaxExpr:
744 case scSMinExpr:
745 case scUMinExpr:
747 case scAddRecExpr:
748 for (const SCEV *Op : S->operands()) {
749 push(Op);
750 if (Visitor.isDone())
751 break;
752 }
753 continue;
755 llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
756 }
757 llvm_unreachable("Unknown SCEV kind!");
758 }
759 }
760};
761
762/// Use SCEVTraversal to visit all nodes in the given expression tree.
763template <typename SV> void visitAll(const SCEV *Root, SV &Visitor) {
764 SCEVTraversal<SV> T(Visitor);
765 T.visitAll(Root);
766}
767
768/// Return true if any node in \p Root satisfies the predicate \p Pred.
769template <typename PredTy>
770bool SCEVExprContains(const SCEV *Root, PredTy Pred) {
771 struct FindClosure {
772 bool Found = false;
773 PredTy Pred;
774
775 FindClosure(PredTy Pred) : Pred(Pred) {}
776
777 bool follow(const SCEV *S) {
778 if (!Pred(S))
779 return true;
780
781 Found = true;
782 return false;
783 }
784
785 bool isDone() const { return Found; }
786 };
787
788 FindClosure FC(Pred);
789 visitAll(Root, FC);
790 return FC.Found;
791}
792
793/// This visitor recursively visits a SCEV expression and re-writes it.
794/// The result from each visit is cached, so it will return the same
795/// SCEV for the same input.
796template <typename SC>
797class SCEVRewriteVisitor : public SCEVVisitor<SC, const SCEV *> {
798protected:
800 // Memoize the result of each visit so that we only compute once for
801 // the same input SCEV. This is to avoid redundant computations when
802 // a SCEV is referenced by multiple SCEVs. Without memoization, this
803 // visit algorithm would have exponential time complexity in the worst
804 // case, causing the compiler to hang on certain tests.
806
807public:
809
810 const SCEV *visit(const SCEV *S) {
811 auto It = RewriteResults.find(S);
812 if (It != RewriteResults.end())
813 return It->second;
814 auto *Visited = SCEVVisitor<SC, const SCEV *>::visit(S);
815 auto Result = RewriteResults.try_emplace(S, Visited);
816 assert(Result.second && "Should insert a new entry");
817 return Result.first->second;
818 }
819
821
822 const SCEV *visitVScale(const SCEVVScale *VScale) { return VScale; }
823
825 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
826 return Operand == Expr->getOperand() ? Expr : SE.getPtrToAddrExpr(Operand);
827 }
828
830 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
831 return Operand == Expr->getOperand()
832 ? Expr
833 : SE.getTruncateExpr(Operand, Expr->getType());
834 }
835
837 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
838 return Operand == Expr->getOperand()
839 ? Expr
840 : SE.getZeroExtendExpr(Operand, Expr->getType());
841 }
842
844 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
845 return Operand == Expr->getOperand()
846 ? Expr
847 : SE.getSignExtendExpr(Operand, Expr->getType());
848 }
849
850 const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
852 bool Changed = false;
853 for (const SCEV *Op : Expr->operands()) {
854 Operands.push_back(((SC *)this)->visit(Op));
855 Changed |= Op != Operands.back();
856 }
857 return !Changed ? Expr : SE.getAddExpr(Operands);
858 }
859
860 const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
862 bool Changed = false;
863 for (const SCEV *Op : Expr->operands()) {
864 Operands.push_back(((SC *)this)->visit(Op));
865 Changed |= Op != Operands.back();
866 }
867 return !Changed ? Expr : SE.getMulExpr(Operands);
868 }
869
870 const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
871 auto *LHS = ((SC *)this)->visit(Expr->getLHS());
872 auto *RHS = ((SC *)this)->visit(Expr->getRHS());
873 bool Changed = LHS != Expr->getLHS() || RHS != Expr->getRHS();
874 return !Changed ? Expr : SE.getUDivExpr(LHS, RHS);
875 }
876
877 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
879 bool Changed = false;
880 for (const SCEV *Op : Expr->operands()) {
881 Operands.push_back(((SC *)this)->visit(Op));
882 Changed |= Op != Operands.back();
883 }
884 return !Changed ? Expr
885 : SE.getAddRecExpr(Operands, Expr->getLoop(),
886 Expr->getNoWrapFlags());
887 }
888
889 const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
891 bool Changed = false;
892 for (const SCEV *Op : Expr->operands()) {
893 Operands.push_back(((SC *)this)->visit(Op));
894 Changed |= Op != Operands.back();
895 }
896 return !Changed ? Expr : SE.getSMaxExpr(Operands);
897 }
898
899 const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
901 bool Changed = false;
902 for (const SCEV *Op : Expr->operands()) {
903 Operands.push_back(((SC *)this)->visit(Op));
904 Changed |= Op != Operands.back();
905 }
906 return !Changed ? Expr : SE.getUMaxExpr(Operands);
907 }
908
909 const SCEV *visitSMinExpr(const SCEVSMinExpr *Expr) {
911 bool Changed = false;
912 for (const SCEV *Op : Expr->operands()) {
913 Operands.push_back(((SC *)this)->visit(Op));
914 Changed |= Op != Operands.back();
915 }
916 return !Changed ? Expr : SE.getSMinExpr(Operands);
917 }
918
919 const SCEV *visitUMinExpr(const SCEVUMinExpr *Expr) {
921 bool Changed = false;
922 for (const SCEV *Op : Expr->operands()) {
923 Operands.push_back(((SC *)this)->visit(Op));
924 Changed |= Op != Operands.back();
925 }
926 return !Changed ? Expr : SE.getUMinExpr(Operands);
927 }
928
931 bool Changed = false;
932 for (const SCEV *Op : Expr->operands()) {
933 Operands.push_back(((SC *)this)->visit(Op));
934 Changed |= Op != Operands.back();
935 }
936 return !Changed ? Expr : SE.getUMinExpr(Operands, /*Sequential=*/true);
937 }
938
939 const SCEV *visitUnknown(const SCEVUnknown *Expr) { return Expr; }
940
942 return Expr;
943 }
944};
945
948
949/// The SCEVParameterRewriter takes a scalar evolution expression and updates
950/// the SCEVUnknown components following the Map (Value -> SCEV).
951class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> {
952public:
953 static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
954 ValueToSCEVMapTy &Map) {
956 return Rewriter.visit(Scev);
957 }
958
961
962 const SCEV *visitUnknown(const SCEVUnknown *Expr) {
963 auto I = Map.find(Expr->getValue());
964 if (I == Map.end())
965 return Expr;
966 return I->second;
967 }
968
969private:
970 ValueToSCEVMapTy &Map;
971};
972
974
975/// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies
976/// the Map (Loop -> SCEV) to all AddRecExprs.
978 : public SCEVRewriteVisitor<SCEVLoopAddRecRewriter> {
979public:
982
983 static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
986 return Rewriter.visit(Scev);
987 }
988
989 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
991 for (SCEVUse Op : Expr->operands())
992 Operands.push_back(visit(Op));
993
994 const Loop *L = Expr->getLoop();
995 auto It = Map.find(L);
996 if (It == Map.end())
997 return SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
998
1000 }
1001
1002private:
1003 LoopToScevMapT &Map;
1004};
1005
1006template <typename SCEVPtrT>
1007inline SCEVUseT<SCEVPtrT>::SCEVUseT(SCEVPtrT S, SCEVFlags Flags) : Base(S, 0) {
1008 assert((Flags & SCEVFlags::FlagsNoWrapMask) == Flags &&
1009 "Expected only no-wrap flags");
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>
1022 if (auto *NAry = dyn_cast<SCEVNAryExpr>(Base::getPointer()))
1023 Flags = NAry->getNoWrapFlags();
1024 return (Flags | getUseNoWrapFlags()) & Mask;
1025}
1026
1027} // end namespace llvm
1028
1029#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 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(SCEVFlags 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 setFlags(SCEVFlags 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 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)
SCEVFlags getNoWrapFlags(SCEVFlags Mask=FlagsNoWrapMask) const
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
SCEVUse getOperand(unsigned i) const
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:
SmallDenseMap< const SCEV *, const SCEV *, 16 > RewriteResults
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)
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 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 FlagsNoWrapMask
SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, unsigned short ExpressionSize, Type *Ty)
static constexpr auto FlagNUW
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.
static constexpr auto FlagNone
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.
static SCEVFlags setFlags(SCEVFlags Flags, SCEVFlags OnFlags)
LLVM_ABI SCEVUse getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEVFlagsPair Flags)
Get an add recurrence expression for the specified loop.
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
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
SCEVFlags
SCEVFlags are bitfield indices into SCEV's SubclassData.
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:1788
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.
SCEVFlags getUseNoWrapFlags() const
Return only the use-specific flags without the underlying SCEV's flags.
SCEVFlags getNoWrapFlags(SCEVFlags Mask=SCEVFlags::FlagsNoWrapMask) const
Return the flags for this SCEVUse, which is the union of the use-specific flags and the underlying SC...
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)