1 //===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- 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 is the interface for LLVM's primary stateless and local alias analysis.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_ANALYSIS_BASICALIASANALYSIS_H
14 #define LLVM_ANALYSIS_BASICALIASANALYSIS_H
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/Analysis/AliasAnalysis.h"
21 #include "llvm/Analysis/AssumptionCache.h"
22 #include "llvm/Analysis/MemoryLocation.h"
23 #include "llvm/IR/InstrTypes.h"
24 #include "llvm/IR/PassManager.h"
25 #include "llvm/Pass.h"
35 class AssumptionCache
;
44 class TargetLibraryInfo
;
48 /// This is the AA result object for the basic, local, and stateless alias
49 /// analysis. It implements the AA query interface in an entirely stateless
50 /// manner. As one consequence, it is never invalidated due to IR changes.
51 /// While it does retain some storage, that is used as an optimization and not
52 /// to preserve information from query to query. However it does retain handles
53 /// to various other analyses and must be recomputed when those analyses are.
54 class BasicAAResult
: public AAResultBase
<BasicAAResult
> {
55 friend AAResultBase
<BasicAAResult
>;
59 const TargetLibraryInfo
&TLI
;
66 BasicAAResult(const DataLayout
&DL
, const Function
&F
,
67 const TargetLibraryInfo
&TLI
, AssumptionCache
&AC
,
68 DominatorTree
*DT
= nullptr, LoopInfo
*LI
= nullptr,
69 PhiValues
*PV
= nullptr)
70 : AAResultBase(), DL(DL
), F(F
), TLI(TLI
), AC(AC
), DT(DT
), LI(LI
), PV(PV
)
73 BasicAAResult(const BasicAAResult
&Arg
)
74 : AAResultBase(Arg
), DL(Arg
.DL
), F(Arg
.F
), TLI(Arg
.TLI
), AC(Arg
.AC
),
75 DT(Arg
.DT
), LI(Arg
.LI
), PV(Arg
.PV
) {}
76 BasicAAResult(BasicAAResult
&&Arg
)
77 : AAResultBase(std::move(Arg
)), DL(Arg
.DL
), F(Arg
.F
), TLI(Arg
.TLI
),
78 AC(Arg
.AC
), DT(Arg
.DT
), LI(Arg
.LI
), PV(Arg
.PV
) {}
80 /// Handle invalidation events in the new pass manager.
81 bool invalidate(Function
&Fn
, const PreservedAnalyses
&PA
,
82 FunctionAnalysisManager::Invalidator
&Inv
);
84 AliasResult
alias(const MemoryLocation
&LocA
, const MemoryLocation
&LocB
,
87 ModRefInfo
getModRefInfo(const CallBase
*Call
, const MemoryLocation
&Loc
,
90 ModRefInfo
getModRefInfo(const CallBase
*Call1
, const CallBase
*Call2
,
93 /// Chases pointers until we find a (constant global) or not.
94 bool pointsToConstantMemory(const MemoryLocation
&Loc
, AAQueryInfo
&AAQI
,
97 /// Get the location associated with a pointer argument of a callsite.
98 ModRefInfo
getArgModRefInfo(const CallBase
*Call
, unsigned ArgIdx
);
100 /// Returns the behavior when calling the given call site.
101 FunctionModRefBehavior
getModRefBehavior(const CallBase
*Call
);
103 /// Returns the behavior when calling the given function. For use when the
104 /// call site is not known.
105 FunctionModRefBehavior
getModRefBehavior(const Function
*Fn
);
108 // A linear transformation of a Value; this class represents ZExt(SExt(V,
109 // SExtBits), ZExtBits) * Scale + Offset.
110 struct VariableGEPIndex
{
111 // An opaque Value - we can't decompose this further.
114 // We need to track what extensions we've done as we consider the same Value
115 // with different extensions as different variables in a GEP's linear
117 // e.g.: if V == -1, then sext(x) != zext(x).
123 bool operator==(const VariableGEPIndex
&Other
) const {
124 return V
== Other
.V
&& ZExtBits
== Other
.ZExtBits
&&
125 SExtBits
== Other
.SExtBits
&& Scale
== Other
.Scale
;
128 bool operator!=(const VariableGEPIndex
&Other
) const {
129 return !operator==(Other
);
133 // Represents the internal structure of a GEP, decomposed into a base pointer,
134 // constant offsets, and variable scaled indices.
135 struct DecomposedGEP
{
136 // Base pointer of the GEP
138 // Total constant offset w.r.t the base from indexing into structs
140 // Total constant offset w.r.t the base from indexing through
141 // pointers/arrays/vectors
143 // Scaled variable (non-constant) indices.
144 SmallVector
<VariableGEPIndex
, 4> VarIndices
;
147 /// Tracks phi nodes we have visited.
149 /// When interpret "Value" pointer equality as value equality we need to make
150 /// sure that the "Value" is not part of a cycle. Otherwise, two uses could
151 /// come from different "iterations" of a cycle and see different values for
152 /// the same "Value" pointer.
154 /// The following example shows the problem:
155 /// %p = phi(%alloca1, %addr2)
157 /// %addr1 = gep, %alloca2, 0, %l
158 /// %addr2 = gep %alloca2, 0, (%l + 1)
159 /// alias(%p, %addr1) -> MayAlias !
161 SmallPtrSet
<const BasicBlock
*, 8> VisitedPhiBBs
;
163 /// Tracks instructions visited by pointsToConstantMemory.
164 SmallPtrSet
<const Value
*, 16> Visited
;
167 GetLinearExpression(const Value
*V
, APInt
&Scale
, APInt
&Offset
,
168 unsigned &ZExtBits
, unsigned &SExtBits
,
169 const DataLayout
&DL
, unsigned Depth
, AssumptionCache
*AC
,
170 DominatorTree
*DT
, bool &NSW
, bool &NUW
);
172 static bool DecomposeGEPExpression(const Value
*V
, DecomposedGEP
&Decomposed
,
173 const DataLayout
&DL
, AssumptionCache
*AC
, DominatorTree
*DT
);
175 static bool isGEPBaseAtNegativeOffset(const GEPOperator
*GEPOp
,
176 const DecomposedGEP
&DecompGEP
, const DecomposedGEP
&DecompObject
,
177 LocationSize ObjectAccessSize
);
179 /// A Heuristic for aliasGEP that searches for a constant offset
180 /// between the variables.
182 /// GetLinearExpression has some limitations, as generally zext(%x + 1)
183 /// != zext(%x) + zext(1) if the arithmetic overflows. GetLinearExpression
184 /// will therefore conservatively refuse to decompose these expressions.
185 /// However, we know that, for all %x, zext(%x) != zext(%x + 1), even if
186 /// the addition overflows.
188 constantOffsetHeuristic(const SmallVectorImpl
<VariableGEPIndex
> &VarIndices
,
189 LocationSize V1Size
, LocationSize V2Size
,
190 APInt BaseOffset
, AssumptionCache
*AC
,
193 bool isValueEqualInPotentialCycles(const Value
*V1
, const Value
*V2
);
195 void GetIndexDifference(SmallVectorImpl
<VariableGEPIndex
> &Dest
,
196 const SmallVectorImpl
<VariableGEPIndex
> &Src
);
198 AliasResult
aliasGEP(const GEPOperator
*V1
, LocationSize V1Size
,
199 const AAMDNodes
&V1AAInfo
, const Value
*V2
,
200 LocationSize V2Size
, const AAMDNodes
&V2AAInfo
,
201 const Value
*UnderlyingV1
, const Value
*UnderlyingV2
,
204 AliasResult
aliasPHI(const PHINode
*PN
, LocationSize PNSize
,
205 const AAMDNodes
&PNAAInfo
, const Value
*V2
,
206 LocationSize V2Size
, const AAMDNodes
&V2AAInfo
,
207 const Value
*UnderV2
, AAQueryInfo
&AAQI
);
209 AliasResult
aliasSelect(const SelectInst
*SI
, LocationSize SISize
,
210 const AAMDNodes
&SIAAInfo
, const Value
*V2
,
211 LocationSize V2Size
, const AAMDNodes
&V2AAInfo
,
212 const Value
*UnderV2
, AAQueryInfo
&AAQI
);
214 AliasResult
aliasCheck(const Value
*V1
, LocationSize V1Size
,
215 AAMDNodes V1AATag
, const Value
*V2
,
216 LocationSize V2Size
, AAMDNodes V2AATag
,
217 AAQueryInfo
&AAQI
, const Value
*O1
= nullptr,
218 const Value
*O2
= nullptr);
221 /// Analysis pass providing a never-invalidated alias analysis result.
222 class BasicAA
: public AnalysisInfoMixin
<BasicAA
> {
223 friend AnalysisInfoMixin
<BasicAA
>;
225 static AnalysisKey Key
;
228 using Result
= BasicAAResult
;
230 BasicAAResult
run(Function
&F
, FunctionAnalysisManager
&AM
);
233 /// Legacy wrapper pass to provide the BasicAAResult object.
234 class BasicAAWrapperPass
: public FunctionPass
{
235 std::unique_ptr
<BasicAAResult
> Result
;
237 virtual void anchor();
242 BasicAAWrapperPass();
244 BasicAAResult
&getResult() { return *Result
; }
245 const BasicAAResult
&getResult() const { return *Result
; }
247 bool runOnFunction(Function
&F
) override
;
248 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
251 FunctionPass
*createBasicAAWrapperPass();
253 /// A helper for the legacy pass manager to create a \c BasicAAResult object
254 /// populated to the best of our ability for a particular function when inside
255 /// of a \c ModulePass or a \c CallGraphSCCPass.
256 BasicAAResult
createLegacyPMBasicAAResult(Pass
&P
, Function
&F
);
258 /// This class is a functor to be used in legacy module or SCC passes for
259 /// computing AA results for a function. We store the results in fields so that
260 /// they live long enough to be queried, but we re-use them each time.
261 class LegacyAARGetter
{
263 Optional
<BasicAAResult
> BAR
;
264 Optional
<AAResults
> AAR
;
267 LegacyAARGetter(Pass
&P
) : P(P
) {}
268 AAResults
&operator()(Function
&F
) {
269 BAR
.emplace(createLegacyPMBasicAAResult(P
, F
));
270 AAR
.emplace(createLegacyPMAAResults(P
, F
, *BAR
));
275 } // end namespace llvm
277 #endif // LLVM_ANALYSIS_BASICALIASANALYSIS_H