1 //===- LoopUnrollAnalyzer.cpp - Unrolling Effect Estimation -----*- 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 implements UnrolledInstAnalyzer class. It's used for predicting
10 // potential effects that loop unrolling might have, such as enabling constant
11 // propagation and other optimizations.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Analysis/LoopUnrollAnalyzer.h"
16 #include "llvm/Analysis/LoopInfo.h"
20 /// Try to simplify instruction \param I using its SCEV expression.
22 /// The idea is that some AddRec expressions become constants, which then
23 /// could trigger folding of other instructions. However, that only happens
24 /// for expressions whose start value is also constant, which isn't always the
25 /// case. In another common and important case the start value is just some
26 /// address (i.e. SCEVUnknown) - in this case we compute the offset and save
27 /// it along with the base address instead.
28 bool UnrolledInstAnalyzer::simplifyInstWithSCEV(Instruction
*I
) {
29 if (!SE
.isSCEVable(I
->getType()))
32 const SCEV
*S
= SE
.getSCEV(I
);
33 if (auto *SC
= dyn_cast
<SCEVConstant
>(S
)) {
34 SimplifiedValues
[I
] = SC
->getValue();
38 // If we have a loop invariant computation, we only need to compute it once.
39 // Given that, all but the first occurance are free.
40 if (!IterationNumber
->isZero() && SE
.isLoopInvariant(S
, L
))
43 auto *AR
= dyn_cast
<SCEVAddRecExpr
>(S
);
44 if (!AR
|| AR
->getLoop() != L
)
47 const SCEV
*ValueAtIteration
= AR
->evaluateAtIteration(IterationNumber
, SE
);
48 // Check if the AddRec expression becomes a constant.
49 if (auto *SC
= dyn_cast
<SCEVConstant
>(ValueAtIteration
)) {
50 SimplifiedValues
[I
] = SC
->getValue();
54 // Check if the offset from the base address becomes a constant.
55 auto *Base
= dyn_cast
<SCEVUnknown
>(SE
.getPointerBase(S
));
59 dyn_cast
<SCEVConstant
>(SE
.getMinusSCEV(ValueAtIteration
, Base
));
62 SimplifiedAddress Address
;
63 Address
.Base
= Base
->getValue();
64 Address
.Offset
= Offset
->getValue();
65 SimplifiedAddresses
[I
] = Address
;
69 /// Try to simplify binary operator I.
71 /// TODO: Probably it's worth to hoist the code for estimating the
72 /// simplifications effects to a separate class, since we have a very similar
73 /// code in InlineCost already.
74 bool UnrolledInstAnalyzer::visitBinaryOperator(BinaryOperator
&I
) {
75 Value
*LHS
= I
.getOperand(0), *RHS
= I
.getOperand(1);
76 if (!isa
<Constant
>(LHS
))
77 if (Value
*SimpleLHS
= SimplifiedValues
.lookup(LHS
))
79 if (!isa
<Constant
>(RHS
))
80 if (Value
*SimpleRHS
= SimplifiedValues
.lookup(RHS
))
83 Value
*SimpleV
= nullptr;
84 const DataLayout
&DL
= I
.getModule()->getDataLayout();
85 if (auto FI
= dyn_cast
<FPMathOperator
>(&I
))
87 SimplifyBinOp(I
.getOpcode(), LHS
, RHS
, FI
->getFastMathFlags(), DL
);
89 SimpleV
= SimplifyBinOp(I
.getOpcode(), LHS
, RHS
, DL
);
92 SimplifiedValues
[&I
] = SimpleV
;
95 return Base::visitBinaryOperator(I
);
98 /// Try to fold load I.
99 bool UnrolledInstAnalyzer::visitLoad(LoadInst
&I
) {
100 Value
*AddrOp
= I
.getPointerOperand();
102 auto AddressIt
= SimplifiedAddresses
.find(AddrOp
);
103 if (AddressIt
== SimplifiedAddresses
.end())
105 ConstantInt
*SimplifiedAddrOp
= AddressIt
->second
.Offset
;
107 auto *GV
= dyn_cast
<GlobalVariable
>(AddressIt
->second
.Base
);
108 // We're only interested in loads that can be completely folded to a
110 if (!GV
|| !GV
->hasDefinitiveInitializer() || !GV
->isConstant())
113 ConstantDataSequential
*CDS
=
114 dyn_cast
<ConstantDataSequential
>(GV
->getInitializer());
118 // We might have a vector load from an array. FIXME: for now we just bail
119 // out in this case, but we should be able to resolve and simplify such
121 if (CDS
->getElementType() != I
.getType())
124 unsigned ElemSize
= CDS
->getElementType()->getPrimitiveSizeInBits() / 8U;
125 if (SimplifiedAddrOp
->getValue().getActiveBits() > 64)
127 int64_t SimplifiedAddrOpV
= SimplifiedAddrOp
->getSExtValue();
128 if (SimplifiedAddrOpV
< 0) {
129 // FIXME: For now we conservatively ignore out of bound accesses, but
130 // we're allowed to perform the optimization in this case.
133 uint64_t Index
= static_cast<uint64_t>(SimplifiedAddrOpV
) / ElemSize
;
134 if (Index
>= CDS
->getNumElements()) {
135 // FIXME: For now we conservatively ignore out of bound accesses, but
136 // we're allowed to perform the optimization in this case.
140 Constant
*CV
= CDS
->getElementAsConstant(Index
);
141 assert(CV
&& "Constant expected.");
142 SimplifiedValues
[&I
] = CV
;
147 /// Try to simplify cast instruction.
148 bool UnrolledInstAnalyzer::visitCastInst(CastInst
&I
) {
149 Value
*Op
= I
.getOperand(0);
150 if (Value
*Simplified
= SimplifiedValues
.lookup(Op
))
153 // The cast can be invalid, because SimplifiedValues contains results of SCEV
154 // analysis, which operates on integers (and, e.g., might convert i8* null to
156 if (CastInst::castIsValid(I
.getOpcode(), Op
, I
.getType())) {
157 const DataLayout
&DL
= I
.getModule()->getDataLayout();
158 if (Value
*V
= SimplifyCastInst(I
.getOpcode(), Op
, I
.getType(), DL
)) {
159 SimplifiedValues
[&I
] = V
;
164 return Base::visitCastInst(I
);
167 /// Try to simplify cmp instruction.
168 bool UnrolledInstAnalyzer::visitCmpInst(CmpInst
&I
) {
169 Value
*LHS
= I
.getOperand(0), *RHS
= I
.getOperand(1);
171 // First try to handle simplified comparisons.
172 if (!isa
<Constant
>(LHS
))
173 if (Value
*SimpleLHS
= SimplifiedValues
.lookup(LHS
))
175 if (!isa
<Constant
>(RHS
))
176 if (Value
*SimpleRHS
= SimplifiedValues
.lookup(RHS
))
179 if (!isa
<Constant
>(LHS
) && !isa
<Constant
>(RHS
)) {
180 auto SimplifiedLHS
= SimplifiedAddresses
.find(LHS
);
181 if (SimplifiedLHS
!= SimplifiedAddresses
.end()) {
182 auto SimplifiedRHS
= SimplifiedAddresses
.find(RHS
);
183 if (SimplifiedRHS
!= SimplifiedAddresses
.end()) {
184 SimplifiedAddress
&LHSAddr
= SimplifiedLHS
->second
;
185 SimplifiedAddress
&RHSAddr
= SimplifiedRHS
->second
;
186 if (LHSAddr
.Base
== RHSAddr
.Base
) {
187 LHS
= LHSAddr
.Offset
;
188 RHS
= RHSAddr
.Offset
;
194 const DataLayout
&DL
= I
.getModule()->getDataLayout();
195 if (Value
*V
= SimplifyCmpInst(I
.getPredicate(), LHS
, RHS
, DL
)) {
196 SimplifiedValues
[&I
] = V
;
200 return Base::visitCmpInst(I
);
203 bool UnrolledInstAnalyzer::visitPHINode(PHINode
&PN
) {
204 // Run base visitor first. This way we can gather some useful for later
205 // analysis information.
206 if (Base::visitPHINode(PN
))
209 // The loop induction PHI nodes are definitionally free.
210 return PN
.getParent() == L
->getHeader();
213 bool UnrolledInstAnalyzer::visitInstruction(Instruction
&I
) {
214 return simplifyInstWithSCEV(&I
);