xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/GlobalsModRef.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- GlobalsModRef.h - Simple Mod/Ref AA for Globals ----------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This is the interface for a simple mod/ref and alias analysis over globals.
10 ///
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_ANALYSIS_GLOBALSMODREF_H
14 #define LLVM_ANALYSIS_GLOBALSMODREF_H
15 
16 #include "llvm/Analysis/AliasAnalysis.h"
17 #include "llvm/IR/PassManager.h"
18 #include "llvm/IR/ValueHandle.h"
19 #include "llvm/Pass.h"
20 #include "llvm/Support/Compiler.h"
21 #include <list>
22 
23 namespace llvm {
24 class CallGraph;
25 class Function;
26 
27 /// An alias analysis result set for globals.
28 ///
29 /// This focuses on handling aliasing properties of globals and interprocedural
30 /// function call mod/ref information.
31 class GlobalsAAResult : public AAResultBase {
32   class FunctionInfo;
33 
34   const DataLayout &DL;
35   std::function<const TargetLibraryInfo &(Function &F)> GetTLI;
36 
37   /// The globals that do not have their addresses taken.
38   SmallPtrSet<const GlobalValue *, 8> NonAddressTakenGlobals;
39 
40   /// Are there functions with local linkage that may modify globals.
41   bool UnknownFunctionsWithLocalLinkage = false;
42 
43   /// IndirectGlobals - The memory pointed to by this global is known to be
44   /// 'owned' by the global.
45   SmallPtrSet<const GlobalValue *, 8> IndirectGlobals;
46 
47   /// AllocsForIndirectGlobals - If an instruction allocates memory for an
48   /// indirect global, this map indicates which one.
49   DenseMap<const Value *, const GlobalValue *> AllocsForIndirectGlobals;
50 
51   /// For each function, keep track of what globals are modified or read.
52   DenseMap<const Function *, FunctionInfo> FunctionInfos;
53 
54   /// A map of functions to SCC. The SCCs are described by a simple integer
55   /// ID that is only useful for comparing for equality (are two functions
56   /// in the same SCC or not?)
57   DenseMap<const Function *, unsigned> FunctionToSCCMap;
58 
59   /// Handle to clear this analysis on deletion of values.
60   struct LLVM_ABI DeletionCallbackHandle final : CallbackVH {
61     GlobalsAAResult *GAR;
62     std::list<DeletionCallbackHandle>::iterator I;
63 
DeletionCallbackHandlefinal64     DeletionCallbackHandle(GlobalsAAResult &GAR, Value *V)
65         : CallbackVH(V), GAR(&GAR) {}
66 
67     void deleted() override;
68   };
69 
70   /// List of callbacks for globals being tracked by this analysis. Note that
71   /// these objects are quite large, but we only anticipate having one per
72   /// global tracked by this analysis. There are numerous optimizations we
73   /// could perform to the memory utilization here if this becomes a problem.
74   std::list<DeletionCallbackHandle> Handles;
75 
76   explicit GlobalsAAResult(
77       const DataLayout &DL,
78       std::function<const TargetLibraryInfo &(Function &F)> GetTLI);
79 
80   friend struct RecomputeGlobalsAAPass;
81 
82 public:
83   LLVM_ABI GlobalsAAResult(GlobalsAAResult &&Arg);
84   LLVM_ABI ~GlobalsAAResult();
85 
86   LLVM_ABI bool invalidate(Module &M, const PreservedAnalyses &PA,
87                            ModuleAnalysisManager::Invalidator &);
88 
89   LLVM_ABI static GlobalsAAResult
90   analyzeModule(Module &M,
91                 std::function<const TargetLibraryInfo &(Function &F)> GetTLI,
92                 CallGraph &CG);
93 
94   //------------------------------------------------
95   // Implement the AliasAnalysis API
96   //
97   LLVM_ABI AliasResult alias(const MemoryLocation &LocA,
98                              const MemoryLocation &LocB, AAQueryInfo &AAQI,
99                              const Instruction *CtxI);
100 
101   using AAResultBase::getModRefInfo;
102   LLVM_ABI ModRefInfo getModRefInfo(const CallBase *Call,
103                                     const MemoryLocation &Loc,
104                                     AAQueryInfo &AAQI);
105 
106   using AAResultBase::getMemoryEffects;
107   /// getMemoryEffects - Return the behavior of the specified function if
108   /// called from the specified call site.  The call site may be null in which
109   /// case the most generic behavior of this function should be returned.
110   LLVM_ABI MemoryEffects getMemoryEffects(const Function *F);
111 
112 private:
113   FunctionInfo *getFunctionInfo(const Function *F);
114 
115   void AnalyzeGlobals(Module &M);
116   void AnalyzeCallGraph(CallGraph &CG, Module &M);
117   bool AnalyzeUsesOfPointer(Value *V,
118                             SmallPtrSetImpl<Function *> *Readers = nullptr,
119                             SmallPtrSetImpl<Function *> *Writers = nullptr,
120                             GlobalValue *OkayStoreDest = nullptr);
121   bool AnalyzeIndirectGlobalMemory(GlobalVariable *GV);
122   void CollectSCCMembership(CallGraph &CG);
123 
124   bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V,
125                                   const Instruction *CtxI);
126   ModRefInfo getModRefInfoForArgument(const CallBase *Call,
127                                       const GlobalValue *GV, AAQueryInfo &AAQI);
128 };
129 
130 /// Analysis pass providing a never-invalidated alias analysis result.
131 class GlobalsAA : public AnalysisInfoMixin<GlobalsAA> {
132   friend AnalysisInfoMixin<GlobalsAA>;
133   LLVM_ABI static AnalysisKey Key;
134 
135 public:
136   typedef GlobalsAAResult Result;
137 
138   LLVM_ABI GlobalsAAResult run(Module &M, ModuleAnalysisManager &AM);
139 };
140 
141 struct RecomputeGlobalsAAPass : PassInfoMixin<RecomputeGlobalsAAPass> {
142   LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
143 };
144 
145 /// Legacy wrapper pass to provide the GlobalsAAResult object.
146 class LLVM_ABI GlobalsAAWrapperPass : public ModulePass {
147   std::unique_ptr<GlobalsAAResult> Result;
148 
149 public:
150   static char ID;
151 
152   GlobalsAAWrapperPass();
153 
getResult()154   GlobalsAAResult &getResult() { return *Result; }
getResult()155   const GlobalsAAResult &getResult() const { return *Result; }
156 
157   bool runOnModule(Module &M) override;
158   bool doFinalization(Module &M) override;
159   void getAnalysisUsage(AnalysisUsage &AU) const override;
160 };
161 
162 //===--------------------------------------------------------------------===//
163 //
164 // createGlobalsAAWrapperPass - This pass provides alias and mod/ref info for
165 // global values that do not have their addresses taken.
166 //
167 LLVM_ABI ModulePass *createGlobalsAAWrapperPass();
168 }
169 
170 #endif
171