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