1 | //===- GlobalsModRef.h - Simple Mod/Ref AA for Globals ----------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | /// \file |
10 | /// This is the interface for a simple mod/ref and alias analysis over globals. |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_ANALYSIS_GLOBALSMODREF_H |
15 | #define LLVM_ANALYSIS_GLOBALSMODREF_H |
16 | |
17 | #include "llvm/Analysis/AliasAnalysis.h" |
18 | #include "llvm/Analysis/CallGraph.h" |
19 | #include "llvm/IR/Constants.h" |
20 | #include "llvm/IR/Function.h" |
21 | #include "llvm/IR/Module.h" |
22 | #include "llvm/IR/ValueHandle.h" |
23 | #include "llvm/Pass.h" |
24 | #include <list> |
25 | |
26 | namespace llvm { |
27 | |
28 | /// An alias analysis result set for globals. |
29 | /// |
30 | /// This focuses on handling aliasing properties of globals and interprocedural |
31 | /// function call mod/ref information. |
32 | class GlobalsAAResult : public AAResultBase<GlobalsAAResult> { |
33 | friend AAResultBase<GlobalsAAResult>; |
34 | |
35 | class FunctionInfo; |
36 | |
37 | const DataLayout &DL; |
38 | const TargetLibraryInfo &TLI; |
39 | |
40 | /// The globals that do not have their addresses taken. |
41 | SmallPtrSet<const GlobalValue *, 8> NonAddressTakenGlobals; |
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 DeletionCallbackHandle final : CallbackVH { |
61 | GlobalsAAResult *GAR; |
62 | std::list<DeletionCallbackHandle>::iterator I; |
63 | |
64 | 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(const DataLayout &DL, const TargetLibraryInfo &TLI); |
77 | |
78 | public: |
79 | GlobalsAAResult(GlobalsAAResult &&Arg); |
80 | ~GlobalsAAResult(); |
81 | |
82 | static GlobalsAAResult analyzeModule(Module &M, const TargetLibraryInfo &TLI, |
83 | CallGraph &CG); |
84 | |
85 | //------------------------------------------------ |
86 | // Implement the AliasAnalysis API |
87 | // |
88 | AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); |
89 | |
90 | using AAResultBase::getModRefInfo; |
91 | ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc); |
92 | |
93 | /// getModRefBehavior - Return the behavior of the specified function if |
94 | /// called from the specified call site. The call site may be null in which |
95 | /// case the most generic behavior of this function should be returned. |
96 | FunctionModRefBehavior getModRefBehavior(const Function *F); |
97 | |
98 | /// getModRefBehavior - Return the behavior of the specified function if |
99 | /// called from the specified call site. The call site may be null in which |
100 | /// case the most generic behavior of this function should be returned. |
101 | FunctionModRefBehavior getModRefBehavior(const CallBase *Call); |
102 | |
103 | private: |
104 | FunctionInfo *getFunctionInfo(const Function *F); |
105 | |
106 | void AnalyzeGlobals(Module &M); |
107 | void AnalyzeCallGraph(CallGraph &CG, Module &M); |
108 | bool AnalyzeUsesOfPointer(Value *V, |
109 | SmallPtrSetImpl<Function *> *Readers = nullptr, |
110 | SmallPtrSetImpl<Function *> *Writers = nullptr, |
111 | GlobalValue *OkayStoreDest = nullptr); |
112 | bool AnalyzeIndirectGlobalMemory(GlobalVariable *GV); |
113 | void CollectSCCMembership(CallGraph &CG); |
114 | |
115 | bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V); |
116 | ModRefInfo getModRefInfoForArgument(const CallBase *Call, |
117 | const GlobalValue *GV); |
118 | }; |
119 | |
120 | /// Analysis pass providing a never-invalidated alias analysis result. |
121 | class GlobalsAA : public AnalysisInfoMixin<GlobalsAA> { |
122 | friend AnalysisInfoMixin<GlobalsAA>; |
123 | static AnalysisKey Key; |
124 | |
125 | public: |
126 | typedef GlobalsAAResult Result; |
127 | |
128 | GlobalsAAResult run(Module &M, ModuleAnalysisManager &AM); |
129 | }; |
130 | |
131 | /// Legacy wrapper pass to provide the GlobalsAAResult object. |
132 | class GlobalsAAWrapperPass : public ModulePass { |
133 | std::unique_ptr<GlobalsAAResult> Result; |
134 | |
135 | public: |
136 | static char ID; |
137 | |
138 | GlobalsAAWrapperPass(); |
139 | |
140 | GlobalsAAResult &getResult() { return *Result; } |
141 | const GlobalsAAResult &getResult() const { return *Result; } |
142 | |
143 | bool runOnModule(Module &M) override; |
144 | bool doFinalization(Module &M) override; |
145 | void getAnalysisUsage(AnalysisUsage &AU) const override; |
146 | }; |
147 | |
148 | //===--------------------------------------------------------------------===// |
149 | // |
150 | // createGlobalsAAWrapperPass - This pass provides alias and mod/ref info for |
151 | // global values that do not have their addresses taken. |
152 | // |
153 | ModulePass *createGlobalsAAWrapperPass(); |
154 | } |
155 | |
156 | #endif |
157 | |