1 //===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the classes used to represent and build scalar expressions.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
14 #define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/FoldingSet.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/iterator_range.h"
21 #include "llvm/Analysis/ScalarEvolution.h"
22 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/Value.h"
24 #include "llvm/IR/ValueHandle.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/ErrorHandling.h"
39 // These should be ordered in terms of increasing complexity to make the
41 scConstant
, scTruncate
, scZeroExtend
, scSignExtend
, scAddExpr
, scMulExpr
,
42 scUDivExpr
, scAddRecExpr
, scUMaxExpr
, scSMaxExpr
,
43 scUnknown
, scCouldNotCompute
46 /// This class represents a constant integer value.
47 class SCEVConstant
: public SCEV
{
48 friend class ScalarEvolution
;
52 SCEVConstant(const FoldingSetNodeIDRef ID
, ConstantInt
*v
) :
53 SCEV(ID
, scConstant
, 1), V(v
) {}
56 ConstantInt
*getValue() const { return V
; }
57 const APInt
&getAPInt() const { return getValue()->getValue(); }
59 Type
*getType() const { return V
->getType(); }
61 /// Methods for support type inquiry through isa, cast, and dyn_cast:
62 static bool classof(const SCEV
*S
) {
63 return S
->getSCEVType() == scConstant
;
67 static unsigned short computeExpressionSize(ArrayRef
<const SCEV
*> Args
) {
69 for (auto *Arg
: Args
)
70 Size
= Size
.uadd_sat(APInt(16, Arg
->getExpressionSize()));
71 return (unsigned short)Size
.getZExtValue();
74 /// This is the base class for unary cast operator classes.
75 class SCEVCastExpr
: public SCEV
{
80 SCEVCastExpr(const FoldingSetNodeIDRef ID
,
81 unsigned SCEVTy
, const SCEV
*op
, Type
*ty
);
84 const SCEV
*getOperand() const { return Op
; }
85 Type
*getType() const { return Ty
; }
87 /// Methods for support type inquiry through isa, cast, and dyn_cast:
88 static bool classof(const SCEV
*S
) {
89 return S
->getSCEVType() == scTruncate
||
90 S
->getSCEVType() == scZeroExtend
||
91 S
->getSCEVType() == scSignExtend
;
95 /// This class represents a truncation of an integer value to a
96 /// smaller integer value.
97 class SCEVTruncateExpr
: public SCEVCastExpr
{
98 friend class ScalarEvolution
;
100 SCEVTruncateExpr(const FoldingSetNodeIDRef ID
,
101 const SCEV
*op
, Type
*ty
);
104 /// Methods for support type inquiry through isa, cast, and dyn_cast:
105 static bool classof(const SCEV
*S
) {
106 return S
->getSCEVType() == scTruncate
;
110 /// This class represents a zero extension of a small integer value
111 /// to a larger integer value.
112 class SCEVZeroExtendExpr
: public SCEVCastExpr
{
113 friend class ScalarEvolution
;
115 SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID
,
116 const SCEV
*op
, Type
*ty
);
119 /// Methods for support type inquiry through isa, cast, and dyn_cast:
120 static bool classof(const SCEV
*S
) {
121 return S
->getSCEVType() == scZeroExtend
;
125 /// This class represents a sign extension of a small integer value
126 /// to a larger integer value.
127 class SCEVSignExtendExpr
: public SCEVCastExpr
{
128 friend class ScalarEvolution
;
130 SCEVSignExtendExpr(const FoldingSetNodeIDRef ID
,
131 const SCEV
*op
, Type
*ty
);
134 /// Methods for support type inquiry through isa, cast, and dyn_cast:
135 static bool classof(const SCEV
*S
) {
136 return S
->getSCEVType() == scSignExtend
;
140 /// This node is a base class providing common functionality for
142 class SCEVNAryExpr
: public SCEV
{
144 // Since SCEVs are immutable, ScalarEvolution allocates operand
145 // arrays with its SCEVAllocator, so this class just needs a simple
146 // pointer rather than a more elaborate vector-like data structure.
147 // This also avoids the need for a non-trivial destructor.
148 const SCEV
*const *Operands
;
151 SCEVNAryExpr(const FoldingSetNodeIDRef ID
, enum SCEVTypes T
,
152 const SCEV
*const *O
, size_t N
)
153 : SCEV(ID
, T
, computeExpressionSize(makeArrayRef(O
, N
))), Operands(O
),
157 size_t getNumOperands() const { return NumOperands
; }
159 const SCEV
*getOperand(unsigned i
) const {
160 assert(i
< NumOperands
&& "Operand index out of range!");
164 using op_iterator
= const SCEV
*const *;
165 using op_range
= iterator_range
<op_iterator
>;
167 op_iterator
op_begin() const { return Operands
; }
168 op_iterator
op_end() const { return Operands
+ NumOperands
; }
169 op_range
operands() const {
170 return make_range(op_begin(), op_end());
173 Type
*getType() const { return getOperand(0)->getType(); }
175 NoWrapFlags
getNoWrapFlags(NoWrapFlags Mask
= NoWrapMask
) const {
176 return (NoWrapFlags
)(SubclassData
& Mask
);
179 bool hasNoUnsignedWrap() const {
180 return getNoWrapFlags(FlagNUW
) != FlagAnyWrap
;
183 bool hasNoSignedWrap() const {
184 return getNoWrapFlags(FlagNSW
) != FlagAnyWrap
;
187 bool hasNoSelfWrap() const {
188 return getNoWrapFlags(FlagNW
) != FlagAnyWrap
;
191 /// Methods for support type inquiry through isa, cast, and dyn_cast:
192 static bool classof(const SCEV
*S
) {
193 return S
->getSCEVType() == scAddExpr
||
194 S
->getSCEVType() == scMulExpr
||
195 S
->getSCEVType() == scSMaxExpr
||
196 S
->getSCEVType() == scUMaxExpr
||
197 S
->getSCEVType() == scAddRecExpr
;
201 /// This node is the base class for n'ary commutative operators.
202 class SCEVCommutativeExpr
: public SCEVNAryExpr
{
204 SCEVCommutativeExpr(const FoldingSetNodeIDRef ID
,
205 enum SCEVTypes T
, const SCEV
*const *O
, size_t N
)
206 : SCEVNAryExpr(ID
, T
, O
, N
) {}
209 /// Methods for support type inquiry through isa, cast, and dyn_cast:
210 static bool classof(const SCEV
*S
) {
211 return S
->getSCEVType() == scAddExpr
||
212 S
->getSCEVType() == scMulExpr
||
213 S
->getSCEVType() == scSMaxExpr
||
214 S
->getSCEVType() == scUMaxExpr
;
217 /// Set flags for a non-recurrence without clearing previously set flags.
218 void setNoWrapFlags(NoWrapFlags Flags
) {
219 SubclassData
|= Flags
;
223 /// This node represents an addition of some number of SCEVs.
224 class SCEVAddExpr
: public SCEVCommutativeExpr
{
225 friend class ScalarEvolution
;
227 SCEVAddExpr(const FoldingSetNodeIDRef ID
,
228 const SCEV
*const *O
, size_t N
)
229 : SCEVCommutativeExpr(ID
, scAddExpr
, O
, N
) {}
232 Type
*getType() const {
233 // Use the type of the last operand, which is likely to be a pointer
234 // type, if there is one. This doesn't usually matter, but it can help
235 // reduce casts when the expressions are expanded.
236 return getOperand(getNumOperands() - 1)->getType();
239 /// Methods for support type inquiry through isa, cast, and dyn_cast:
240 static bool classof(const SCEV
*S
) {
241 return S
->getSCEVType() == scAddExpr
;
245 /// This node represents multiplication of some number of SCEVs.
246 class SCEVMulExpr
: public SCEVCommutativeExpr
{
247 friend class ScalarEvolution
;
249 SCEVMulExpr(const FoldingSetNodeIDRef ID
,
250 const SCEV
*const *O
, size_t N
)
251 : SCEVCommutativeExpr(ID
, scMulExpr
, O
, N
) {}
254 /// Methods for support type inquiry through isa, cast, and dyn_cast:
255 static bool classof(const SCEV
*S
) {
256 return S
->getSCEVType() == scMulExpr
;
260 /// This class represents a binary unsigned division operation.
261 class SCEVUDivExpr
: public SCEV
{
262 friend class ScalarEvolution
;
267 SCEVUDivExpr(const FoldingSetNodeIDRef ID
, const SCEV
*lhs
, const SCEV
*rhs
)
268 : SCEV(ID
, scUDivExpr
, computeExpressionSize({lhs
, rhs
})), LHS(lhs
),
272 const SCEV
*getLHS() const { return LHS
; }
273 const SCEV
*getRHS() const { return RHS
; }
275 Type
*getType() const {
276 // In most cases the types of LHS and RHS will be the same, but in some
277 // crazy cases one or the other may be a pointer. ScalarEvolution doesn't
278 // depend on the type for correctness, but handling types carefully can
279 // avoid extra casts in the SCEVExpander. The LHS is more likely to be
280 // a pointer type than the RHS, so use the RHS' type here.
281 return getRHS()->getType();
284 /// Methods for support type inquiry through isa, cast, and dyn_cast:
285 static bool classof(const SCEV
*S
) {
286 return S
->getSCEVType() == scUDivExpr
;
290 /// This node represents a polynomial recurrence on the trip count
291 /// of the specified loop. This is the primary focus of the
292 /// ScalarEvolution framework; all the other SCEV subclasses are
293 /// mostly just supporting infrastructure to allow SCEVAddRecExpr
294 /// expressions to be created and analyzed.
296 /// All operands of an AddRec are required to be loop invariant.
298 class SCEVAddRecExpr
: public SCEVNAryExpr
{
299 friend class ScalarEvolution
;
303 SCEVAddRecExpr(const FoldingSetNodeIDRef ID
,
304 const SCEV
*const *O
, size_t N
, const Loop
*l
)
305 : SCEVNAryExpr(ID
, scAddRecExpr
, O
, N
), L(l
) {}
308 const SCEV
*getStart() const { return Operands
[0]; }
309 const Loop
*getLoop() const { return L
; }
311 /// Constructs and returns the recurrence indicating how much this
312 /// expression steps by. If this is a polynomial of degree N, it
313 /// returns a chrec of degree N-1. We cannot determine whether
314 /// the step recurrence has self-wraparound.
315 const SCEV
*getStepRecurrence(ScalarEvolution
&SE
) const {
316 if (isAffine()) return getOperand(1);
317 return SE
.getAddRecExpr(SmallVector
<const SCEV
*, 3>(op_begin()+1,
319 getLoop(), FlagAnyWrap
);
322 /// Return true if this represents an expression A + B*x where A
323 /// and B are loop invariant values.
324 bool isAffine() const {
325 // We know that the start value is invariant. This expression is thus
326 // affine iff the step is also invariant.
327 return getNumOperands() == 2;
330 /// Return true if this represents an expression A + B*x + C*x^2
331 /// where A, B and C are loop invariant values. This corresponds
332 /// to an addrec of the form {L,+,M,+,N}
333 bool isQuadratic() const {
334 return getNumOperands() == 3;
337 /// Set flags for a recurrence without clearing any previously set flags.
338 /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
339 /// to make it easier to propagate flags.
340 void setNoWrapFlags(NoWrapFlags Flags
) {
341 if (Flags
& (FlagNUW
| FlagNSW
))
342 Flags
= ScalarEvolution::setFlags(Flags
, FlagNW
);
343 SubclassData
|= Flags
;
346 /// Return the value of this chain of recurrences at the specified
347 /// iteration number.
348 const SCEV
*evaluateAtIteration(const SCEV
*It
, ScalarEvolution
&SE
) const;
350 /// Return the number of iterations of this loop that produce
351 /// values in the specified constant range. Another way of
352 /// looking at this is that it returns the first iteration number
353 /// where the value is not in the condition, thus computing the
354 /// exit count. If the iteration count can't be computed, an
355 /// instance of SCEVCouldNotCompute is returned.
356 const SCEV
*getNumIterationsInRange(const ConstantRange
&Range
,
357 ScalarEvolution
&SE
) const;
359 /// Return an expression representing the value of this expression
360 /// one iteration of the loop ahead.
361 const SCEVAddRecExpr
*getPostIncExpr(ScalarEvolution
&SE
) const;
363 /// Methods for support type inquiry through isa, cast, and dyn_cast:
364 static bool classof(const SCEV
*S
) {
365 return S
->getSCEVType() == scAddRecExpr
;
369 /// This class represents a signed maximum selection.
370 class SCEVSMaxExpr
: public SCEVCommutativeExpr
{
371 friend class ScalarEvolution
;
373 SCEVSMaxExpr(const FoldingSetNodeIDRef ID
,
374 const SCEV
*const *O
, size_t N
)
375 : SCEVCommutativeExpr(ID
, scSMaxExpr
, O
, N
) {
376 // Max never overflows.
377 setNoWrapFlags((NoWrapFlags
)(FlagNUW
| FlagNSW
));
381 /// Methods for support type inquiry through isa, cast, and dyn_cast:
382 static bool classof(const SCEV
*S
) {
383 return S
->getSCEVType() == scSMaxExpr
;
387 /// This class represents an unsigned maximum selection.
388 class SCEVUMaxExpr
: public SCEVCommutativeExpr
{
389 friend class ScalarEvolution
;
391 SCEVUMaxExpr(const FoldingSetNodeIDRef ID
,
392 const SCEV
*const *O
, size_t N
)
393 : SCEVCommutativeExpr(ID
, scUMaxExpr
, O
, N
) {
394 // Max never overflows.
395 setNoWrapFlags((NoWrapFlags
)(FlagNUW
| FlagNSW
));
399 /// Methods for support type inquiry through isa, cast, and dyn_cast:
400 static bool classof(const SCEV
*S
) {
401 return S
->getSCEVType() == scUMaxExpr
;
405 /// This means that we are dealing with an entirely unknown SCEV
406 /// value, and only represent it as its LLVM Value. This is the
407 /// "bottom" value for the analysis.
408 class SCEVUnknown final
: public SCEV
, private CallbackVH
{
409 friend class ScalarEvolution
;
411 /// The parent ScalarEvolution value. This is used to update the
412 /// parent's maps when the value associated with a SCEVUnknown is
413 /// deleted or RAUW'd.
416 /// The next pointer in the linked list of all SCEVUnknown
417 /// instances owned by a ScalarEvolution.
420 SCEVUnknown(const FoldingSetNodeIDRef ID
, Value
*V
,
421 ScalarEvolution
*se
, SCEVUnknown
*next
) :
422 SCEV(ID
, scUnknown
, 1), CallbackVH(V
), SE(se
), Next(next
) {}
424 // Implement CallbackVH.
425 void deleted() override
;
426 void allUsesReplacedWith(Value
*New
) override
;
429 Value
*getValue() const { return getValPtr(); }
432 /// Test whether this is a special constant representing a type
433 /// size, alignment, or field offset in a target-independent
434 /// manner, and hasn't happened to have been folded with other
435 /// operations into something unrecognizable. This is mainly only
436 /// useful for pretty-printing and other situations where it isn't
437 /// absolutely required for these to succeed.
438 bool isSizeOf(Type
*&AllocTy
) const;
439 bool isAlignOf(Type
*&AllocTy
) const;
440 bool isOffsetOf(Type
*&STy
, Constant
*&FieldNo
) const;
443 Type
*getType() const { return getValPtr()->getType(); }
445 /// Methods for support type inquiry through isa, cast, and dyn_cast:
446 static bool classof(const SCEV
*S
) {
447 return S
->getSCEVType() == scUnknown
;
451 /// This class defines a simple visitor class that may be used for
452 /// various SCEV analysis purposes.
453 template<typename SC
, typename RetVal
=void>
455 RetVal
visit(const SCEV
*S
) {
456 switch (S
->getSCEVType()) {
458 return ((SC
*)this)->visitConstant((const SCEVConstant
*)S
);
460 return ((SC
*)this)->visitTruncateExpr((const SCEVTruncateExpr
*)S
);
462 return ((SC
*)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr
*)S
);
464 return ((SC
*)this)->visitSignExtendExpr((const SCEVSignExtendExpr
*)S
);
466 return ((SC
*)this)->visitAddExpr((const SCEVAddExpr
*)S
);
468 return ((SC
*)this)->visitMulExpr((const SCEVMulExpr
*)S
);
470 return ((SC
*)this)->visitUDivExpr((const SCEVUDivExpr
*)S
);
472 return ((SC
*)this)->visitAddRecExpr((const SCEVAddRecExpr
*)S
);
474 return ((SC
*)this)->visitSMaxExpr((const SCEVSMaxExpr
*)S
);
476 return ((SC
*)this)->visitUMaxExpr((const SCEVUMaxExpr
*)S
);
478 return ((SC
*)this)->visitUnknown((const SCEVUnknown
*)S
);
479 case scCouldNotCompute
:
480 return ((SC
*)this)->visitCouldNotCompute((const SCEVCouldNotCompute
*)S
);
482 llvm_unreachable("Unknown SCEV type!");
486 RetVal
visitCouldNotCompute(const SCEVCouldNotCompute
*S
) {
487 llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
491 /// Visit all nodes in the expression tree using worklist traversal.
493 /// Visitor implements:
494 /// // return true to follow this node.
495 /// bool follow(const SCEV *S);
496 /// // return true to terminate the search.
498 template<typename SV
>
499 class SCEVTraversal
{
501 SmallVector
<const SCEV
*, 8> Worklist
;
502 SmallPtrSet
<const SCEV
*, 8> Visited
;
504 void push(const SCEV
*S
) {
505 if (Visited
.insert(S
).second
&& Visitor
.follow(S
))
506 Worklist
.push_back(S
);
510 SCEVTraversal(SV
& V
): Visitor(V
) {}
512 void visitAll(const SCEV
*Root
) {
514 while (!Worklist
.empty() && !Visitor
.isDone()) {
515 const SCEV
*S
= Worklist
.pop_back_val();
517 switch (S
->getSCEVType()) {
524 push(cast
<SCEVCastExpr
>(S
)->getOperand());
531 for (const auto *Op
: cast
<SCEVNAryExpr
>(S
)->operands())
535 const SCEVUDivExpr
*UDiv
= cast
<SCEVUDivExpr
>(S
);
536 push(UDiv
->getLHS());
537 push(UDiv
->getRHS());
540 case scCouldNotCompute
:
541 llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
543 llvm_unreachable("Unknown SCEV kind!");
549 /// Use SCEVTraversal to visit all nodes in the given expression tree.
550 template<typename SV
>
551 void visitAll(const SCEV
*Root
, SV
& Visitor
) {
552 SCEVTraversal
<SV
> T(Visitor
);
556 /// Return true if any node in \p Root satisfies the predicate \p Pred.
557 template <typename PredTy
>
558 bool SCEVExprContains(const SCEV
*Root
, PredTy Pred
) {
563 FindClosure(PredTy Pred
) : Pred(Pred
) {}
565 bool follow(const SCEV
*S
) {
573 bool isDone() const { return Found
; }
576 FindClosure
FC(Pred
);
581 /// This visitor recursively visits a SCEV expression and re-writes it.
582 /// The result from each visit is cached, so it will return the same
583 /// SCEV for the same input.
584 template<typename SC
>
585 class SCEVRewriteVisitor
: public SCEVVisitor
<SC
, const SCEV
*> {
588 // Memoize the result of each visit so that we only compute once for
589 // the same input SCEV. This is to avoid redundant computations when
590 // a SCEV is referenced by multiple SCEVs. Without memoization, this
591 // visit algorithm would have exponential time complexity in the worst
592 // case, causing the compiler to hang on certain tests.
593 DenseMap
<const SCEV
*, const SCEV
*> RewriteResults
;
596 SCEVRewriteVisitor(ScalarEvolution
&SE
) : SE(SE
) {}
598 const SCEV
*visit(const SCEV
*S
) {
599 auto It
= RewriteResults
.find(S
);
600 if (It
!= RewriteResults
.end())
602 auto* Visited
= SCEVVisitor
<SC
, const SCEV
*>::visit(S
);
603 auto Result
= RewriteResults
.try_emplace(S
, Visited
);
604 assert(Result
.second
&& "Should insert a new entry");
605 return Result
.first
->second
;
608 const SCEV
*visitConstant(const SCEVConstant
*Constant
) {
612 const SCEV
*visitTruncateExpr(const SCEVTruncateExpr
*Expr
) {
613 const SCEV
*Operand
= ((SC
*)this)->visit(Expr
->getOperand());
614 return Operand
== Expr
->getOperand()
616 : SE
.getTruncateExpr(Operand
, Expr
->getType());
619 const SCEV
*visitZeroExtendExpr(const SCEVZeroExtendExpr
*Expr
) {
620 const SCEV
*Operand
= ((SC
*)this)->visit(Expr
->getOperand());
621 return Operand
== Expr
->getOperand()
623 : SE
.getZeroExtendExpr(Operand
, Expr
->getType());
626 const SCEV
*visitSignExtendExpr(const SCEVSignExtendExpr
*Expr
) {
627 const SCEV
*Operand
= ((SC
*)this)->visit(Expr
->getOperand());
628 return Operand
== Expr
->getOperand()
630 : SE
.getSignExtendExpr(Operand
, Expr
->getType());
633 const SCEV
*visitAddExpr(const SCEVAddExpr
*Expr
) {
634 SmallVector
<const SCEV
*, 2> Operands
;
635 bool Changed
= false;
636 for (auto *Op
: Expr
->operands()) {
637 Operands
.push_back(((SC
*)this)->visit(Op
));
638 Changed
|= Op
!= Operands
.back();
640 return !Changed
? Expr
: SE
.getAddExpr(Operands
);
643 const SCEV
*visitMulExpr(const SCEVMulExpr
*Expr
) {
644 SmallVector
<const SCEV
*, 2> Operands
;
645 bool Changed
= false;
646 for (auto *Op
: Expr
->operands()) {
647 Operands
.push_back(((SC
*)this)->visit(Op
));
648 Changed
|= Op
!= Operands
.back();
650 return !Changed
? Expr
: SE
.getMulExpr(Operands
);
653 const SCEV
*visitUDivExpr(const SCEVUDivExpr
*Expr
) {
654 auto *LHS
= ((SC
*)this)->visit(Expr
->getLHS());
655 auto *RHS
= ((SC
*)this)->visit(Expr
->getRHS());
656 bool Changed
= LHS
!= Expr
->getLHS() || RHS
!= Expr
->getRHS();
657 return !Changed
? Expr
: SE
.getUDivExpr(LHS
, RHS
);
660 const SCEV
*visitAddRecExpr(const SCEVAddRecExpr
*Expr
) {
661 SmallVector
<const SCEV
*, 2> Operands
;
662 bool Changed
= false;
663 for (auto *Op
: Expr
->operands()) {
664 Operands
.push_back(((SC
*)this)->visit(Op
));
665 Changed
|= Op
!= Operands
.back();
667 return !Changed
? Expr
668 : SE
.getAddRecExpr(Operands
, Expr
->getLoop(),
669 Expr
->getNoWrapFlags());
672 const SCEV
*visitSMaxExpr(const SCEVSMaxExpr
*Expr
) {
673 SmallVector
<const SCEV
*, 2> Operands
;
674 bool Changed
= false;
675 for (auto *Op
: Expr
->operands()) {
676 Operands
.push_back(((SC
*)this)->visit(Op
));
677 Changed
|= Op
!= Operands
.back();
679 return !Changed
? Expr
: SE
.getSMaxExpr(Operands
);
682 const SCEV
*visitUMaxExpr(const SCEVUMaxExpr
*Expr
) {
683 SmallVector
<const SCEV
*, 2> Operands
;
684 bool Changed
= false;
685 for (auto *Op
: Expr
->operands()) {
686 Operands
.push_back(((SC
*)this)->visit(Op
));
687 Changed
|= Op
!= Operands
.back();
689 return !Changed
? Expr
: SE
.getUMaxExpr(Operands
);
692 const SCEV
*visitUnknown(const SCEVUnknown
*Expr
) {
696 const SCEV
*visitCouldNotCompute(const SCEVCouldNotCompute
*Expr
) {
701 using ValueToValueMap
= DenseMap
<const Value
*, Value
*>;
703 /// The SCEVParameterRewriter takes a scalar evolution expression and updates
704 /// the SCEVUnknown components following the Map (Value -> Value).
705 class SCEVParameterRewriter
: public SCEVRewriteVisitor
<SCEVParameterRewriter
> {
707 static const SCEV
*rewrite(const SCEV
*Scev
, ScalarEvolution
&SE
,
708 ValueToValueMap
&Map
,
709 bool InterpretConsts
= false) {
710 SCEVParameterRewriter
Rewriter(SE
, Map
, InterpretConsts
);
711 return Rewriter
.visit(Scev
);
714 SCEVParameterRewriter(ScalarEvolution
&SE
, ValueToValueMap
&M
, bool C
)
715 : SCEVRewriteVisitor(SE
), Map(M
), InterpretConsts(C
) {}
717 const SCEV
*visitUnknown(const SCEVUnknown
*Expr
) {
718 Value
*V
= Expr
->getValue();
721 if (InterpretConsts
&& isa
<ConstantInt
>(NV
))
722 return SE
.getConstant(cast
<ConstantInt
>(NV
));
723 return SE
.getUnknown(NV
);
729 ValueToValueMap
&Map
;
730 bool InterpretConsts
;
733 using LoopToScevMapT
= DenseMap
<const Loop
*, const SCEV
*>;
735 /// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies
736 /// the Map (Loop -> SCEV) to all AddRecExprs.
737 class SCEVLoopAddRecRewriter
738 : public SCEVRewriteVisitor
<SCEVLoopAddRecRewriter
> {
740 SCEVLoopAddRecRewriter(ScalarEvolution
&SE
, LoopToScevMapT
&M
)
741 : SCEVRewriteVisitor(SE
), Map(M
) {}
743 static const SCEV
*rewrite(const SCEV
*Scev
, LoopToScevMapT
&Map
,
744 ScalarEvolution
&SE
) {
745 SCEVLoopAddRecRewriter
Rewriter(SE
, Map
);
746 return Rewriter
.visit(Scev
);
749 const SCEV
*visitAddRecExpr(const SCEVAddRecExpr
*Expr
) {
750 SmallVector
<const SCEV
*, 2> Operands
;
751 for (const SCEV
*Op
: Expr
->operands())
752 Operands
.push_back(visit(Op
));
754 const Loop
*L
= Expr
->getLoop();
755 const SCEV
*Res
= SE
.getAddRecExpr(Operands
, L
, Expr
->getNoWrapFlags());
757 if (0 == Map
.count(L
))
760 const SCEVAddRecExpr
*Rec
= cast
<SCEVAddRecExpr
>(Res
);
761 return Rec
->evaluateAtIteration(Map
[L
], SE
);
768 } // end namespace llvm
770 #endif // LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H