1 //===- ScalarEvolutionNormalization.cpp - See below -------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements utilities for working with "normalized" expressions.
11 // See the comments at the top of ScalarEvolutionNormalization.h for details.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Analysis/Dominators.h"
16 #include "llvm/Analysis/LoopInfo.h"
17 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
18 #include "llvm/Analysis/ScalarEvolutionNormalization.h"
21 /// IVUseShouldUsePostIncValue - We have discovered a "User" of an IV expression
22 /// and now we need to decide whether the user should use the preinc or post-inc
23 /// value. If this user should use the post-inc version of the IV, return true.
25 /// Choosing wrong here can break dominance properties (if we choose to use the
26 /// post-inc value when we cannot) or it can end up adding extra live-ranges to
27 /// the loop, resulting in reg-reg copies (if we use the pre-inc value when we
28 /// should use the post-inc value).
29 static bool IVUseShouldUsePostIncValue(Instruction
*User
, Value
*Operand
,
30 const Loop
*L
, DominatorTree
*DT
) {
31 // If the user is in the loop, use the preinc value.
32 if (L
->contains(User
)) return false;
34 BasicBlock
*LatchBlock
= L
->getLoopLatch();
38 // Ok, the user is outside of the loop. If it is dominated by the latch
39 // block, use the post-inc value.
40 if (DT
->dominates(LatchBlock
, User
->getParent()))
43 // There is one case we have to be careful of: PHI nodes. These little guys
44 // can live in blocks that are not dominated by the latch block, but (since
45 // their uses occur in the predecessor block, not the block the PHI lives in)
46 // should still use the post-inc value. Check for this case now.
47 PHINode
*PN
= dyn_cast
<PHINode
>(User
);
48 if (!PN
|| !Operand
) return false; // not a phi, not dominated by latch block.
50 // Look at all of the uses of Operand by the PHI node. If any use corresponds
51 // to a block that is not dominated by the latch block, give up and use the
52 // preincremented value.
53 for (unsigned i
= 0, e
= PN
->getNumIncomingValues(); i
!= e
; ++i
)
54 if (PN
->getIncomingValue(i
) == Operand
&&
55 !DT
->dominates(LatchBlock
, PN
->getIncomingBlock(i
)))
58 // Okay, all uses of Operand by PN are in predecessor blocks that really are
59 // dominated by the latch block. Use the post-incremented value.
63 const SCEV
*llvm::TransformForPostIncUse(TransformKind Kind
,
66 Value
*OperandValToReplace
,
67 PostIncLoopSet
&Loops
,
70 if (isa
<SCEVConstant
>(S
) || isa
<SCEVUnknown
>(S
))
73 if (const SCEVCastExpr
*X
= dyn_cast
<SCEVCastExpr
>(S
)) {
74 const SCEV
*O
= X
->getOperand();
75 const SCEV
*N
= TransformForPostIncUse(Kind
, O
, User
, OperandValToReplace
,
78 switch (S
->getSCEVType()) {
79 case scZeroExtend
: return SE
.getZeroExtendExpr(N
, S
->getType());
80 case scSignExtend
: return SE
.getSignExtendExpr(N
, S
->getType());
81 case scTruncate
: return SE
.getTruncateExpr(N
, S
->getType());
82 default: llvm_unreachable("Unexpected SCEVCastExpr kind!");
87 if (const SCEVAddRecExpr
*AR
= dyn_cast
<SCEVAddRecExpr
>(S
)) {
88 // An addrec. This is the interesting part.
89 SmallVector
<const SCEV
*, 8> Operands
;
90 const Loop
*L
= AR
->getLoop();
91 // The addrec conceptually uses its operands at loop entry.
92 Instruction
*LUser
= L
->getHeader()->begin();
93 // Transform each operand.
94 for (SCEVNAryExpr::op_iterator I
= AR
->op_begin(), E
= AR
->op_end();
97 const SCEV
*N
= TransformForPostIncUse(Kind
, O
, LUser
, 0, Loops
, SE
, DT
);
98 Operands
.push_back(N
);
100 // Conservatively use AnyWrap until/unless we need FlagNW.
101 const SCEV
*Result
= SE
.getAddRecExpr(Operands
, L
, SCEV::FlagAnyWrap
);
103 default: llvm_unreachable("Unexpected transform name!");
104 case NormalizeAutodetect
:
105 if (IVUseShouldUsePostIncValue(User
, OperandValToReplace
, L
, &DT
)) {
106 const SCEV
*TransformedStep
=
107 TransformForPostIncUse(Kind
, AR
->getStepRecurrence(SE
),
108 User
, OperandValToReplace
, Loops
, SE
, DT
);
109 Result
= SE
.getMinusSCEV(Result
, TransformedStep
);
113 // This assert is conceptually correct, but ScalarEvolution currently
114 // sometimes fails to canonicalize two equal SCEVs to exactly the same
115 // form. It's possibly a pessimization when this happens, but it isn't a
116 // correctness problem, so disable this assert for now.
117 assert(S
== TransformForPostIncUse(Denormalize
, Result
,
118 User
, OperandValToReplace
,
120 "SCEV normalization is not invertible!");
124 if (Loops
.count(L
)) {
125 const SCEV
*TransformedStep
=
126 TransformForPostIncUse(Kind
, AR
->getStepRecurrence(SE
),
127 User
, OperandValToReplace
, Loops
, SE
, DT
);
128 Result
= SE
.getMinusSCEV(Result
, TransformedStep
);
131 // See the comment on the assert above.
132 assert(S
== TransformForPostIncUse(Denormalize
, Result
,
133 User
, OperandValToReplace
,
135 "SCEV normalization is not invertible!");
140 Result
= cast
<SCEVAddRecExpr
>(Result
)->getPostIncExpr(SE
);
146 if (const SCEVNAryExpr
*X
= dyn_cast
<SCEVNAryExpr
>(S
)) {
147 SmallVector
<const SCEV
*, 8> Operands
;
148 bool Changed
= false;
149 // Transform each operand.
150 for (SCEVNAryExpr::op_iterator I
= X
->op_begin(), E
= X
->op_end();
153 const SCEV
*N
= TransformForPostIncUse(Kind
, O
, User
, OperandValToReplace
,
156 Operands
.push_back(N
);
158 // If any operand actually changed, return a transformed result.
160 switch (S
->getSCEVType()) {
161 case scAddExpr
: return SE
.getAddExpr(Operands
);
162 case scMulExpr
: return SE
.getMulExpr(Operands
);
163 case scSMaxExpr
: return SE
.getSMaxExpr(Operands
);
164 case scUMaxExpr
: return SE
.getUMaxExpr(Operands
);
165 default: llvm_unreachable("Unexpected SCEVNAryExpr kind!");
170 if (const SCEVUDivExpr
*X
= dyn_cast
<SCEVUDivExpr
>(S
)) {
171 const SCEV
*LO
= X
->getLHS();
172 const SCEV
*RO
= X
->getRHS();
173 const SCEV
*LN
= TransformForPostIncUse(Kind
, LO
, User
, OperandValToReplace
,
175 const SCEV
*RN
= TransformForPostIncUse(Kind
, RO
, User
, OperandValToReplace
,
177 if (LO
!= LN
|| RO
!= RN
)
178 return SE
.getUDivExpr(LN
, RN
);
182 llvm_unreachable("Unexpected SCEV kind!");