Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1 | //===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- C++ -*-===// |
| 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 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 |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 6 | // |
| 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 21 | #include "llvm/IR/PassManager.h" |
| 22 | #include "llvm/Pass.h" |
| 23 | #include <algorithm> |
| 24 | #include <cstdint> |
| 25 | #include <memory> |
| 26 | #include <utility> |
| 27 | |
| 28 | namespace llvm { |
| 29 | |
| 30 | struct AAMDNodes; |
| 31 | class APInt; |
| 32 | class AssumptionCache; |
| 33 | class BasicBlock; |
| 34 | class DataLayout; |
| 35 | class DominatorTree; |
| 36 | class Function; |
| 37 | class GEPOperator; |
| 38 | class LoopInfo; |
| 39 | class PHINode; |
| 40 | class SelectInst; |
| 41 | class TargetLibraryInfo; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 42 | class PhiValues; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 43 | class 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. |
| 51 | class BasicAAResult : public AAResultBase<BasicAAResult> { |
| 52 | friend AAResultBase<BasicAAResult>; |
| 53 | |
| 54 | const DataLayout &DL; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 55 | const Function &F; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 56 | const TargetLibraryInfo &TLI; |
| 57 | AssumptionCache &AC; |
| 58 | DominatorTree *DT; |
| 59 | LoopInfo *LI; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 60 | PhiValues *PV; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 61 | |
| 62 | public: |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 63 | 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 69 | |
| 70 | BasicAAResult(const BasicAAResult &Arg) |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 71 | : 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 73 | BasicAAResult(BasicAAResult &&Arg) |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 74 | : 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 76 | |
| 77 | /// Handle invalidation events in the new pass manager. |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 78 | bool invalidate(Function &Fn, const PreservedAnalyses &PA, |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 79 | FunctionAnalysisManager::Invalidator &Inv); |
| 80 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 81 | AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, |
| 82 | AAQueryInfo &AAQI); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 83 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 84 | ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, |
| 85 | AAQueryInfo &AAQI); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 86 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 87 | ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2, |
| 88 | AAQueryInfo &AAQI); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 89 | |
| 90 | /// Chases pointers until we find a (constant global) or not. |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 91 | bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI, |
| 92 | bool OrLocal); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 93 | |
| 94 | /// Get the location associated with a pointer argument of a callsite. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 95 | ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 96 | |
| 97 | /// Returns the behavior when calling the given call site. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 98 | FunctionModRefBehavior getModRefBehavior(const CallBase *Call); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 99 | |
| 100 | /// Returns the behavior when calling the given function. For use when the |
| 101 | /// call site is not known. |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 102 | FunctionModRefBehavior getModRefBehavior(const Function *Fn); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 103 | |
| 104 | private: |
| 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 Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 118 | APInt Scale; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 119 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 120 | // Context instruction to use when querying information about this index. |
| 121 | const Instruction *CxtI; |
| 122 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 123 | 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 Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 131 | |
| 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 142 | }; |
| 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 Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 149 | // Total constant offset from base. |
| 150 | APInt Offset; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 151 | // Scaled variable (non-constant) indices. |
| 152 | SmallVector<VariableGEPIndex, 4> VarIndices; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 153 | // 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 172 | }; |
| 173 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 174 | /// 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 Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 193 | /// 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 201 | 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 Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 207 | static DecomposedGEP |
| 208 | DecomposeGEPExpression(const Value *V, const DataLayout &DL, |
| 209 | AssumptionCache *AC, DominatorTree *DT); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 210 | |
| 211 | static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp, |
| 212 | const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject, |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 213 | LocationSize ObjectAccessSize); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 214 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 215 | /// A Heuristic for aliasGEP that searches for a constant offset |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 216 | /// 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 Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 225 | LocationSize V1Size, LocationSize V2Size, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 226 | const APInt &BaseOffset, AssumptionCache *AC, |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 227 | DominatorTree *DT); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 228 | |
| 229 | bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2); |
| 230 | |
| 231 | void GetIndexDifference(SmallVectorImpl<VariableGEPIndex> &Dest, |
| 232 | const SmallVectorImpl<VariableGEPIndex> &Src); |
| 233 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 234 | AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size, |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 235 | const AAMDNodes &V1AAInfo, const Value *V2, |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 236 | LocationSize V2Size, const AAMDNodes &V2AAInfo, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 237 | const Value *UnderlyingV1, const Value *UnderlyingV2, |
| 238 | AAQueryInfo &AAQI); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 239 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 240 | AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize, |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 241 | const AAMDNodes &PNAAInfo, const Value *V2, |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 242 | LocationSize V2Size, const AAMDNodes &V2AAInfo, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 243 | const Value *UnderV2, AAQueryInfo &AAQI); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 244 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 245 | AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize, |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 246 | const AAMDNodes &SIAAInfo, const Value *V2, |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 247 | LocationSize V2Size, const AAMDNodes &V2AAInfo, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 248 | const Value *UnderV2, AAQueryInfo &AAQI); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 249 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 250 | AliasResult aliasCheck(const Value *V1, LocationSize V1Size, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 251 | const AAMDNodes &V1AATag, const Value *V2, |
| 252 | LocationSize V2Size, const AAMDNodes &V2AATag, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 253 | AAQueryInfo &AAQI, const Value *O1 = nullptr, |
| 254 | const Value *O2 = nullptr); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 255 | |
| 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 Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 261 | }; |
| 262 | |
| 263 | /// Analysis pass providing a never-invalidated alias analysis result. |
| 264 | class BasicAA : public AnalysisInfoMixin<BasicAA> { |
| 265 | friend AnalysisInfoMixin<BasicAA>; |
| 266 | |
| 267 | static AnalysisKey Key; |
| 268 | |
| 269 | public: |
| 270 | using Result = BasicAAResult; |
| 271 | |
| 272 | BasicAAResult run(Function &F, FunctionAnalysisManager &AM); |
| 273 | }; |
| 274 | |
| 275 | /// Legacy wrapper pass to provide the BasicAAResult object. |
| 276 | class BasicAAWrapperPass : public FunctionPass { |
| 277 | std::unique_ptr<BasicAAResult> Result; |
| 278 | |
| 279 | virtual void anchor(); |
| 280 | |
| 281 | public: |
| 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 | |
| 293 | FunctionPass *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. |
| 298 | BasicAAResult 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. |
| 303 | class LegacyAARGetter { |
| 304 | Pass &P; |
| 305 | Optional<BasicAAResult> BAR; |
| 306 | Optional<AAResults> AAR; |
| 307 | |
| 308 | public: |
| 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 |