/builds/2mk6rsew/0/parcoach/parcoach/src/include/parcoach/MemorySSA.h
Line | Count | Source |
1 | | #pragma once |
2 | | |
3 | | #include "parcoach/ExtInfo.h" |
4 | | #include "parcoach/MemoryRegion.h" |
5 | | #include "parcoach/andersen/Andersen.h" |
6 | | |
7 | | #include "llvm/ADT/DenseMap.h" |
8 | | #include "llvm/Analysis/DominanceFrontier.h" |
9 | | #include "llvm/IR/ValueMap.h" |
10 | | |
11 | | #include <map> |
12 | | |
13 | | class DepGraphDCF; |
14 | | class PTACallGraph; |
15 | | class MSSAMu; |
16 | | class MSSAChi; |
17 | | class MSSAPhi; |
18 | | class MSSAVar; |
19 | | |
20 | | namespace llvm { |
21 | | class PostDominatorTree; |
22 | | } |
23 | | |
24 | | namespace parcoach { |
25 | | class ModRefAnalysisResult; |
26 | | class MemorySSA { |
27 | | |
28 | | // Containers for Mu,Chi,Phi,BB and Values |
29 | | using MuOwnerSet = std::vector<std::unique_ptr<MSSAMu>>; |
30 | | using ChiOwnerSet = std::vector<std::unique_ptr<MSSAChi>>; |
31 | | using PhiOwnerSet = std::vector<std::unique_ptr<MSSAPhi>>; |
32 | | using MuSet = std::set<MSSAMu *>; |
33 | | using ChiSet = std::set<MSSAChi *>; |
34 | | using PhiSet = std::set<MSSAPhi *>; |
35 | | using BBSet = std::set<llvm::BasicBlock const *>; |
36 | | using ValueSet = std::set<llvm::Value const *>; |
37 | | |
38 | | // Chi and Mu annotations |
39 | | using LoadToMuMap = llvm::ValueMap<llvm::LoadInst const *, MuOwnerSet>; |
40 | | using StoreToChiMap = llvm::ValueMap<llvm::StoreInst const *, ChiOwnerSet>; |
41 | | using CallSiteToMuSetMap = llvm::ValueMap<llvm::CallBase const *, MuOwnerSet>; |
42 | | using CallSiteToChiSetMap = llvm::ValueMap<llvm::CallBase *, ChiOwnerSet>; |
43 | | using FuncCallSiteToChiMap = |
44 | | llvm::ValueMap<llvm::Function const *, |
45 | | std::map<llvm::CallBase *, std::unique_ptr<MSSAChi>>>; |
46 | | using FuncCallSiteToArgChiMap = |
47 | | llvm::ValueMap<llvm::Function const *, |
48 | | std::map<llvm::CallBase *, std::map<unsigned, MSSAChi *>>>; |
49 | | |
50 | | // Phis |
51 | | using BBToPhiMap = llvm::ValueMap<llvm::BasicBlock const *, PhiOwnerSet>; |
52 | | using MemRegToBBMap = std::map<MemRegEntry *, BBSet>; |
53 | | using LLVMPhiToPredMap = llvm::ValueMap<llvm::PHINode const *, ValueSet>; |
54 | | |
55 | | // Map functions to entry Chi set and return Mu set |
56 | | using FunToEntryChiMap = llvm::ValueMap<llvm::Function const *, ChiOwnerSet>; |
57 | | using FunToReturnMuMap = llvm::ValueMap<llvm::Function const *, MuOwnerSet>; |
58 | | |
59 | | using FunRegToEntryChiMap = |
60 | | llvm::ValueMap<llvm::Function const *, |
61 | | std::map<MemRegEntry *, MSSAChi *>>; |
62 | | using FunRegToReturnMuMap = |
63 | | llvm::ValueMap<llvm::Function const *, std::map<MemRegEntry *, MSSAMu *>>; |
64 | | |
65 | | using FuncToChiMap = llvm::ValueMap<llvm::Function const *, MSSAChi *>; |
66 | | using FuncToArgChiMap = |
67 | | llvm::ValueMap<llvm::Function const *, std::map<unsigned, MSSAChi *>>; |
68 | | using FuncToCallBaseSet = |
69 | | llvm::ValueMap<llvm::Function const *, std::set<llvm::CallBase *>>; |
70 | | |
71 | | public: |
72 | | MemorySSA(llvm::Module &M, Andersen const &PTA, PTACallGraph const &CG, |
73 | | MemReg const &Regions, ModRefAnalysisResult *MRA, |
74 | | ExtInfo const &extInfo, llvm::ModuleAnalysisManager &AM); |
75 | | virtual ~MemorySSA(); |
76 | | |
77 | | private: |
78 | | void dumpMSSA(llvm::Function const *F); |
79 | | |
80 | | void buildSSA(llvm::Module &M, llvm::ModuleAnalysisManager &AM); |
81 | | void buildSSA(llvm::Function const *F, llvm::DominatorTree &DT, |
82 | | llvm::DominanceFrontier &DF, llvm::PostDominatorTree &PDT); |
83 | | |
84 | | void createArtificalChiForCalledFunction(llvm::CallBase *CB, |
85 | | llvm::Function const *callee); |
86 | | |
87 | | void computeMuChi(llvm::Function const *F); |
88 | | |
89 | | void computeMuChiForCalledFunction(llvm::CallBase *inst, |
90 | | llvm::Function *callee); |
91 | | |
92 | | // The three following functions generate SSA from mu/chi by implementing the |
93 | | // algorithm from the paper: |
94 | | // R. Cytron, J. Ferrante, B. K. Rosen, M. N. Wegman, and F. K. |
95 | | // Zadeck, “Efficiently computing static single assignment form and |
96 | | // the control dependence graph,” ACM Trans. Program. Lang. Syst., |
97 | | // vol. 13, no. 4, pp. 451–490, Oct. 1991. |
98 | | // http://doi.acm.org/10.1145/115372.115320 |
99 | | void computePhi(llvm::Function const *F); |
100 | | void rename(llvm::Function const *F); |
101 | | void renameBB(llvm::Function const *F, llvm::BasicBlock const *X, |
102 | | std::map<MemRegEntry *, unsigned> &C, |
103 | | std::map<MemRegEntry *, std::vector<MSSAVar *>> &S); |
104 | | |
105 | | void computePhiPredicates(llvm::Function const *F); |
106 | | void computeLLVMPhiPredicates(llvm::PHINode const *phi); |
107 | | void computeMSSAPhiPredicates(MSSAPhi *phi); |
108 | | |
109 | | static unsigned whichPred(llvm::BasicBlock const *pred, |
110 | | llvm::BasicBlock const *succ); |
111 | | |
112 | | protected: |
113 | | Andersen const &PTA; |
114 | | PTACallGraph const &CG; |
115 | | MemReg const &Regions; |
116 | | ModRefAnalysisResult *MRA; |
117 | | ExtInfo const &extInfo; |
118 | | |
119 | | llvm::DominanceFrontier *curDF; |
120 | | llvm::DominatorTree *curDT; |
121 | | llvm::PostDominatorTree *curPDT; |
122 | | MemRegSet usedRegs; |
123 | | MemRegToBBMap regDefToBBMap; |
124 | | |
125 | | LoadToMuMap loadToMuMap; |
126 | | StoreToChiMap storeToChiMap; |
127 | | CallSiteToMuSetMap callSiteToMuMap; |
128 | | CallSiteToChiSetMap callSiteToChiMap; |
129 | | CallSiteToChiSetMap callSiteToSyncChiMap; |
130 | | BBToPhiMap bbToPhiMap; |
131 | | FunToEntryChiMap funToEntryChiMap; |
132 | | FunToReturnMuMap funToReturnMuMap; |
133 | | LLVMPhiToPredMap llvmPhiToPredMap; |
134 | | FunRegToEntryChiMap funRegToEntryChiMap; |
135 | | FunRegToReturnMuMap funRegToReturnMuMap; |
136 | | // External function artifical chis. |
137 | | CallSiteToChiSetMap extCallSiteToCallerRetChi; // inside caller (necessary |
138 | | // because there is no mod/ref analysis for external functions). |
139 | | FuncCallSiteToChiMap extCallSiteToCalleeRetChi; |
140 | | FuncCallSiteToChiMap extCallSiteToVarArgEntryChi; |
141 | | FuncCallSiteToChiMap extCallSiteToVarArgExitChi; |
142 | | FuncCallSiteToArgChiMap extCallSiteToArgEntryChi; |
143 | | FuncCallSiteToArgChiMap extCallSiteToArgExitChi; |
144 | | // Owner of chis allocated in the 2 ArgChi maps above; the data structure |
145 | | // makes it impossible to hold the unique_ptr in a map in a map in a map... |
146 | | ChiOwnerSet AllocatedArgChi; |
147 | | FuncToCallBaseSet extFuncToCSMap; |
148 | | |
149 | | public: |
150 | 43.9k | auto const &getLoadToMuMap() const { return loadToMuMap; } |
151 | 26.4k | auto const &getStoreToChiMap() const { return storeToChiMap; } |
152 | 27.5k | auto const &getCSToMuMap() const { return callSiteToMuMap; } |
153 | 27.5k | auto const &getCSToChiMap() const { return callSiteToChiMap; }; |
154 | 27.5k | auto const &getCSToSynChiMap() const { return callSiteToSyncChiMap; }; |
155 | 30.4k | auto const &getBBToPhiMap() const { return bbToPhiMap; }; |
156 | 17.9k | auto const &getFunToEntryChiMap() const { return funToEntryChiMap; }; |
157 | 49 | auto const &getPhiToPredMap() const { return llvmPhiToPredMap; } |
158 | 215 | auto const &getFunRegToEntryChiMap() const { return funRegToEntryChiMap; } |
159 | 31 | auto const &getFunRegToReturnMuMap() const { return funRegToReturnMuMap; } |
160 | 2.60k | auto const &getExtCSToCallerRetChi() const { |
161 | 2.60k | return extCallSiteToCallerRetChi; |
162 | 2.60k | } |
163 | 8.40k | auto const &getExtCSToCalleeRetChi() const { |
164 | 8.40k | return extCallSiteToCalleeRetChi; |
165 | 8.40k | } |
166 | 12.0k | auto const &getExtCSToVArgEntryChi() const { |
167 | 12.0k | return extCallSiteToVarArgEntryChi; |
168 | 12.0k | } |
169 | 12.0k | auto const &getExtCSToVArgExitChi() const { |
170 | 12.0k | return extCallSiteToVarArgExitChi; |
171 | 12.0k | } |
172 | 115k | auto const &getExtCSToArgEntryChi() const { return extCallSiteToArgEntryChi; } |
173 | 79.4k | auto const &getExtCSToArgExitChi() const { return extCallSiteToArgExitChi; } |
174 | 16.1k | auto const &getExtFuncToCSMap() const { return extFuncToCSMap; } |
175 | | }; |
176 | | |
177 | | class MemorySSAAnalysis : public llvm::AnalysisInfoMixin<MemorySSAAnalysis> { |
178 | | friend llvm::AnalysisInfoMixin<MemorySSAAnalysis>; |
179 | | static llvm::AnalysisKey Key; |
180 | | |
181 | | public: |
182 | | // We return a unique_ptr to ensure stability of the analysis' internal state. |
183 | | using Result = std::unique_ptr<MemorySSA>; |
184 | | static Result run(llvm::Module &M, llvm::ModuleAnalysisManager &); |
185 | | }; |
186 | | } // namespace parcoach |