xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/BasicAliasAnalysis.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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