10b57cec5SDimitry Andric //===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// \file 90b57cec5SDimitry Andric /// This is the interface for LLVM's primary stateless and local alias analysis. 100b57cec5SDimitry Andric /// 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_ANALYSIS_BASICALIASANALYSIS_H 140b57cec5SDimitry Andric #define LLVM_ANALYSIS_BASICALIASANALYSIS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 170b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 190b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 200b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 210b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 220b57cec5SDimitry Andric #include "llvm/Pass.h" 230b57cec5SDimitry Andric #include <algorithm> 240b57cec5SDimitry Andric #include <cstdint> 250b57cec5SDimitry Andric #include <memory> 260b57cec5SDimitry Andric #include <utility> 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace llvm { 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric struct AAMDNodes; 310b57cec5SDimitry Andric class APInt; 320b57cec5SDimitry Andric class AssumptionCache; 330b57cec5SDimitry Andric class BasicBlock; 340b57cec5SDimitry Andric class DataLayout; 350b57cec5SDimitry Andric class DominatorTree; 360b57cec5SDimitry Andric class Function; 370b57cec5SDimitry Andric class GEPOperator; 380b57cec5SDimitry Andric class LoopInfo; 390b57cec5SDimitry Andric class PHINode; 400b57cec5SDimitry Andric class SelectInst; 410b57cec5SDimitry Andric class TargetLibraryInfo; 420b57cec5SDimitry Andric class PhiValues; 430b57cec5SDimitry Andric class Value; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric /// This is the AA result object for the basic, local, and stateless alias 460b57cec5SDimitry Andric /// analysis. It implements the AA query interface in an entirely stateless 470b57cec5SDimitry Andric /// manner. As one consequence, it is never invalidated due to IR changes. 480b57cec5SDimitry Andric /// While it does retain some storage, that is used as an optimization and not 490b57cec5SDimitry Andric /// to preserve information from query to query. However it does retain handles 500b57cec5SDimitry Andric /// to various other analyses and must be recomputed when those analyses are. 510b57cec5SDimitry Andric class BasicAAResult : public AAResultBase<BasicAAResult> { 520b57cec5SDimitry Andric friend AAResultBase<BasicAAResult>; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric const DataLayout &DL; 550b57cec5SDimitry Andric const Function &F; 560b57cec5SDimitry Andric const TargetLibraryInfo &TLI; 570b57cec5SDimitry Andric AssumptionCache &AC; 580b57cec5SDimitry Andric DominatorTree *DT; 590b57cec5SDimitry Andric LoopInfo *LI; 600b57cec5SDimitry Andric PhiValues *PV; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric public: 630b57cec5SDimitry Andric BasicAAResult(const DataLayout &DL, const Function &F, 640b57cec5SDimitry Andric const TargetLibraryInfo &TLI, AssumptionCache &AC, 650b57cec5SDimitry Andric DominatorTree *DT = nullptr, LoopInfo *LI = nullptr, 660b57cec5SDimitry Andric PhiValues *PV = nullptr) 670b57cec5SDimitry Andric : AAResultBase(), DL(DL), F(F), TLI(TLI), AC(AC), DT(DT), LI(LI), PV(PV) 680b57cec5SDimitry Andric {} 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric BasicAAResult(const BasicAAResult &Arg) 710b57cec5SDimitry Andric : AAResultBase(Arg), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), AC(Arg.AC), 720b57cec5SDimitry Andric DT(Arg.DT), LI(Arg.LI), PV(Arg.PV) {} 730b57cec5SDimitry Andric BasicAAResult(BasicAAResult &&Arg) 740b57cec5SDimitry Andric : AAResultBase(std::move(Arg)), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), 750b57cec5SDimitry Andric AC(Arg.AC), DT(Arg.DT), LI(Arg.LI), PV(Arg.PV) {} 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric /// Handle invalidation events in the new pass manager. 780b57cec5SDimitry Andric bool invalidate(Function &Fn, const PreservedAnalyses &PA, 790b57cec5SDimitry Andric FunctionAnalysisManager::Invalidator &Inv); 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, 820b57cec5SDimitry Andric AAQueryInfo &AAQI); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, 850b57cec5SDimitry Andric AAQueryInfo &AAQI); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2, 880b57cec5SDimitry Andric AAQueryInfo &AAQI); 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric /// Chases pointers until we find a (constant global) or not. 910b57cec5SDimitry Andric bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI, 920b57cec5SDimitry Andric bool OrLocal); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric /// Get the location associated with a pointer argument of a callsite. 950b57cec5SDimitry Andric ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx); 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric /// Returns the behavior when calling the given call site. 980b57cec5SDimitry Andric FunctionModRefBehavior getModRefBehavior(const CallBase *Call); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// Returns the behavior when calling the given function. For use when the 1010b57cec5SDimitry Andric /// call site is not known. 1020b57cec5SDimitry Andric FunctionModRefBehavior getModRefBehavior(const Function *Fn); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric private: 1050b57cec5SDimitry Andric // A linear transformation of a Value; this class represents ZExt(SExt(V, 1060b57cec5SDimitry Andric // SExtBits), ZExtBits) * Scale + Offset. 1070b57cec5SDimitry Andric struct VariableGEPIndex { 1080b57cec5SDimitry Andric // An opaque Value - we can't decompose this further. 1090b57cec5SDimitry Andric const Value *V; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // We need to track what extensions we've done as we consider the same Value 1120b57cec5SDimitry Andric // with different extensions as different variables in a GEP's linear 1130b57cec5SDimitry Andric // expression; 1140b57cec5SDimitry Andric // e.g.: if V == -1, then sext(x) != zext(x). 1150b57cec5SDimitry Andric unsigned ZExtBits; 1160b57cec5SDimitry Andric unsigned SExtBits; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric APInt Scale; 1190b57cec5SDimitry Andric 120*e8d8bef9SDimitry Andric // Context instruction to use when querying information about this index. 121*e8d8bef9SDimitry Andric const Instruction *CxtI; 122*e8d8bef9SDimitry Andric 1230b57cec5SDimitry Andric bool operator==(const VariableGEPIndex &Other) const { 1240b57cec5SDimitry Andric return V == Other.V && ZExtBits == Other.ZExtBits && 1250b57cec5SDimitry Andric SExtBits == Other.SExtBits && Scale == Other.Scale; 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric bool operator!=(const VariableGEPIndex &Other) const { 1290b57cec5SDimitry Andric return !operator==(Other); 1300b57cec5SDimitry Andric } 131*e8d8bef9SDimitry Andric 132*e8d8bef9SDimitry Andric void dump() const { 133*e8d8bef9SDimitry Andric print(dbgs()); 134*e8d8bef9SDimitry Andric dbgs() << "\n"; 135*e8d8bef9SDimitry Andric } 136*e8d8bef9SDimitry Andric void print(raw_ostream &OS) const { 137*e8d8bef9SDimitry Andric OS << "(V=" << V->getName() 138*e8d8bef9SDimitry Andric << ", zextbits=" << ZExtBits 139*e8d8bef9SDimitry Andric << ", sextbits=" << SExtBits 140*e8d8bef9SDimitry Andric << ", scale=" << Scale << ")"; 141*e8d8bef9SDimitry Andric } 1420b57cec5SDimitry Andric }; 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric // Represents the internal structure of a GEP, decomposed into a base pointer, 1450b57cec5SDimitry Andric // constant offsets, and variable scaled indices. 1460b57cec5SDimitry Andric struct DecomposedGEP { 1470b57cec5SDimitry Andric // Base pointer of the GEP 1480b57cec5SDimitry Andric const Value *Base; 149*e8d8bef9SDimitry Andric // Total constant offset from base. 150*e8d8bef9SDimitry Andric APInt Offset; 1510b57cec5SDimitry Andric // Scaled variable (non-constant) indices. 1520b57cec5SDimitry Andric SmallVector<VariableGEPIndex, 4> VarIndices; 1535ffd83dbSDimitry Andric // Is GEP index scale compile-time constant. 1545ffd83dbSDimitry Andric bool HasCompileTimeConstantScale; 155*e8d8bef9SDimitry Andric 156*e8d8bef9SDimitry Andric void dump() const { 157*e8d8bef9SDimitry Andric print(dbgs()); 158*e8d8bef9SDimitry Andric dbgs() << "\n"; 159*e8d8bef9SDimitry Andric } 160*e8d8bef9SDimitry Andric void print(raw_ostream &OS) const { 161*e8d8bef9SDimitry Andric OS << "(DecomposedGEP Base=" << Base->getName() 162*e8d8bef9SDimitry Andric << ", Offset=" << Offset 163*e8d8bef9SDimitry Andric << ", VarIndices=["; 164*e8d8bef9SDimitry Andric for (size_t i = 0; i < VarIndices.size(); i++) { 165*e8d8bef9SDimitry Andric if (i != 0) 166*e8d8bef9SDimitry Andric OS << ", "; 167*e8d8bef9SDimitry Andric VarIndices[i].print(OS); 168*e8d8bef9SDimitry Andric } 169*e8d8bef9SDimitry Andric OS << "], HasCompileTimeConstantScale=" << HasCompileTimeConstantScale 170*e8d8bef9SDimitry Andric << ")"; 171*e8d8bef9SDimitry Andric } 1720b57cec5SDimitry Andric }; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric /// Tracks phi nodes we have visited. 1750b57cec5SDimitry Andric /// 1760b57cec5SDimitry Andric /// When interpret "Value" pointer equality as value equality we need to make 1770b57cec5SDimitry Andric /// sure that the "Value" is not part of a cycle. Otherwise, two uses could 1780b57cec5SDimitry Andric /// come from different "iterations" of a cycle and see different values for 1790b57cec5SDimitry Andric /// the same "Value" pointer. 1800b57cec5SDimitry Andric /// 1810b57cec5SDimitry Andric /// The following example shows the problem: 1820b57cec5SDimitry Andric /// %p = phi(%alloca1, %addr2) 1830b57cec5SDimitry Andric /// %l = load %ptr 1840b57cec5SDimitry Andric /// %addr1 = gep, %alloca2, 0, %l 1850b57cec5SDimitry Andric /// %addr2 = gep %alloca2, 0, (%l + 1) 1860b57cec5SDimitry Andric /// alias(%p, %addr1) -> MayAlias ! 1870b57cec5SDimitry Andric /// store %l, ... 1880b57cec5SDimitry Andric SmallPtrSet<const BasicBlock *, 8> VisitedPhiBBs; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric /// Tracks instructions visited by pointsToConstantMemory. 1910b57cec5SDimitry Andric SmallPtrSet<const Value *, 16> Visited; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric static const Value * 1940b57cec5SDimitry Andric GetLinearExpression(const Value *V, APInt &Scale, APInt &Offset, 1950b57cec5SDimitry Andric unsigned &ZExtBits, unsigned &SExtBits, 1960b57cec5SDimitry Andric const DataLayout &DL, unsigned Depth, AssumptionCache *AC, 1970b57cec5SDimitry Andric DominatorTree *DT, bool &NSW, bool &NUW); 1980b57cec5SDimitry Andric 199*e8d8bef9SDimitry Andric static DecomposedGEP 200*e8d8bef9SDimitry Andric DecomposeGEPExpression(const Value *V, const DataLayout &DL, 201*e8d8bef9SDimitry Andric AssumptionCache *AC, DominatorTree *DT); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp, 2040b57cec5SDimitry Andric const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject, 2050b57cec5SDimitry Andric LocationSize ObjectAccessSize); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric /// A Heuristic for aliasGEP that searches for a constant offset 2080b57cec5SDimitry Andric /// between the variables. 2090b57cec5SDimitry Andric /// 2100b57cec5SDimitry Andric /// GetLinearExpression has some limitations, as generally zext(%x + 1) 2110b57cec5SDimitry Andric /// != zext(%x) + zext(1) if the arithmetic overflows. GetLinearExpression 2120b57cec5SDimitry Andric /// will therefore conservatively refuse to decompose these expressions. 2130b57cec5SDimitry Andric /// However, we know that, for all %x, zext(%x) != zext(%x + 1), even if 2140b57cec5SDimitry Andric /// the addition overflows. 2150b57cec5SDimitry Andric bool 2160b57cec5SDimitry Andric constantOffsetHeuristic(const SmallVectorImpl<VariableGEPIndex> &VarIndices, 2170b57cec5SDimitry Andric LocationSize V1Size, LocationSize V2Size, 2185ffd83dbSDimitry Andric const APInt &BaseOffset, AssumptionCache *AC, 2190b57cec5SDimitry Andric DominatorTree *DT); 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2); 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric void GetIndexDifference(SmallVectorImpl<VariableGEPIndex> &Dest, 2240b57cec5SDimitry Andric const SmallVectorImpl<VariableGEPIndex> &Src); 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size, 2270b57cec5SDimitry Andric const AAMDNodes &V1AAInfo, const Value *V2, 2280b57cec5SDimitry Andric LocationSize V2Size, const AAMDNodes &V2AAInfo, 2290b57cec5SDimitry Andric const Value *UnderlyingV1, const Value *UnderlyingV2, 2300b57cec5SDimitry Andric AAQueryInfo &AAQI); 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize, 2330b57cec5SDimitry Andric const AAMDNodes &PNAAInfo, const Value *V2, 2340b57cec5SDimitry Andric LocationSize V2Size, const AAMDNodes &V2AAInfo, 235*e8d8bef9SDimitry Andric AAQueryInfo &AAQI); 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize, 2380b57cec5SDimitry Andric const AAMDNodes &SIAAInfo, const Value *V2, 2390b57cec5SDimitry Andric LocationSize V2Size, const AAMDNodes &V2AAInfo, 240*e8d8bef9SDimitry Andric AAQueryInfo &AAQI); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric AliasResult aliasCheck(const Value *V1, LocationSize V1Size, 243*e8d8bef9SDimitry Andric const AAMDNodes &V1AATag, const Value *V2, 244*e8d8bef9SDimitry Andric LocationSize V2Size, const AAMDNodes &V2AATag, 245*e8d8bef9SDimitry Andric AAQueryInfo &AAQI); 246*e8d8bef9SDimitry Andric 247*e8d8bef9SDimitry Andric AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size, 248*e8d8bef9SDimitry Andric const AAMDNodes &V1AATag, const Value *V2, 249*e8d8bef9SDimitry Andric LocationSize V2Size, const AAMDNodes &V2AATag, 250*e8d8bef9SDimitry Andric AAQueryInfo &AAQI, const Value *O1, 251*e8d8bef9SDimitry Andric const Value *O2); 2520b57cec5SDimitry Andric }; 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric /// Analysis pass providing a never-invalidated alias analysis result. 2550b57cec5SDimitry Andric class BasicAA : public AnalysisInfoMixin<BasicAA> { 2560b57cec5SDimitry Andric friend AnalysisInfoMixin<BasicAA>; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric static AnalysisKey Key; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric public: 2610b57cec5SDimitry Andric using Result = BasicAAResult; 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric BasicAAResult run(Function &F, FunctionAnalysisManager &AM); 2640b57cec5SDimitry Andric }; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric /// Legacy wrapper pass to provide the BasicAAResult object. 2670b57cec5SDimitry Andric class BasicAAWrapperPass : public FunctionPass { 2680b57cec5SDimitry Andric std::unique_ptr<BasicAAResult> Result; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric virtual void anchor(); 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric public: 2730b57cec5SDimitry Andric static char ID; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric BasicAAWrapperPass(); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric BasicAAResult &getResult() { return *Result; } 2780b57cec5SDimitry Andric const BasicAAResult &getResult() const { return *Result; } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric bool runOnFunction(Function &F) override; 2810b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 2820b57cec5SDimitry Andric }; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric FunctionPass *createBasicAAWrapperPass(); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric /// A helper for the legacy pass manager to create a \c BasicAAResult object 2870b57cec5SDimitry Andric /// populated to the best of our ability for a particular function when inside 2880b57cec5SDimitry Andric /// of a \c ModulePass or a \c CallGraphSCCPass. 2890b57cec5SDimitry Andric BasicAAResult createLegacyPMBasicAAResult(Pass &P, Function &F); 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric /// This class is a functor to be used in legacy module or SCC passes for 2920b57cec5SDimitry Andric /// computing AA results for a function. We store the results in fields so that 2930b57cec5SDimitry Andric /// they live long enough to be queried, but we re-use them each time. 2940b57cec5SDimitry Andric class LegacyAARGetter { 2950b57cec5SDimitry Andric Pass &P; 2960b57cec5SDimitry Andric Optional<BasicAAResult> BAR; 2970b57cec5SDimitry Andric Optional<AAResults> AAR; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric public: 3000b57cec5SDimitry Andric LegacyAARGetter(Pass &P) : P(P) {} 3010b57cec5SDimitry Andric AAResults &operator()(Function &F) { 3020b57cec5SDimitry Andric BAR.emplace(createLegacyPMBasicAAResult(P, F)); 3030b57cec5SDimitry Andric AAR.emplace(createLegacyPMAAResults(P, F, *BAR)); 3040b57cec5SDimitry Andric return *AAR; 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric }; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric } // end namespace llvm 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric #endif // LLVM_ANALYSIS_BASICALIASANALYSIS_H 311