xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/BasicAliasAnalysis.h (revision b3edf4467982447620505a28fc82e38a414c07dc)
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/SmallPtrSet.h"
170b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
180b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
190b57cec5SDimitry Andric #include "llvm/Pass.h"
200b57cec5SDimitry Andric #include <memory>
210b57cec5SDimitry Andric #include <utility>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace llvm {
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric class AssumptionCache;
260b57cec5SDimitry Andric class DataLayout;
270b57cec5SDimitry Andric class DominatorTree;
280b57cec5SDimitry Andric class Function;
290b57cec5SDimitry Andric class GEPOperator;
300b57cec5SDimitry Andric class PHINode;
310b57cec5SDimitry Andric class SelectInst;
320b57cec5SDimitry Andric class TargetLibraryInfo;
330b57cec5SDimitry Andric class Value;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric /// This is the AA result object for the basic, local, and stateless alias
360b57cec5SDimitry Andric /// analysis. It implements the AA query interface in an entirely stateless
370b57cec5SDimitry Andric /// manner. As one consequence, it is never invalidated due to IR changes.
380b57cec5SDimitry Andric /// While it does retain some storage, that is used as an optimization and not
390b57cec5SDimitry Andric /// to preserve information from query to query. However it does retain handles
400b57cec5SDimitry Andric /// to various other analyses and must be recomputed when those analyses are.
41bdd1243dSDimitry Andric class BasicAAResult : public AAResultBase {
420b57cec5SDimitry Andric   const DataLayout &DL;
430b57cec5SDimitry Andric   const Function &F;
440b57cec5SDimitry Andric   const TargetLibraryInfo &TLI;
450b57cec5SDimitry Andric   AssumptionCache &AC;
46*b3edf446SDimitry Andric   /// Use getDT() instead of accessing this member directly, in order to
47*b3edf446SDimitry Andric   /// respect the AAQI.UseDominatorTree option.
48*b3edf446SDimitry Andric   DominatorTree *DT_;
49*b3edf446SDimitry Andric 
50*b3edf446SDimitry Andric   DominatorTree *getDT(const AAQueryInfo &AAQI) const {
51*b3edf446SDimitry Andric     return AAQI.UseDominatorTree ? DT_ : nullptr;
52*b3edf446SDimitry Andric   }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric public:
550b57cec5SDimitry Andric   BasicAAResult(const DataLayout &DL, const Function &F,
560b57cec5SDimitry Andric                 const TargetLibraryInfo &TLI, AssumptionCache &AC,
57bdd1243dSDimitry Andric                 DominatorTree *DT = nullptr)
58*b3edf446SDimitry Andric       : DL(DL), F(F), TLI(TLI), AC(AC), DT_(DT) {}
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   BasicAAResult(const BasicAAResult &Arg)
610b57cec5SDimitry Andric       : AAResultBase(Arg), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), AC(Arg.AC),
62*b3edf446SDimitry Andric         DT_(Arg.DT_) {}
630b57cec5SDimitry Andric   BasicAAResult(BasicAAResult &&Arg)
640b57cec5SDimitry Andric       : AAResultBase(std::move(Arg)), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI),
65*b3edf446SDimitry Andric         AC(Arg.AC), DT_(Arg.DT_) {}
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   /// Handle invalidation events in the new pass manager.
680b57cec5SDimitry Andric   bool invalidate(Function &Fn, const PreservedAnalyses &PA,
690b57cec5SDimitry Andric                   FunctionAnalysisManager::Invalidator &Inv);
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
72bdd1243dSDimitry Andric                     AAQueryInfo &AAQI, const Instruction *CtxI);
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
750b57cec5SDimitry Andric                            AAQueryInfo &AAQI);
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
780b57cec5SDimitry Andric                            AAQueryInfo &AAQI);
790b57cec5SDimitry Andric 
80bdd1243dSDimitry Andric   /// Returns a bitmask that should be unconditionally applied to the ModRef
81bdd1243dSDimitry Andric   /// info of a memory location. This allows us to eliminate Mod and/or Ref
82bdd1243dSDimitry Andric   /// from the ModRef info based on the knowledge that the memory location
83bdd1243dSDimitry Andric   /// points to constant and/or locally-invariant memory.
84bdd1243dSDimitry Andric   ///
85bdd1243dSDimitry Andric   /// If IgnoreLocals is true, then this method returns NoModRef for memory
86bdd1243dSDimitry Andric   /// that points to a local alloca.
87bdd1243dSDimitry Andric   ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
88bdd1243dSDimitry Andric                                bool IgnoreLocals = false);
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   /// Get the location associated with a pointer argument of a callsite.
910b57cec5SDimitry Andric   ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   /// Returns the behavior when calling the given call site.
94bdd1243dSDimitry Andric   MemoryEffects getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI);
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   /// Returns the behavior when calling the given function. For use when the
970b57cec5SDimitry Andric   /// call site is not known.
98bdd1243dSDimitry Andric   MemoryEffects getMemoryEffects(const Function *Fn);
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric private:
101349cc55cSDimitry Andric   struct DecomposedGEP;
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   /// Tracks instructions visited by pointsToConstantMemory.
1040b57cec5SDimitry Andric   SmallPtrSet<const Value *, 16> Visited;
1050b57cec5SDimitry Andric 
106e8d8bef9SDimitry Andric   static DecomposedGEP
107e8d8bef9SDimitry Andric   DecomposeGEPExpression(const Value *V, const DataLayout &DL,
108e8d8bef9SDimitry Andric                          AssumptionCache *AC, DominatorTree *DT);
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   /// A Heuristic for aliasGEP that searches for a constant offset
1110b57cec5SDimitry Andric   /// between the variables.
1120b57cec5SDimitry Andric   ///
1130b57cec5SDimitry Andric   /// GetLinearExpression has some limitations, as generally zext(%x + 1)
1140b57cec5SDimitry Andric   /// != zext(%x) + zext(1) if the arithmetic overflows. GetLinearExpression
1150b57cec5SDimitry Andric   /// will therefore conservatively refuse to decompose these expressions.
1160b57cec5SDimitry Andric   /// However, we know that, for all %x, zext(%x) != zext(%x + 1), even if
1170b57cec5SDimitry Andric   /// the addition overflows.
118bdd1243dSDimitry Andric   bool constantOffsetHeuristic(const DecomposedGEP &GEP, LocationSize V1Size,
119349cc55cSDimitry Andric                                LocationSize V2Size, AssumptionCache *AC,
120bdd1243dSDimitry Andric                                DominatorTree *DT, const AAQueryInfo &AAQI);
1210b57cec5SDimitry Andric 
122bdd1243dSDimitry Andric   bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2,
123bdd1243dSDimitry Andric                                      const AAQueryInfo &AAQI);
1240b57cec5SDimitry Andric 
125349cc55cSDimitry Andric   void subtractDecomposedGEPs(DecomposedGEP &DestGEP,
126bdd1243dSDimitry Andric                               const DecomposedGEP &SrcGEP,
127bdd1243dSDimitry Andric                               const AAQueryInfo &AAQI);
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size,
130fe6060f1SDimitry Andric                        const Value *V2, LocationSize V2Size,
1310b57cec5SDimitry Andric                        const Value *UnderlyingV1, const Value *UnderlyingV2,
1320b57cec5SDimitry Andric                        AAQueryInfo &AAQI);
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize,
135fe6060f1SDimitry Andric                        const Value *V2, LocationSize V2Size, AAQueryInfo &AAQI);
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize,
138fe6060f1SDimitry Andric                           const Value *V2, LocationSize V2Size,
139e8d8bef9SDimitry Andric                           AAQueryInfo &AAQI);
1400b57cec5SDimitry Andric 
141bdd1243dSDimitry Andric   AliasResult aliasCheck(const Value *V1, LocationSize V1Size, const Value *V2,
142bdd1243dSDimitry Andric                          LocationSize V2Size, AAQueryInfo &AAQI,
143bdd1243dSDimitry Andric                          const Instruction *CtxI);
144e8d8bef9SDimitry Andric 
145e8d8bef9SDimitry Andric   AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size,
146fe6060f1SDimitry Andric                                   const Value *V2, LocationSize V2Size,
147e8d8bef9SDimitry Andric                                   AAQueryInfo &AAQI, const Value *O1,
148e8d8bef9SDimitry Andric                                   const Value *O2);
1490b57cec5SDimitry Andric };
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric /// Analysis pass providing a never-invalidated alias analysis result.
1520b57cec5SDimitry Andric class BasicAA : public AnalysisInfoMixin<BasicAA> {
1530b57cec5SDimitry Andric   friend AnalysisInfoMixin<BasicAA>;
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   static AnalysisKey Key;
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric public:
1580b57cec5SDimitry Andric   using Result = BasicAAResult;
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   BasicAAResult run(Function &F, FunctionAnalysisManager &AM);
1610b57cec5SDimitry Andric };
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric /// Legacy wrapper pass to provide the BasicAAResult object.
1640b57cec5SDimitry Andric class BasicAAWrapperPass : public FunctionPass {
1650b57cec5SDimitry Andric   std::unique_ptr<BasicAAResult> Result;
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   virtual void anchor();
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric public:
1700b57cec5SDimitry Andric   static char ID;
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   BasicAAWrapperPass();
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric   BasicAAResult &getResult() { return *Result; }
1750b57cec5SDimitry Andric   const BasicAAResult &getResult() const { return *Result; }
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric   bool runOnFunction(Function &F) override;
1780b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
1790b57cec5SDimitry Andric };
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric FunctionPass *createBasicAAWrapperPass();
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric } // end namespace llvm
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric #endif // LLVM_ANALYSIS_BASICALIASANALYSIS_H
186