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