LLVM 22.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(v) {}
68
69public:
70 ConstantInt *getValue() const { return V; }
71 const APInt &getAPInt() const { return getValue()->getValue(); }
72
73 Type *getType() const { return V->getType(); }
74
75 /// Methods for support type inquiry through isa, cast, and dyn_cast:
76 static bool classof(const SCEV *S) { return S->getSCEVType() == scConstant; }
77};
78
79/// This class represents the value of vscale, as used when defining the length
80/// of a scalable vector or returned by the llvm.vscale() intrinsic.
81class SCEVVScale : public SCEV {
82 friend class ScalarEvolution;
83
84 SCEVVScale(const FoldingSetNodeIDRef ID, Type *ty)
85 : SCEV(ID, scVScale, 0), Ty(ty) {}
86
87 Type *Ty;
88
89public:
90 Type *getType() const { return Ty; }
91
92 /// Methods for support type inquiry through isa, cast, and dyn_cast:
93 static bool classof(const SCEV *S) { return S->getSCEVType() == scVScale; }
94};
95
96inline unsigned short computeExpressionSize(ArrayRef<const SCEV *> Args) {
97 APInt Size(16, 1);
98 for (const auto *Arg : Args)
99 Size = Size.uadd_sat(APInt(16, Arg->getExpressionSize()));
100 return (unsigned short)Size.getZExtValue();
101}
102
103/// This is the base class for unary cast operator classes.
104class SCEVCastExpr : public SCEV {
105protected:
106 const SCEV *Op;
108
110 const SCEV *op, Type *ty);
111
112public:
113 const SCEV *getOperand() const { return Op; }
114 const SCEV *getOperand(unsigned i) const {
115 assert(i == 0 && "Operand index out of range!");
116 return Op;
117 }
119 size_t getNumOperands() const { return 1; }
120 Type *getType() const { return Ty; }
121
122 /// Methods for support type inquiry through isa, cast, and dyn_cast:
123 static bool classof(const SCEV *S) {
124 return S->getSCEVType() == scPtrToInt || S->getSCEVType() == scTruncate ||
126 }
127};
128
129/// This class represents a cast from a pointer to a pointer-sized integer
130/// value.
131class SCEVPtrToIntExpr : public SCEVCastExpr {
132 friend class ScalarEvolution;
133
134 SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op, Type *ITy);
135
136public:
137 /// Methods for support type inquiry through isa, cast, and dyn_cast:
138 static bool classof(const SCEV *S) { return S->getSCEVType() == scPtrToInt; }
139};
140
141/// This is the base class for unary integral cast operator classes.
143protected:
145 const SCEV *op, Type *ty);
146
147public:
148 /// Methods for support type inquiry through isa, cast, and dyn_cast:
149 static bool classof(const SCEV *S) {
150 return S->getSCEVType() == scTruncate || S->getSCEVType() == scZeroExtend ||
152 }
153};
154
155/// This class represents a truncation of an integer value to a
156/// smaller integer value.
157class SCEVTruncateExpr : public SCEVIntegralCastExpr {
158 friend class ScalarEvolution;
159
160 SCEVTruncateExpr(const FoldingSetNodeIDRef ID, const SCEV *op, Type *ty);
161
162public:
163 /// Methods for support type inquiry through isa, cast, and dyn_cast:
164 static bool classof(const SCEV *S) { return S->getSCEVType() == scTruncate; }
165};
166
167/// This class represents a zero extension of a small integer value
168/// to a larger integer value.
169class SCEVZeroExtendExpr : public SCEVIntegralCastExpr {
170 friend class ScalarEvolution;
171
172 SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID, const SCEV *op, Type *ty);
173
174public:
175 /// Methods for support type inquiry through isa, cast, and dyn_cast:
176 static bool classof(const SCEV *S) {
177 return S->getSCEVType() == scZeroExtend;
178 }
179};
180
181/// This class represents a sign extension of a small integer value
182/// to a larger integer value.
183class SCEVSignExtendExpr : public SCEVIntegralCastExpr {
184 friend class ScalarEvolution;
185
186 SCEVSignExtendExpr(const FoldingSetNodeIDRef ID, const SCEV *op, Type *ty);
187
188public:
189 /// Methods for support type inquiry through isa, cast, and dyn_cast:
190 static bool classof(const SCEV *S) {
191 return S->getSCEVType() == scSignExtend;
192 }
193};
194
195/// This node is a base class providing common functionality for
196/// n'ary operators.
197class SCEVNAryExpr : public SCEV {
198protected:
199 // Since SCEVs are immutable, ScalarEvolution allocates operand
200 // arrays with its SCEVAllocator, so this class just needs a simple
201 // pointer rather than a more elaborate vector-like data structure.
202 // This also avoids the need for a non-trivial destructor.
203 const SCEV *const *Operands;
205
207 const SCEV *const *O, size_t N)
209 NumOperands(N) {}
210
211public:
212 size_t getNumOperands() const { return NumOperands; }
213
214 const SCEV *getOperand(unsigned i) const {
215 assert(i < NumOperands && "Operand index out of range!");
216 return Operands[i];
217 }
218
222
224 return (NoWrapFlags)(SubclassData & Mask);
225 }
226
227 bool hasNoUnsignedWrap() const {
229 }
230
231 bool hasNoSignedWrap() const {
233 }
234
235 bool hasNoSelfWrap() const { return getNoWrapFlags(FlagNW) != FlagAnyWrap; }
236
237 /// Methods for support type inquiry through isa, cast, and dyn_cast:
238 static bool classof(const SCEV *S) {
239 return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
240 S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
241 S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr ||
244 }
245};
246
247/// This node is the base class for n'ary commutative operators.
249protected:
251 const SCEV *const *O, size_t N)
252 : SCEVNAryExpr(ID, T, O, N) {}
253
254public:
255 /// Methods for support type inquiry through isa, cast, and dyn_cast:
256 static bool classof(const SCEV *S) {
257 return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
258 S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
259 S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr;
260 }
261
262 /// Set flags for a non-recurrence without clearing previously set flags.
263 void setNoWrapFlags(NoWrapFlags Flags) { SubclassData |= Flags; }
264};
265
266/// This node represents an addition of some number of SCEVs.
267class SCEVAddExpr : public SCEVCommutativeExpr {
268 friend class ScalarEvolution;
269
270 Type *Ty;
271
272 SCEVAddExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
274 auto *FirstPointerTypedOp = find_if(operands(), [](const SCEV *Op) {
275 return Op->getType()->isPointerTy();
276 });
277 if (FirstPointerTypedOp != operands().end())
278 Ty = (*FirstPointerTypedOp)->getType();
279 else
280 Ty = getOperand(0)->getType();
281 }
282
283public:
284 Type *getType() const { return Ty; }
285
286 /// Methods for support type inquiry through isa, cast, and dyn_cast:
287 static bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr; }
288};
289
290/// This node represents multiplication of some number of SCEVs.
291class SCEVMulExpr : public SCEVCommutativeExpr {
292 friend class ScalarEvolution;
293
294 SCEVMulExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
296
297public:
298 Type *getType() const { return getOperand(0)->getType(); }
299
300 /// Methods for support type inquiry through isa, cast, and dyn_cast:
301 static bool classof(const SCEV *S) { return S->getSCEVType() == scMulExpr; }
302};
303
304/// This class represents a binary unsigned division operation.
305class SCEVUDivExpr : public SCEV {
306 friend class ScalarEvolution;
307
308 std::array<const SCEV *, 2> Operands;
309
310 SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
311 : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs})) {
312 Operands[0] = lhs;
313 Operands[1] = rhs;
314 }
315
316public:
317 const SCEV *getLHS() const { return Operands[0]; }
318 const SCEV *getRHS() const { return Operands[1]; }
319 size_t getNumOperands() const { return 2; }
320 const SCEV *getOperand(unsigned i) const {
321 assert((i == 0 || i == 1) && "Operand index out of range!");
322 return i == 0 ? getLHS() : getRHS();
323 }
324
325 ArrayRef<const SCEV *> operands() const { return Operands; }
326
327 Type *getType() const {
328 // In most cases the types of LHS and RHS will be the same, but in some
329 // crazy cases one or the other may be a pointer. ScalarEvolution doesn't
330 // depend on the type for correctness, but handling types carefully can
331 // avoid extra casts in the SCEVExpander. The LHS is more likely to be
332 // a pointer type than the RHS, so use the RHS' type here.
333 return getRHS()->getType();
334 }
335
336 /// Methods for support type inquiry through isa, cast, and dyn_cast:
337 static bool classof(const SCEV *S) { return S->getSCEVType() == scUDivExpr; }
338};
339
340/// This node represents a polynomial recurrence on the trip count
341/// of the specified loop. This is the primary focus of the
342/// ScalarEvolution framework; all the other SCEV subclasses are
343/// mostly just supporting infrastructure to allow SCEVAddRecExpr
344/// expressions to be created and analyzed.
345///
346/// All operands of an AddRec are required to be loop invariant.
347///
348class SCEVAddRecExpr : public SCEVNAryExpr {
349 friend class ScalarEvolution;
350
351 const Loop *L;
352
353 SCEVAddRecExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N,
354 const Loop *l)
355 : SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) {}
356
357public:
358 Type *getType() const { return getStart()->getType(); }
359 const SCEV *getStart() const { return Operands[0]; }
360 const Loop *getLoop() const { return L; }
361
362 /// Constructs and returns the recurrence indicating how much this
363 /// expression steps by. If this is a polynomial of degree N, it
364 /// returns a chrec of degree N-1. We cannot determine whether
365 /// the step recurrence has self-wraparound.
367 if (isAffine())
368 return getOperand(1);
369 return SE.getAddRecExpr(
372 }
373
374 /// Return true if this represents an expression A + B*x where A
375 /// and B are loop invariant values.
376 bool isAffine() const {
377 // We know that the start value is invariant. This expression is thus
378 // affine iff the step is also invariant.
379 return getNumOperands() == 2;
380 }
381
382 /// Return true if this represents an expression A + B*x + C*x^2
383 /// where A, B and C are loop invariant values. This corresponds
384 /// to an addrec of the form {L,+,M,+,N}
385 bool isQuadratic() const { return getNumOperands() == 3; }
386
387 /// Set flags for a recurrence without clearing any previously set flags.
388 /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
389 /// to make it easier to propagate flags.
391 if (Flags & (FlagNUW | FlagNSW))
392 Flags = ScalarEvolution::setFlags(Flags, FlagNW);
393 SubclassData |= Flags;
394 }
395
396 /// Return the value of this chain of recurrences at the specified
397 /// iteration number.
398 LLVM_ABI const SCEV *evaluateAtIteration(const SCEV *It,
399 ScalarEvolution &SE) const;
400
401 /// Return the value of this chain of recurrences at the specified iteration
402 /// number. Takes an explicit list of operands to represent an AddRec.
403 LLVM_ABI static const SCEV *
405 ScalarEvolution &SE);
406
407 /// Return the number of iterations of this loop that produce
408 /// values in the specified constant range. Another way of
409 /// looking at this is that it returns the first iteration number
410 /// where the value is not in the condition, thus computing the
411 /// exit count. If the iteration count can't be computed, an
412 /// instance of SCEVCouldNotCompute is returned.
414 ScalarEvolution &SE) const;
415
416 /// Return an expression representing the value of this expression
417 /// one iteration of the loop ahead.
419
420 /// Methods for support type inquiry through isa, cast, and dyn_cast:
421 static bool classof(const SCEV *S) {
422 return S->getSCEVType() == scAddRecExpr;
423 }
424};
425
426/// This node is the base class min/max selections.
428 friend class ScalarEvolution;
429
430 static bool isMinMaxType(enum SCEVTypes T) {
431 return T == scSMaxExpr || T == scUMaxExpr || T == scSMinExpr ||
432 T == scUMinExpr;
433 }
434
435protected:
436 /// Note: Constructing subclasses via this constructor is allowed
438 const SCEV *const *O, size_t N)
439 : SCEVCommutativeExpr(ID, T, O, N) {
440 assert(isMinMaxType(T));
441 // Min and max never overflow
443 }
444
445public:
446 Type *getType() const { return getOperand(0)->getType(); }
447
448 static bool classof(const SCEV *S) { return isMinMaxType(S->getSCEVType()); }
449
450 static enum SCEVTypes negate(enum SCEVTypes T) {
451 switch (T) {
452 case scSMaxExpr:
453 return scSMinExpr;
454 case scSMinExpr:
455 return scSMaxExpr;
456 case scUMaxExpr:
457 return scUMinExpr;
458 case scUMinExpr:
459 return scUMaxExpr;
460 default:
461 llvm_unreachable("Not a min or max SCEV type!");
462 }
463 }
464};
465
466/// This class represents a signed maximum selection.
467class SCEVSMaxExpr : public SCEVMinMaxExpr {
468 friend class ScalarEvolution;
469
470 SCEVSMaxExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
471 : SCEVMinMaxExpr(ID, scSMaxExpr, O, N) {}
472
473public:
474 /// Methods for support type inquiry through isa, cast, and dyn_cast:
475 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMaxExpr; }
476};
477
478/// This class represents an unsigned maximum selection.
479class SCEVUMaxExpr : public SCEVMinMaxExpr {
480 friend class ScalarEvolution;
481
482 SCEVUMaxExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
483 : SCEVMinMaxExpr(ID, scUMaxExpr, O, N) {}
484
485public:
486 /// Methods for support type inquiry through isa, cast, and dyn_cast:
487 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMaxExpr; }
488};
489
490/// This class represents a signed minimum selection.
491class SCEVSMinExpr : public SCEVMinMaxExpr {
492 friend class ScalarEvolution;
493
494 SCEVSMinExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
495 : SCEVMinMaxExpr(ID, scSMinExpr, O, N) {}
496
497public:
498 /// Methods for support type inquiry through isa, cast, and dyn_cast:
499 static bool classof(const SCEV *S) { return S->getSCEVType() == scSMinExpr; }
500};
501
502/// This class represents an unsigned minimum selection.
503class SCEVUMinExpr : public SCEVMinMaxExpr {
504 friend class ScalarEvolution;
505
506 SCEVUMinExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
507 : SCEVMinMaxExpr(ID, scUMinExpr, O, N) {}
508
509public:
510 /// Methods for support type inquiry through isa, cast, and dyn_cast:
511 static bool classof(const SCEV *S) { return S->getSCEVType() == scUMinExpr; }
512};
513
514/// This node is the base class for sequential/in-order min/max selections.
515/// Note that their fundamental difference from SCEVMinMaxExpr's is that they
516/// are early-returning upon reaching saturation point.
517/// I.e. given `0 umin_seq poison`, the result will be `0`, while the result of
518/// `0 umin poison` is `poison`. When returning early, later expressions are not
519/// executed, so `0 umin_seq (%x u/ 0)` does not result in undefined behavior.
521 friend class ScalarEvolution;
522
523 static bool isSequentialMinMaxType(enum SCEVTypes T) {
524 return T == scSequentialUMinExpr;
525 }
526
527 /// Set flags for a non-recurrence without clearing previously set flags.
528 void setNoWrapFlags(NoWrapFlags Flags) { SubclassData |= Flags; }
529
530protected:
531 /// Note: Constructing subclasses via this constructor is allowed
533 const SCEV *const *O, size_t N)
534 : SCEVNAryExpr(ID, T, O, N) {
535 assert(isSequentialMinMaxType(T));
536 // Min and max never overflow
537 setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
538 }
539
540public:
541 Type *getType() const { return getOperand(0)->getType(); }
542
544 assert(isSequentialMinMaxType(Ty));
545 switch (Ty) {
547 return scUMinExpr;
548 default:
549 llvm_unreachable("Not a sequential min/max type.");
550 }
551 }
552
556
557 static bool classof(const SCEV *S) {
558 return isSequentialMinMaxType(S->getSCEVType());
559 }
560};
561
562/// This class represents a sequential/in-order unsigned minimum selection.
563class SCEVSequentialUMinExpr : public SCEVSequentialMinMaxExpr {
564 friend class ScalarEvolution;
565
566 SCEVSequentialUMinExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O,
567 size_t N)
569
570public:
571 /// Methods for support type inquiry through isa, cast, and dyn_cast:
572 static bool classof(const SCEV *S) {
573 return S->getSCEVType() == scSequentialUMinExpr;
574 }
575};
576
577/// This means that we are dealing with an entirely unknown SCEV
578/// value, and only represent it as its LLVM Value. This is the
579/// "bottom" value for the analysis.
580class LLVM_ABI SCEVUnknown final : public SCEV, private CallbackVH {
581 friend class ScalarEvolution;
582
583 /// The parent ScalarEvolution value. This is used to update the
584 /// parent's maps when the value associated with a SCEVUnknown is
585 /// deleted or RAUW'd.
586 ScalarEvolution *SE;
587
588 /// The next pointer in the linked list of all SCEVUnknown
589 /// instances owned by a ScalarEvolution.
590 SCEVUnknown *Next;
591
592 SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V, ScalarEvolution *se,
593 SCEVUnknown *next)
594 : SCEV(ID, scUnknown, 1), CallbackVH(V), SE(se), Next(next) {}
595
596 // Implement CallbackVH.
597 void deleted() override;
598 void allUsesReplacedWith(Value *New) override;
599
600public:
601 Value *getValue() const { return getValPtr(); }
602
603 Type *getType() const { return getValPtr()->getType(); }
604
605 /// Methods for support type inquiry through isa, cast, and dyn_cast:
606 static bool classof(const SCEV *S) { return S->getSCEVType() == scUnknown; }
607};
608
609/// This class defines a simple visitor class that may be used for
610/// various SCEV analysis purposes.
611template <typename SC, typename RetVal = void> struct SCEVVisitor {
612 RetVal visit(const SCEV *S) {
613 switch (S->getSCEVType()) {
614 case scConstant:
615 return ((SC *)this)->visitConstant((const SCEVConstant *)S);
616 case scVScale:
617 return ((SC *)this)->visitVScale((const SCEVVScale *)S);
618 case scPtrToInt:
619 return ((SC *)this)->visitPtrToIntExpr((const SCEVPtrToIntExpr *)S);
620 case scTruncate:
621 return ((SC *)this)->visitTruncateExpr((const SCEVTruncateExpr *)S);
622 case scZeroExtend:
623 return ((SC *)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr *)S);
624 case scSignExtend:
625 return ((SC *)this)->visitSignExtendExpr((const SCEVSignExtendExpr *)S);
626 case scAddExpr:
627 return ((SC *)this)->visitAddExpr((const SCEVAddExpr *)S);
628 case scMulExpr:
629 return ((SC *)this)->visitMulExpr((const SCEVMulExpr *)S);
630 case scUDivExpr:
631 return ((SC *)this)->visitUDivExpr((const SCEVUDivExpr *)S);
632 case scAddRecExpr:
633 return ((SC *)this)->visitAddRecExpr((const SCEVAddRecExpr *)S);
634 case scSMaxExpr:
635 return ((SC *)this)->visitSMaxExpr((const SCEVSMaxExpr *)S);
636 case scUMaxExpr:
637 return ((SC *)this)->visitUMaxExpr((const SCEVUMaxExpr *)S);
638 case scSMinExpr:
639 return ((SC *)this)->visitSMinExpr((const SCEVSMinExpr *)S);
640 case scUMinExpr:
641 return ((SC *)this)->visitUMinExpr((const SCEVUMinExpr *)S);
643 return ((SC *)this)
644 ->visitSequentialUMinExpr((const SCEVSequentialUMinExpr *)S);
645 case scUnknown:
646 return ((SC *)this)->visitUnknown((const SCEVUnknown *)S);
648 return ((SC *)this)->visitCouldNotCompute((const SCEVCouldNotCompute *)S);
649 }
650 llvm_unreachable("Unknown SCEV kind!");
651 }
652
654 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
655 }
656};
657
658/// Visit all nodes in the expression tree using worklist traversal.
659///
660/// Visitor implements:
661/// // return true to follow this node.
662/// bool follow(const SCEV *S);
663/// // return true to terminate the search.
664/// bool isDone();
665template <typename SV> class SCEVTraversal {
666 SV &Visitor;
669
670 void push(const SCEV *S) {
671 if (Visited.insert(S).second && Visitor.follow(S))
672 Worklist.push_back(S);
673 }
674
675public:
676 SCEVTraversal(SV &V) : Visitor(V) {}
677
678 void visitAll(const SCEV *Root) {
679 push(Root);
680 while (!Worklist.empty() && !Visitor.isDone()) {
681 const SCEV *S = Worklist.pop_back_val();
682
683 switch (S->getSCEVType()) {
684 case scConstant:
685 case scVScale:
686 case scUnknown:
687 continue;
688 case scPtrToInt:
689 case scTruncate:
690 case scZeroExtend:
691 case scSignExtend:
692 case scAddExpr:
693 case scMulExpr:
694 case scUDivExpr:
695 case scSMaxExpr:
696 case scUMaxExpr:
697 case scSMinExpr:
698 case scUMinExpr:
700 case scAddRecExpr:
701 for (const auto *Op : S->operands()) {
702 push(Op);
703 if (Visitor.isDone())
704 break;
705 }
706 continue;
708 llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
709 }
710 llvm_unreachable("Unknown SCEV kind!");
711 }
712 }
713};
714
715/// Use SCEVTraversal to visit all nodes in the given expression tree.
716template <typename SV> void visitAll(const SCEV *Root, SV &Visitor) {
717 SCEVTraversal<SV> T(Visitor);
718 T.visitAll(Root);
719}
720
721/// Return true if any node in \p Root satisfies the predicate \p Pred.
722template <typename PredTy>
723bool SCEVExprContains(const SCEV *Root, PredTy Pred) {
724 struct FindClosure {
725 bool Found = false;
726 PredTy Pred;
727
728 FindClosure(PredTy Pred) : Pred(Pred) {}
729
730 bool follow(const SCEV *S) {
731 if (!Pred(S))
732 return true;
733
734 Found = true;
735 return false;
736 }
737
738 bool isDone() const { return Found; }
739 };
740
741 FindClosure FC(Pred);
742 visitAll(Root, FC);
743 return FC.Found;
744}
745
746/// This visitor recursively visits a SCEV expression and re-writes it.
747/// The result from each visit is cached, so it will return the same
748/// SCEV for the same input.
749template <typename SC>
750class SCEVRewriteVisitor : public SCEVVisitor<SC, const SCEV *> {
751protected:
753 // Memoize the result of each visit so that we only compute once for
754 // the same input SCEV. This is to avoid redundant computations when
755 // a SCEV is referenced by multiple SCEVs. Without memoization, this
756 // visit algorithm would have exponential time complexity in the worst
757 // case, causing the compiler to hang on certain tests.
759
760public:
762
763 const SCEV *visit(const SCEV *S) {
764 auto It = RewriteResults.find(S);
765 if (It != RewriteResults.end())
766 return It->second;
767 auto *Visited = SCEVVisitor<SC, const SCEV *>::visit(S);
768 auto Result = RewriteResults.try_emplace(S, Visited);
769 assert(Result.second && "Should insert a new entry");
770 return Result.first->second;
771 }
772
774
775 const SCEV *visitVScale(const SCEVVScale *VScale) { return VScale; }
776
778 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
779 return Operand == Expr->getOperand()
780 ? Expr
781 : SE.getPtrToIntExpr(Operand, Expr->getType());
782 }
783
785 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
786 return Operand == Expr->getOperand()
787 ? Expr
788 : SE.getTruncateExpr(Operand, Expr->getType());
789 }
790
792 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
793 return Operand == Expr->getOperand()
794 ? Expr
795 : SE.getZeroExtendExpr(Operand, Expr->getType());
796 }
797
799 const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
800 return Operand == Expr->getOperand()
801 ? Expr
802 : SE.getSignExtendExpr(Operand, Expr->getType());
803 }
804
805 const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
807 bool Changed = false;
808 for (const auto *Op : Expr->operands()) {
809 Operands.push_back(((SC *)this)->visit(Op));
810 Changed |= Op != Operands.back();
811 }
812 return !Changed ? Expr : SE.getAddExpr(Operands);
813 }
814
815 const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
817 bool Changed = false;
818 for (const auto *Op : Expr->operands()) {
819 Operands.push_back(((SC *)this)->visit(Op));
820 Changed |= Op != Operands.back();
821 }
822 return !Changed ? Expr : SE.getMulExpr(Operands);
823 }
824
825 const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
826 auto *LHS = ((SC *)this)->visit(Expr->getLHS());
827 auto *RHS = ((SC *)this)->visit(Expr->getRHS());
828 bool Changed = LHS != Expr->getLHS() || RHS != Expr->getRHS();
829 return !Changed ? Expr : SE.getUDivExpr(LHS, RHS);
830 }
831
832 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
834 bool Changed = false;
835 for (const auto *Op : Expr->operands()) {
836 Operands.push_back(((SC *)this)->visit(Op));
837 Changed |= Op != Operands.back();
838 }
839 return !Changed ? Expr
840 : SE.getAddRecExpr(Operands, Expr->getLoop(),
841 Expr->getNoWrapFlags());
842 }
843
844 const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
846 bool Changed = false;
847 for (const auto *Op : Expr->operands()) {
848 Operands.push_back(((SC *)this)->visit(Op));
849 Changed |= Op != Operands.back();
850 }
851 return !Changed ? Expr : SE.getSMaxExpr(Operands);
852 }
853
854 const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
856 bool Changed = false;
857 for (const auto *Op : Expr->operands()) {
858 Operands.push_back(((SC *)this)->visit(Op));
859 Changed |= Op != Operands.back();
860 }
861 return !Changed ? Expr : SE.getUMaxExpr(Operands);
862 }
863
864 const SCEV *visitSMinExpr(const SCEVSMinExpr *Expr) {
866 bool Changed = false;
867 for (const auto *Op : Expr->operands()) {
868 Operands.push_back(((SC *)this)->visit(Op));
869 Changed |= Op != Operands.back();
870 }
871 return !Changed ? Expr : SE.getSMinExpr(Operands);
872 }
873
874 const SCEV *visitUMinExpr(const SCEVUMinExpr *Expr) {
876 bool Changed = false;
877 for (const auto *Op : Expr->operands()) {
878 Operands.push_back(((SC *)this)->visit(Op));
879 Changed |= Op != Operands.back();
880 }
881 return !Changed ? Expr : SE.getUMinExpr(Operands);
882 }
883
886 bool Changed = false;
887 for (const auto *Op : Expr->operands()) {
888 Operands.push_back(((SC *)this)->visit(Op));
889 Changed |= Op != Operands.back();
890 }
891 return !Changed ? Expr : SE.getUMinExpr(Operands, /*Sequential=*/true);
892 }
893
894 const SCEV *visitUnknown(const SCEVUnknown *Expr) { return Expr; }
895
897 return Expr;
898 }
899};
900
903
904/// The SCEVParameterRewriter takes a scalar evolution expression and updates
905/// the SCEVUnknown components following the Map (Value -> SCEV).
906class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> {
907public:
908 static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
909 ValueToSCEVMapTy &Map) {
911 return Rewriter.visit(Scev);
912 }
913
916
917 const SCEV *visitUnknown(const SCEVUnknown *Expr) {
918 auto I = Map.find(Expr->getValue());
919 if (I == Map.end())
920 return Expr;
921 return I->second;
922 }
923
924private:
925 ValueToSCEVMapTy &Map;
926};
927
929
930/// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies
931/// the Map (Loop -> SCEV) to all AddRecExprs.
933 : public SCEVRewriteVisitor<SCEVLoopAddRecRewriter> {
934public:
937
938 static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
941 return Rewriter.visit(Scev);
942 }
943
944 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
946 for (const SCEV *Op : Expr->operands())
947 Operands.push_back(visit(Op));
948
949 const Loop *L = Expr->getLoop();
950 auto It = Map.find(L);
951 if (It == Map.end())
952 return SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
953
955 }
956
957private:
958 LoopToScevMapT &Map;
959};
960
961} // end namespace llvm
962
963#endif // LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:213
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
#define op(i)
#define I(x, y, z)
Definition MD5.cpp:58
mir Rename Register Operands
#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
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
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:154
This class represents a range of values.
This is an important base class in LLVM.
Definition Constant.h:43
FoldingSetNodeIDRef - This class describes a reference to an interned FoldingSetNodeID,...
Definition FoldingSet.h:293
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 const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
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:
const SCEV * getOperand(unsigned i) const
ArrayRef< const SCEV * > operands() const
const SCEV * getOperand() const
LLVM_ABI SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, const SCEV *op, Type *ty)
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
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.
SCEVCommutativeExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T, const SCEV *const *O, size_t N)
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, const SCEV *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 SCEV *const *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:
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask=NoWrapMask) const
SCEVNAryExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T, const SCEV *const *O, size_t N)
const SCEV * getOperand(unsigned i) const
ArrayRef< const SCEV * > operands() 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.
static bool classof(const SCEV *S)
Methods for support type inquiry through isa, cast, and dyn_cast:
const SCEV * visitSignExtendExpr(const SCEVSignExtendExpr *Expr)
const SCEV * visitPtrToIntExpr(const SCEVPtrToIntExpr *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:
SCEVSequentialMinMaxExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T, const SCEV *const *O, size_t N)
Note: Constructing subclasses via this constructor is allowed.
static SCEVTypes getEquivalentNonSequentialSCEVType(SCEVTypes Ty)
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< const SCEV * > operands() const
const SCEV * 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.
LLVM_ABI ArrayRef< const SCEV * > operands() const
Return operands of this SCEV expression.
SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, unsigned short ExpressionSize)
SCEVTypes getSCEVType() const
unsigned short SubclassData
This field is initialized to zero and may be used in subclasses to store miscellaneous information.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
NoWrapFlags
NoWrapFlags are bitfield indices into SubclassData.
The main scalar evolution driver.
LLVM_ABI const SCEV * getAddRecExpr(const SCEV *Start, const SCEV *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:45
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
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
DenseMap< const Loop *, const SCEV * > LoopToScevMapT
unsigned short computeExpressionSize(ArrayRef< const SCEV * > Args)
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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:1760
DenseMap< const Value *, Value * > ValueToValueMap
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.
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)