blob: 635c35585f8153aed4c66efdedfdb54d8822d69f [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This is the interface for LLVM's primary stateless and local alias analysis.
10///
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_ANALYSIS_BASICALIASANALYSIS_H
14#define LLVM_ANALYSIS_BASICALIASANALYSIS_H
15
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"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010021#include "llvm/IR/PassManager.h"
22#include "llvm/Pass.h"
23#include <algorithm>
24#include <cstdint>
25#include <memory>
26#include <utility>
27
28namespace llvm {
29
30struct AAMDNodes;
31class APInt;
32class AssumptionCache;
33class BasicBlock;
34class DataLayout;
35class DominatorTree;
36class Function;
37class GEPOperator;
38class LoopInfo;
39class PHINode;
40class SelectInst;
41class TargetLibraryInfo;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010042class PhiValues;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010043class Value;
44
45/// This is the AA result object for the basic, local, and stateless alias
46/// analysis. It implements the AA query interface in an entirely stateless
47/// manner. As one consequence, it is never invalidated due to IR changes.
48/// While it does retain some storage, that is used as an optimization and not
49/// to preserve information from query to query. However it does retain handles
50/// to various other analyses and must be recomputed when those analyses are.
51class BasicAAResult : public AAResultBase<BasicAAResult> {
52 friend AAResultBase<BasicAAResult>;
53
54 const DataLayout &DL;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010055 const Function &F;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010056 const TargetLibraryInfo &TLI;
57 AssumptionCache &AC;
58 DominatorTree *DT;
59 LoopInfo *LI;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010060 PhiValues *PV;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010061
62public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +010063 BasicAAResult(const DataLayout &DL, const Function &F,
64 const TargetLibraryInfo &TLI, AssumptionCache &AC,
65 DominatorTree *DT = nullptr, LoopInfo *LI = nullptr,
66 PhiValues *PV = nullptr)
67 : AAResultBase(), DL(DL), F(F), TLI(TLI), AC(AC), DT(DT), LI(LI), PV(PV)
68 {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010069
70 BasicAAResult(const BasicAAResult &Arg)
Andrew Scullcdfcccc2018-10-05 20:58:37 +010071 : AAResultBase(Arg), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), AC(Arg.AC),
72 DT(Arg.DT), LI(Arg.LI), PV(Arg.PV) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010073 BasicAAResult(BasicAAResult &&Arg)
Andrew Scullcdfcccc2018-10-05 20:58:37 +010074 : AAResultBase(std::move(Arg)), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI),
75 AC(Arg.AC), DT(Arg.DT), LI(Arg.LI), PV(Arg.PV) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010076
77 /// Handle invalidation events in the new pass manager.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010078 bool invalidate(Function &Fn, const PreservedAnalyses &PA,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010079 FunctionAnalysisManager::Invalidator &Inv);
80
Andrew Walbran3d2c1972020-04-07 12:24:26 +010081 AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
82 AAQueryInfo &AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010083
Andrew Walbran3d2c1972020-04-07 12:24:26 +010084 ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
85 AAQueryInfo &AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010086
Andrew Walbran3d2c1972020-04-07 12:24:26 +010087 ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
88 AAQueryInfo &AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010089
90 /// Chases pointers until we find a (constant global) or not.
Andrew Walbran3d2c1972020-04-07 12:24:26 +010091 bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
92 bool OrLocal);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010093
94 /// Get the location associated with a pointer argument of a callsite.
Andrew Walbran16937d02019-10-22 13:54:20 +010095 ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010096
97 /// Returns the behavior when calling the given call site.
Andrew Walbran16937d02019-10-22 13:54:20 +010098 FunctionModRefBehavior getModRefBehavior(const CallBase *Call);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010099
100 /// Returns the behavior when calling the given function. For use when the
101 /// call site is not known.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100102 FunctionModRefBehavior getModRefBehavior(const Function *Fn);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100103
104private:
105 // A linear transformation of a Value; this class represents ZExt(SExt(V,
106 // SExtBits), ZExtBits) * Scale + Offset.
107 struct VariableGEPIndex {
108 // An opaque Value - we can't decompose this further.
109 const Value *V;
110
111 // We need to track what extensions we've done as we consider the same Value
112 // with different extensions as different variables in a GEP's linear
113 // expression;
114 // e.g.: if V == -1, then sext(x) != zext(x).
115 unsigned ZExtBits;
116 unsigned SExtBits;
117
Andrew Walbran16937d02019-10-22 13:54:20 +0100118 APInt Scale;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100119
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200120 // Context instruction to use when querying information about this index.
121 const Instruction *CxtI;
122
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100123 bool operator==(const VariableGEPIndex &Other) const {
124 return V == Other.V && ZExtBits == Other.ZExtBits &&
125 SExtBits == Other.SExtBits && Scale == Other.Scale;
126 }
127
128 bool operator!=(const VariableGEPIndex &Other) const {
129 return !operator==(Other);
130 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200131
132 void dump() const {
133 print(dbgs());
134 dbgs() << "\n";
135 }
136 void print(raw_ostream &OS) const {
137 OS << "(V=" << V->getName()
138 << ", zextbits=" << ZExtBits
139 << ", sextbits=" << SExtBits
140 << ", scale=" << Scale << ")";
141 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100142 };
143
144 // Represents the internal structure of a GEP, decomposed into a base pointer,
145 // constant offsets, and variable scaled indices.
146 struct DecomposedGEP {
147 // Base pointer of the GEP
148 const Value *Base;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200149 // Total constant offset from base.
150 APInt Offset;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100151 // Scaled variable (non-constant) indices.
152 SmallVector<VariableGEPIndex, 4> VarIndices;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200153 // Is GEP index scale compile-time constant.
154 bool HasCompileTimeConstantScale;
155
156 void dump() const {
157 print(dbgs());
158 dbgs() << "\n";
159 }
160 void print(raw_ostream &OS) const {
161 OS << "(DecomposedGEP Base=" << Base->getName()
162 << ", Offset=" << Offset
163 << ", VarIndices=[";
164 for (size_t i = 0; i < VarIndices.size(); i++) {
165 if (i != 0)
166 OS << ", ";
167 VarIndices[i].print(OS);
168 }
169 OS << "], HasCompileTimeConstantScale=" << HasCompileTimeConstantScale
170 << ")";
171 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100172 };
173
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100174 /// Tracks phi nodes we have visited.
175 ///
176 /// When interpret "Value" pointer equality as value equality we need to make
177 /// sure that the "Value" is not part of a cycle. Otherwise, two uses could
178 /// come from different "iterations" of a cycle and see different values for
179 /// the same "Value" pointer.
180 ///
181 /// The following example shows the problem:
182 /// %p = phi(%alloca1, %addr2)
183 /// %l = load %ptr
184 /// %addr1 = gep, %alloca2, 0, %l
185 /// %addr2 = gep %alloca2, 0, (%l + 1)
186 /// alias(%p, %addr1) -> MayAlias !
187 /// store %l, ...
188 SmallPtrSet<const BasicBlock *, 8> VisitedPhiBBs;
189
190 /// Tracks instructions visited by pointsToConstantMemory.
191 SmallPtrSet<const Value *, 16> Visited;
192
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200193 /// How many active NoAlias assumption uses there are.
194 int NumAssumptionUses = 0;
195
196 /// Location pairs for which an assumption based result is currently stored.
197 /// Used to remove all potentially incorrect results from the cache if an
198 /// assumption is disproven.
199 SmallVector<AAQueryInfo::LocPair, 4> AssumptionBasedResults;
200
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100201 static const Value *
202 GetLinearExpression(const Value *V, APInt &Scale, APInt &Offset,
203 unsigned &ZExtBits, unsigned &SExtBits,
204 const DataLayout &DL, unsigned Depth, AssumptionCache *AC,
205 DominatorTree *DT, bool &NSW, bool &NUW);
206
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200207 static DecomposedGEP
208 DecomposeGEPExpression(const Value *V, const DataLayout &DL,
209 AssumptionCache *AC, DominatorTree *DT);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100210
211 static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
212 const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100213 LocationSize ObjectAccessSize);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100214
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100215 /// A Heuristic for aliasGEP that searches for a constant offset
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100216 /// between the variables.
217 ///
218 /// GetLinearExpression has some limitations, as generally zext(%x + 1)
219 /// != zext(%x) + zext(1) if the arithmetic overflows. GetLinearExpression
220 /// will therefore conservatively refuse to decompose these expressions.
221 /// However, we know that, for all %x, zext(%x) != zext(%x + 1), even if
222 /// the addition overflows.
223 bool
224 constantOffsetHeuristic(const SmallVectorImpl<VariableGEPIndex> &VarIndices,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100225 LocationSize V1Size, LocationSize V2Size,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200226 const APInt &BaseOffset, AssumptionCache *AC,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100227 DominatorTree *DT);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100228
229 bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2);
230
231 void GetIndexDifference(SmallVectorImpl<VariableGEPIndex> &Dest,
232 const SmallVectorImpl<VariableGEPIndex> &Src);
233
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100234 AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100235 const AAMDNodes &V1AAInfo, const Value *V2,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100236 LocationSize V2Size, const AAMDNodes &V2AAInfo,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100237 const Value *UnderlyingV1, const Value *UnderlyingV2,
238 AAQueryInfo &AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100239
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100240 AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100241 const AAMDNodes &PNAAInfo, const Value *V2,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100242 LocationSize V2Size, const AAMDNodes &V2AAInfo,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100243 const Value *UnderV2, AAQueryInfo &AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100244
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100245 AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100246 const AAMDNodes &SIAAInfo, const Value *V2,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100247 LocationSize V2Size, const AAMDNodes &V2AAInfo,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100248 const Value *UnderV2, AAQueryInfo &AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100249
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100250 AliasResult aliasCheck(const Value *V1, LocationSize V1Size,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200251 const AAMDNodes &V1AATag, const Value *V2,
252 LocationSize V2Size, const AAMDNodes &V2AATag,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100253 AAQueryInfo &AAQI, const Value *O1 = nullptr,
254 const Value *O2 = nullptr);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200255
256 AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size,
257 const AAMDNodes &V1AATag, const Value *V2,
258 LocationSize V2Size, const AAMDNodes &V2AATag,
259 AAQueryInfo &AAQI, const Value *O1,
260 const Value *O2);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100261};
262
263/// Analysis pass providing a never-invalidated alias analysis result.
264class BasicAA : public AnalysisInfoMixin<BasicAA> {
265 friend AnalysisInfoMixin<BasicAA>;
266
267 static AnalysisKey Key;
268
269public:
270 using Result = BasicAAResult;
271
272 BasicAAResult run(Function &F, FunctionAnalysisManager &AM);
273};
274
275/// Legacy wrapper pass to provide the BasicAAResult object.
276class BasicAAWrapperPass : public FunctionPass {
277 std::unique_ptr<BasicAAResult> Result;
278
279 virtual void anchor();
280
281public:
282 static char ID;
283
284 BasicAAWrapperPass();
285
286 BasicAAResult &getResult() { return *Result; }
287 const BasicAAResult &getResult() const { return *Result; }
288
289 bool runOnFunction(Function &F) override;
290 void getAnalysisUsage(AnalysisUsage &AU) const override;
291};
292
293FunctionPass *createBasicAAWrapperPass();
294
295/// A helper for the legacy pass manager to create a \c BasicAAResult object
296/// populated to the best of our ability for a particular function when inside
297/// of a \c ModulePass or a \c CallGraphSCCPass.
298BasicAAResult createLegacyPMBasicAAResult(Pass &P, Function &F);
299
300/// This class is a functor to be used in legacy module or SCC passes for
301/// computing AA results for a function. We store the results in fields so that
302/// they live long enough to be queried, but we re-use them each time.
303class LegacyAARGetter {
304 Pass &P;
305 Optional<BasicAAResult> BAR;
306 Optional<AAResults> AAR;
307
308public:
309 LegacyAARGetter(Pass &P) : P(P) {}
310 AAResults &operator()(Function &F) {
311 BAR.emplace(createLegacyPMBasicAAResult(P, F));
312 AAR.emplace(createLegacyPMAAResults(P, F, *BAR));
313 return *AAR;
314 }
315};
316
317} // end namespace llvm
318
319#endif // LLVM_ANALYSIS_BASICALIASANALYSIS_H