Static Value-Flow Analysis
MemSSA.h
Go to the documentation of this file.
1 //===- MemSSA.h -- Memory SSA-------------------------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * MemorySSAPass.h
25  *
26  * Created on: Jul 14, 2013
27  * Author: Yulei Sui
28  *
29  * The implementation is based on
30  * Yulei Sui, Hua Yan, Yunpeng Zhang, Jingling Xue and Zheng Zheng.
31  * "Parallel Construction of Interprocedural Memory SSA Form".
32  * Journal of Systems and Software (JSS'16), Algorithm 3 in the paper
33  */
34 
35 
36 #ifndef MEMORYSSAPASS_H_
37 #define MEMORYSSAPASS_H_
38 
39 #include "MSSA/MemRegion.h"
40 #include "MSSA/MSSAMuChi.h"
41 
42 #include <vector>
43 
44 namespace SVF
45 {
46 
47 class PointerAnalysis;
48 class MemSSAStat;
49 /*
50  * Memory SSA implementation on top of partial SSA
51  */
52 class MemSSA
53 {
54 
55 public:
56 
68  typedef MSSADEF MDEF;
69 
70  typedef Set<MU*> MUSet;
71  typedef Set<CHI*> CHISet;
72  typedef Set<PHI*> PHISet;
73 
76  typedef std::vector<const MemRegion*> MRVector;
79 
86 
90 
92 
93  typedef std::vector<const SVFBasicBlock*> BBList;
97 
101 
104 
106 
108  static double timeOfCreateMUCHI;
109  static double timeOfInsertingPHI;
110  static double timeOfSSARenaming;
112 
114  {
118  };
119 
120 protected:
124 
126  virtual void createMUCHI(const SVFFunction& fun);
128  virtual void insertPHI(const SVFFunction& fun);
130  virtual void SSARename(const SVFFunction& fun);
132  virtual void SSARenameBB(const SVFBasicBlock& bb);
133 private:
139 
142 
145 
147  // (see algorithm in book Engineering A Compiler section 9.3)
156 
157  std::vector<std::unique_ptr<MRVer>> usedMRVers;
158 
160  void destroy();
161 
163  MRVer* newSSAName(const MemRegion* mr, MSSADEF* def);
164 
166  inline MRVer* getTopStackVer(const MemRegion* mr)
167  {
168  std::vector<MRVer*> &stack = mr2VerStackMap[mr];
169  assert(!stack.empty() && "stack is empty!!");
170  return stack.back();
171  }
172 
174 
175  inline void collectRegUses(const MemRegion* mr)
176  {
177  if (0 == varKills.count(mr))
178  usedRegs.insert(mr);
179  }
180  inline void collectRegDefs(const SVFBasicBlock* bb, const MemRegion* mr)
181  {
182  varKills.insert(mr);
183  reg2BBMap[mr].push_back(bb);
184  }
186 
188 
189  inline void AddLoadMU(const SVFBasicBlock* bb, const LoadStmt* load, const MRSet& mrSet)
190  {
191  for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter)
192  AddLoadMU(bb,load,*iter);
193  }
194  inline void AddStoreCHI(const SVFBasicBlock* bb, const StoreStmt* store, const MRSet& mrSet)
195  {
196  for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter)
197  AddStoreCHI(bb,store,*iter);
198  }
199  inline void AddCallSiteMU(const CallICFGNode* cs, const MRSet& mrSet)
200  {
201  for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter)
202  AddCallSiteMU(cs,*iter);
203  }
204  inline void AddCallSiteCHI(const CallICFGNode* cs, const MRSet& mrSet)
205  {
206  for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter)
207  AddCallSiteCHI(cs,*iter);
208  }
209  inline void AddMSSAPHI(const SVFBasicBlock* bb, const MRSet& mrSet)
210  {
211  for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter)
212  AddMSSAPHI(bb,*iter);
213  }
214  inline void AddLoadMU(const SVFBasicBlock* bb, const LoadStmt* load, const MemRegion* mr)
215  {
216  LOADMU* mu = new LOADMU(bb,load, mr);
217  load2MuSetMap[load].insert(mu);
218  collectRegUses(mr);
219  }
220  inline void AddStoreCHI(const SVFBasicBlock* bb, const StoreStmt* store, const MemRegion* mr)
221  {
222  STORECHI* chi = new STORECHI(bb,store, mr);
223  store2ChiSetMap[store].insert(chi);
224  collectRegUses(mr);
225  collectRegDefs(bb,mr);
226  }
227  inline void AddCallSiteMU(const CallICFGNode* cs, const MemRegion* mr)
228  {
229  CALLMU* mu = new CALLMU(cs, mr);
230  callsiteToMuSetMap[cs].insert(mu);
231  collectRegUses(mr);
232  }
233  inline void AddCallSiteCHI(const CallICFGNode* cs, const MemRegion* mr)
234  {
235  CALLCHI* chi = new CALLCHI(cs, mr);
236  callsiteToChiSetMap[cs].insert(chi);
237  collectRegUses(mr);
238  collectRegDefs(chi->getBasicBlock(),mr);
239  }
240  inline void AddMSSAPHI(const SVFBasicBlock* bb, const MemRegion* mr)
241  {
242  bb2PhiSetMap[bb].insert(new PHI(bb, mr));
243  }
245 
247 
248  inline void RenameMuSet(const MUSet& muSet)
250  {
251  for (MUSet::const_iterator mit = muSet.begin(), emit = muSet.end();
252  mit != emit; ++mit)
253  {
254  MU* mu = (*mit);
255  mu->setVer(getTopStackVer(mu->getMR()));
256  }
257  }
258 
260  inline void RenameChiSet(const CHISet& chiSet, MRVector& memRegs)
261  {
262  for (CHISet::const_iterator cit = chiSet.begin(), ecit = chiSet.end();
263  cit != ecit; ++cit)
264  {
265  CHI* chi = (*cit);
266  chi->setOpVer(getTopStackVer(chi->getMR()));
267  chi->setResVer(newSSAName(chi->getMR(),chi));
268  memRegs.push_back(chi->getMR());
269  }
270  }
271 
273  inline void RenamePhiRes(const PHISet& phiSet, MRVector& memRegs)
274  {
275  for (PHISet::const_iterator iter = phiSet.begin(), eiter = phiSet.end();
276  iter != eiter; ++iter)
277  {
278  PHI* phi = *iter;
279  phi->setResVer(newSSAName(phi->getMR(),phi));
280  memRegs.push_back(phi->getMR());
281  }
282  }
283 
285  inline void RenamePhiOps(const PHISet& phiSet, u32_t pos, MRVector&)
286  {
287  for (PHISet::const_iterator iter = phiSet.begin(), eiter = phiSet.end();
288  iter != eiter; ++iter)
289  {
290  PHI* phi = *iter;
291  phi->setOpVer(getTopStackVer(phi->getMR()), pos);
292  }
293  }
295 
296 public:
298  MemSSA(BVDataPTAImpl* p, bool ptrOnlyMSSA);
299 
301  virtual ~MemSSA()
302  {
303  destroy();
304  }
306  inline SVFIR* getPAG();
308  inline BVDataPTAImpl* getPTA() const
309  {
310  return pta;
311  }
314  {
315  return mrGen;
316  }
318  virtual void buildMemSSA(const SVFFunction& fun);
319 
321  void performStat();
322 
324 
325  inline bool hasMU(const PAGEdge* inst) const
326  {
327  if (const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(inst))
328  {
329  bool hasMu = load2MuSetMap.count(load) != 0;
330  assert(hasMu && "not associated with mem region!");
331  return hasMu;
332  }
333  else
334  return false;
335  }
336  inline bool hasCHI(const PAGEdge* inst) const
337  {
338  if (const StoreStmt* store = SVFUtil::dyn_cast<StoreStmt>(
339  inst))
340  {
341  bool has_store = store2ChiSetMap.count(store) != 0;
342  assert(has_store && "not associated with mem region!");
343  return has_store;
344  }
345  else
346  return false;
347  }
348  inline bool hasMU(const CallICFGNode* cs) const
349  {
350  return callsiteToMuSetMap.find(cs)!=callsiteToMuSetMap.end();
351  }
352  inline bool hasCHI(const CallICFGNode* cs) const
353  {
354  return callsiteToChiSetMap.find(cs)!=callsiteToChiSetMap.end();
355  }
357 
359 
360  inline bool hasFuncEntryChi(const SVFFunction * fun) const
361  {
362  return (funToEntryChiSetMap.find(fun) != funToEntryChiSetMap.end());
363  }
364  inline bool hasReturnMu(const SVFFunction * fun) const
365  {
366  return (funToReturnMuSetMap.find(fun) != funToReturnMuSetMap.end());
367  }
368 
369  inline CHISet& getFuncEntryChiSet(const SVFFunction * fun)
370  {
371  return funToEntryChiSetMap[fun];
372  }
373  inline MUSet& getReturnMuSet(const SVFFunction * fun)
374  {
375  return funToReturnMuSetMap[fun];
376  }
378 
380 
381  inline MUSet& getMUSet(const LoadStmt* ld)
382  {
383  return load2MuSetMap[ld];
384  }
385  inline CHISet& getCHISet(const StoreStmt* st)
386  {
387  return store2ChiSetMap[st];
388  }
389  inline MUSet& getMUSet(const CallICFGNode* cs)
390  {
391  return callsiteToMuSetMap[cs];
392  }
393  inline CHISet& getCHISet(const CallICFGNode* cs)
394  {
395  return callsiteToChiSetMap[cs];
396  }
397  inline PHISet& getPHISet(const SVFBasicBlock* bb)
398  {
399  return bb2PhiSetMap[bb];
400  }
401  inline bool hasPHISet(const SVFBasicBlock* bb) const
402  {
403  return bb2PhiSetMap.find(bb)!=bb2PhiSetMap.end();
404  }
406  {
407  return load2MuSetMap;
408  }
410  {
411  return store2ChiSetMap;
412  }
414  {
415  return funToReturnMuSetMap;
416  }
418  {
419  return funToEntryChiSetMap;
420  }
422  {
423  return callsiteToMuSetMap;
424  }
426  {
427  return callsiteToChiSetMap;
428  }
430  {
431  return bb2PhiSetMap;
432  }
434 
436 
437  u32_t getLoadMuNum() const;
438  u32_t getStoreChiNum() const;
439  u32_t getFunEntryChiNum() const;
440  u32_t getFunRetMuNum() const;
441  u32_t getCallSiteMuNum() const;
442  u32_t getCallSiteChiNum() const;
443  u32_t getBBPhiNum() const;
445 
447  void dumpMSSA(OutStream & Out = SVFUtil::outs());
448 };
449 
450 } // End namespace SVF
451 
452 #endif /* MEMORYSSAPASS_H_ */
cJSON * p
Definition: cJSON.cpp:2559
const SVFBasicBlock * getBasicBlock() const
Return basic block.
Definition: MSSAMuChi.h:538
OrderedSet< const MemRegion *, MemRegion::equalMemRegion > MRSet
Get typedef from Pointer Analysis.
Definition: MemRegion.h:141
void setOpVer(MRVer *v)
Set operand ver.
Definition: MSSAMuChi.h:414
void setResVer(MRVer *v)
Set result operand ver.
Definition: MSSAMuChi.h:366
const MemRegion * getMR() const
Return memory region.
Definition: MSSAMuChi.h:354
void setOpVer(const MRVer *v, u32_t pos)
Set operand ver.
Definition: MSSAMuChi.h:651
Memory Region class.
Definition: MemRegion.h:56
bool Condition
Definition: MemRegion.h:59
CallSiteToMUSetMap & getCallSiteToMuSetMap()
Definition: MemSSA.h:421
void AddStoreCHI(const SVFBasicBlock *bb, const StoreStmt *store, const MemRegion *mr)
Definition: MemSSA.h:220
std::vector< const SVFBasicBlock * > BBList
For phi insertion.
Definition: MemSSA.h:93
void RenamePhiOps(const PHISet &phiSet, u32_t pos, MRVector &)
Rename operands (RHS) of phis.
Definition: MemSSA.h:285
CHISet & getFuncEntryChiSet(const SVFFunction *fun)
Definition: MemSSA.h:369
StoreCHI< Condition > STORECHI
Definition: MemSSA.h:65
u32_t getFunEntryChiNum() const
Definition: MemSSA.cpp:491
virtual void SSARename(const SVFFunction &fun)
SSA rename for a function.
Definition: MemSSA.cpp:248
BBToPhiSetMap bb2PhiSetMap
Definition: MemSSA.h:138
CallSiteToCHISetMap callsiteToChiSetMap
Definition: MemSSA.h:137
MRGenerator * mrGen
Definition: MemSSA.h:122
MemRegToCounterMap mr2CounterMap
Definition: MemSSA.h:144
void RenameMuSet(const MUSet &muSet)
Rename mus, chis and phis.
Definition: MemSSA.h:249
MSSAMU< Condition > MU
Definition: MemSSA.h:59
u32_t getCallSiteChiNum() const
Definition: MemSSA.cpp:542
CHISet & getCHISet(const StoreStmt *st)
Definition: MemSSA.h:385
bool hasReturnMu(const SVFFunction *fun) const
Definition: MemSSA.h:364
void collectRegDefs(const SVFBasicBlock *bb, const MemRegion *mr)
Definition: MemSSA.h:180
MRGenerator::MRSet MRSet
Define mem region set.
Definition: MemSSA.h:75
static double timeOfGeneratingMemRegions
Statistics.
Definition: MemSSA.h:107
MRVer * newSSAName(const MemRegion *mr, MSSADEF *def)
Get a new SSA name of a memory region.
Definition: MemSSA.cpp:346
void AddStoreCHI(const SVFBasicBlock *bb, const StoreStmt *store, const MRSet &mrSet)
Definition: MemSSA.h:194
static double timeOfInsertingPHI
Time for inserting phis.
Definition: MemSSA.h:109
Map< const SVFFunction *, MUSet > FunToReturnMuSetMap
Definition: MemSSA.h:89
void destroy()
Release the memory.
Definition: MemSSA.cpp:365
SVFIR * getPAG()
Return SVFIR.
Definition: MemSSA.cpp:71
bool hasPHISet(const SVFBasicBlock *bb) const
Definition: MemSSA.h:401
void AddLoadMU(const SVFBasicBlock *bb, const LoadStmt *load, const MRSet &mrSet)
Add methods for mus/chis/phis.
Definition: MemSSA.h:189
Map< const CallICFGNode *, CHISet > CallSiteToCHISetMap
Definition: MemSSA.h:83
SVFIR::SVFStmtList SVFStmtList
SVFIR edge list.
Definition: MemSSA.h:103
FunToReturnMuSetMap & getFunToRetMuSetMap()
Definition: MemSSA.h:413
BVDataPTAImpl * pta
Definition: MemSSA.h:121
LoadMU< Condition > LOADMU
Definition: MemSSA.h:61
static double timeOfCreateMUCHI
Time for generating mu/chi for load/store/calls.
Definition: MemSSA.h:108
virtual void buildMemSSA(const SVFFunction &fun)
We start from here.
Definition: MemSSA.cpp:79
MemSSAStat * stat
Definition: MemSSA.h:123
MSSACHI< Condition > CHI
Definition: MemSSA.h:63
CallCHI< Condition > CALLCHI
Definition: MemSSA.h:66
MSSADEF MDEF
Definition: MemSSA.h:68
FunToEntryChiSetMap funToEntryChiSetMap
Definition: MemSSA.h:140
LoadToMUSetMap load2MuSetMap
Definition: MemSSA.h:134
Map< const CallICFGNode *, MUSet > CallSiteToMUSetMap
Definition: MemSSA.h:82
void RenameChiSet(const CHISet &chiSet, MRVector &memRegs)
Rename chi set.
Definition: MemSSA.h:260
void RenamePhiRes(const PHISet &phiSet, MRVector &memRegs)
Rename result (LHS) of phis.
Definition: MemSSA.h:273
u32_t getFunRetMuNum() const
Definition: MemSSA.cpp:508
virtual void createMUCHI(const SVFFunction &fun)
Create mu chi for candidate regions in a function.
Definition: MemSSA.cpp:114
EntryCHI< Condition > ENTRYCHI
Definition: MemSSA.h:64
MemSSA(BVDataPTAImpl *p, bool ptrOnlyMSSA)
Constructor.
Definition: MemSSA.cpp:46
bool hasMU(const CallICFGNode *cs) const
Definition: MemSSA.h:348
std::vector< std::unique_ptr< MRVer > > usedMRVers
Definition: MemSSA.h:157
LoadToMUSetMap & getLoadToMUSetMap()
Definition: MemSSA.h:405
StoreToChiSetMap store2ChiSetMap
Definition: MemSSA.h:135
void dumpMSSA(OutStream &Out=SVFUtil::outs())
Print Memory SSA.
Definition: MemSSA.cpp:575
CallMU< Condition > CALLMU
Definition: MemSSA.h:62
void AddMSSAPHI(const SVFBasicBlock *bb, const MemRegion *mr)
Definition: MemSSA.h:240
std::vector< const MemRegion * > MRVector
Definition: MemSSA.h:76
void collectRegUses(const MemRegion *mr)
Collect region uses and region defs according to mus/chis, in order to insert phis.
Definition: MemSSA.h:175
Set< MU * > MUSet
Definition: MemSSA.h:70
PHISet & getPHISet(const SVFBasicBlock *bb)
Definition: MemSSA.h:397
void performStat()
Perform statistics.
Definition: MemSSA.cpp:448
Set< PHI * > PHISet
Definition: MemSSA.h:72
Map< const MemRegion *, BBList > MemRegToBBsMap
Definition: MemSSA.h:95
MSSAPHI< Condition > PHI
Definition: MemSSA.h:67
void AddCallSiteMU(const CallICFGNode *cs, const MRSet &mrSet)
Definition: MemSSA.h:199
CallSiteToCHISetMap & getCallSiteToChiSetMap()
Definition: MemSSA.h:425
Map< const LoadStmt *, MUSet > LoadToMUSetMap
Definition: MemSSA.h:80
RetMU< Condition > RETMU
Definition: MemSSA.h:60
CHISet & getCHISet(const CallICFGNode *cs)
Definition: MemSSA.h:393
BBToPhiSetMap & getBBToPhiSetMap()
Definition: MemSSA.h:429
StoreToChiSetMap & getStoreToChiSetMap()
Definition: MemSSA.h:409
static double timeOfSSARenaming
Time for SSA rename.
Definition: MemSSA.h:110
u32_t getBBPhiNum() const
Definition: MemSSA.cpp:559
u32_t getCallSiteMuNum() const
Definition: MemSSA.cpp:525
u32_t getStoreChiNum() const
Definition: MemSSA.cpp:474
Map< const MemRegion *, std::vector< MRVer * > > MemRegToVerStackMap
For SSA renaming.
Definition: MemSSA.h:99
u32_t getLoadMuNum() const
Stat methods.
Definition: MemSSA.cpp:457
MRGenerator * getMRGenerator()
Return MRGenerator.
Definition: MemSSA.h:313
CallSiteToMUSetMap callsiteToMuSetMap
Definition: MemSSA.h:136
FunToReturnMuSetMap funToReturnMuSetMap
Definition: MemSSA.h:141
bool hasCHI(const PAGEdge *inst) const
Definition: MemSSA.h:336
@ InterDisjoint
Definition: MemSSA.h:117
@ Distinct
Definition: MemSSA.h:115
@ IntraDisjoint
Definition: MemSSA.h:116
MemRegion::Condition Condition
define condition here changes needed if we add new type
Definition: MemSSA.h:58
Map< const SVFFunction *, CHISet > FunToEntryChiSetMap
Map from fun to its entry chi set and return mu set.
Definition: MemSSA.h:88
virtual void insertPHI(const SVFFunction &fun)
Insert phi for candidate regions in a function.
Definition: MemSSA.cpp:200
MRSet usedRegs
The following three set are used for prune SSA phi insertion.
Definition: MemSSA.h:150
Map< const SVFBasicBlock *, MRSet > BBToMRSetMap
Definition: MemSSA.h:94
Map< const StoreStmt *, CHISet > StoreToChiSetMap
Definition: MemSSA.h:81
BVDataPTAImpl * getPTA() const
Return PTA.
Definition: MemSSA.h:308
MRVer * getTopStackVer(const MemRegion *mr)
Get the last version of the SSA ver of memory region.
Definition: MemSSA.h:166
void AddCallSiteCHI(const CallICFGNode *cs, const MRSet &mrSet)
Definition: MemSSA.h:204
void AddCallSiteMU(const CallICFGNode *cs, const MemRegion *mr)
Definition: MemSSA.h:227
MemRegToBBsMap reg2BBMap
Maps memory region to its basic block.
Definition: MemSSA.h:152
virtual ~MemSSA()
Destructor.
Definition: MemSSA.h:301
bool hasCHI(const CallICFGNode *cs) const
Definition: MemSSA.h:352
Map< const MemRegion *, MRVERSION > MemRegToCounterMap
Definition: MemSSA.h:100
void AddMSSAPHI(const SVFBasicBlock *bb, const MRSet &mrSet)
Definition: MemSSA.h:209
MemRegToVerStackMap mr2VerStackMap
Definition: MemSSA.h:143
MRSet varKills
Collect memory regions whose definition killed.
Definition: MemSSA.h:154
virtual void SSARenameBB(const SVFBasicBlock &bb)
SSA rename for a basic block.
Definition: MemSSA.cpp:261
bool hasFuncEntryChi(const SVFFunction *fun) const
Has function entry chi or return mu.
Definition: MemSSA.h:360
MUSet & getMUSet(const CallICFGNode *cs)
Definition: MemSSA.h:389
void AddLoadMU(const SVFBasicBlock *bb, const LoadStmt *load, const MemRegion *mr)
Definition: MemSSA.h:214
MUSet & getMUSet(const LoadStmt *ld)
Get methods of mu/chi/phi.
Definition: MemSSA.h:381
bool hasMU(const PAGEdge *inst) const
Has mu/chi methods.
Definition: MemSSA.h:325
void AddCallSiteCHI(const CallICFGNode *cs, const MemRegion *mr)
Definition: MemSSA.h:233
MUSet & getReturnMuSet(const SVFFunction *fun)
Definition: MemSSA.h:373
OrderedMap< const SVFBasicBlock *, PHISet > BBToPhiSetMap
Definition: MemSSA.h:84
Set< CHI * > CHISet
Definition: MemSSA.h:71
FunToEntryChiSetMap & getFunToEntryChiSetMap()
Definition: MemSSA.h:417
std::vector< const SVFStmt * > SVFStmtList
Definition: SVFIR.h:58
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
std::ostream OutStream
Definition: GeneralType.h:45
unsigned u32_t
Definition: GeneralType.h:46
std::map< Key, Value, Compare, Allocator > OrderedMap
Definition: GeneralType.h:109
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96