Static Value-Flow Analysis
MemSSA.cpp
Go to the documentation of this file.
1 //===- MemSSA.cpp -- Base class of pointer analyses------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2017> <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  * MemSSA.cpp
25  *
26  * Created on: Dec 14, 2013
27  * Author: Yulei Sui
28  */
29 
30 #include "Util/Options.h"
31 #include "MSSA/MemPartition.h"
32 #include "MSSA/MemSSA.h"
33 #include "Graphs/SVFGStat.h"
34 
35 using namespace SVF;
36 using namespace SVFUtil;
37 
39 double MemSSA::timeOfCreateMUCHI = 0;
40 double MemSSA::timeOfInsertingPHI = 0;
41 double MemSSA::timeOfSSARenaming = 0;
42 
46 MemSSA::MemSSA(BVDataPTAImpl* p, bool ptrOnlyMSSA)
47 {
48  pta = p;
49  assert((pta->getAnalysisTy()!=PointerAnalysis::Default_PTA)
50  && "please specify a pointer analysis");
51 
52  if (Options::MemPar() == MemPartition::Distinct)
53  mrGen = new DistinctMRG(pta, ptrOnlyMSSA);
54  else if (Options::MemPar() == MemPartition::IntraDisjoint)
55  mrGen = new IntraDisjointMRG(pta, ptrOnlyMSSA);
56  else if (Options::MemPar() == MemPartition::InterDisjoint)
57  mrGen = new InterDisjointMRG(pta, ptrOnlyMSSA);
58  else
59  assert(false && "unrecognised memory partition strategy");
60 
61 
62  stat = new MemSSAStat(this);
63 
65  double mrStart = stat->getClk(true);
66  mrGen->generateMRs();
67  double mrEnd = stat->getClk(true);
68  timeOfGeneratingMemRegions = (mrEnd - mrStart)/TIMEINTERVAL;
69 }
70 
72 {
73  return pta->getPAG();
74 }
75 
80 {
81 
82  assert(!isExtCall(&fun) && "we do not build memory ssa for external functions");
83 
84  DBOUT(DMSSA, outs() << "Building Memory SSA for function " << fun.getName()
85  << " \n");
86 
87  usedRegs.clear();
88  reg2BBMap.clear();
89 
91  double muchiStart = stat->getClk(true);
92  createMUCHI(fun);
93  double muchiEnd = stat->getClk(true);
94  timeOfCreateMUCHI += (muchiEnd - muchiStart)/TIMEINTERVAL;
95 
97  double phiStart = stat->getClk(true);
98  insertPHI(fun);
99  double phiEnd = stat->getClk(true);
100  timeOfInsertingPHI += (phiEnd - phiStart)/TIMEINTERVAL;
101 
103  double renameStart = stat->getClk(true);
104  SSARename(fun);
105  double renameEnd = stat->getClk(true);
106  timeOfSSARenaming += (renameEnd - renameStart)/TIMEINTERVAL;
107 
108 }
109 
115 {
116 
117 
118  DBOUT(DMSSA,
119  outs() << "\t creating mu chi for function " << fun.getName()
120  << "\n");
121  // 1. create mu/chi
122  // insert a set of mus for memory regions at each load
123  // inset a set of chis for memory regions at each store
124 
125  // 2. find global names (region name before renaming) of each memory region,
126  // collect used mrs in usedRegs, and collect its def basic block in reg2BBMap
127  // in the form of mu(r) and r = chi (r)
128  // a) mu(r):
129  // if(r \not\in varKills) global = global \cup r
130  // b) r = chi(r):
131  // if(r \not\in varKills) global = global \cup r
132  // varKills = varKills \cup r
133  // block(r) = block(r) \cup bb_{chi}
134 
137  BBList reachableBBs = fun.getReachableBBs();
138 
139  for (BBList::const_iterator iter = reachableBBs.begin(), eiter = reachableBBs.end();
140  iter != eiter; ++iter)
141  {
142  const SVFBasicBlock* bb = *iter;
143  varKills.clear();
144  for (const auto& inst: bb->getICFGNodeList())
145  {
146  if(mrGen->hasSVFStmtList(inst))
147  {
148  SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst);
149  for (SVFStmtList::const_iterator bit = pagEdgeList.begin(),
150  ebit = pagEdgeList.end(); bit != ebit; ++bit)
151  {
152  const PAGEdge* inst = *bit;
153  if (const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(inst))
154  AddLoadMU(bb, load, mrGen->getLoadMRSet(load));
155  else if (const StoreStmt* store = SVFUtil::dyn_cast<StoreStmt>(inst))
156  AddStoreCHI(bb, store, mrGen->getStoreMRSet(store));
157  }
158  }
159  if (isNonInstricCallSite(inst))
160  {
161  const CallICFGNode* cs = cast<CallICFGNode>(inst);
162  if(mrGen->hasRefMRSet(cs))
163  AddCallSiteMU(cs,mrGen->getCallSiteRefMRSet(cs));
164 
165  if(mrGen->hasModMRSet(cs))
166  AddCallSiteCHI(cs,mrGen->getCallSiteModMRSet(cs));
167  }
168  }
169  }
170 
171  // create entry chi for this function including all memory regions
172  // initialize them with version 0 and 1 r_1 = chi (r_0)
173  for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end();
174  iter != eiter; ++iter)
175  {
176  const MemRegion* mr = *iter;
177  // initialize mem region version and stack for renaming phase
178  mr2CounterMap[mr] = 0;
179  mr2VerStackMap[mr].clear();
180  ENTRYCHI* chi = new ENTRYCHI(&fun, mr);
181  chi->setOpVer(newSSAName(mr,chi));
182  chi->setResVer(newSSAName(mr,chi));
183  funToEntryChiSetMap[&fun].insert(chi);
184 
187  if(fun.hasReturn())
188  {
189  RETMU* mu = new RETMU(&fun, mr);
190  funToReturnMuSetMap[&fun].insert(mu);
191  }
192 
193  }
194 
195 }
196 
197 /*
198  * Insert phi node
199  */
201 {
202 
203  DBOUT(DMSSA,
204  outs() << "\t insert phi for function " << fun.getName() << "\n");
205 
207  // record whether a phi of mr has already been inserted into the bb.
208  BBToMRSetMap bb2MRSetMap;
209 
210  // start inserting phi node
211  for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end();
212  iter != eiter; ++iter)
213  {
214  const MemRegion* mr = *iter;
215 
216  BBList bbs = reg2BBMap[mr];
217  while (!bbs.empty())
218  {
219  const SVFBasicBlock* bb = bbs.back();
220  bbs.pop_back();
221  Map<const SVFBasicBlock*,Set<const SVFBasicBlock*>>::const_iterator it = df.find(bb);
222  if(it == df.end())
223  {
224  writeWrnMsg("bb not in the dominance frontier map??");
225  continue;
226  }
227  const Set<const SVFBasicBlock*>& domSet = it->second;
228  for (const SVFBasicBlock* pbb : domSet)
229  {
230  // if we never insert this phi node before
231  if (0 == bb2MRSetMap[pbb].count(mr))
232  {
233  bb2MRSetMap[pbb].insert(mr);
234  // insert phi node
235  AddMSSAPHI(pbb,mr);
236  // continue to insert phi in its iterative dominate frontiers
237  bbs.push_back(pbb);
238  }
239  }
240  }
241  }
242 
243 }
244 
249 {
250 
251  DBOUT(DMSSA,
252  outs() << "\t ssa rename for function " << fun.getName() << "\n");
253 
254  SSARenameBB(*fun.getEntryBlock());
255 }
256 
262 {
263 
264  // record which mem region needs to pop stack
265  MRVector memRegs;
266 
267  // rename phi result op
268  // for each r = phi (...)
269  // rewrite r as new name
270  if (hasPHISet(&bb))
271  RenamePhiRes(getPHISet(&bb),memRegs);
272 
273 
274  // process mu and chi
275  // for each mu(r)
276  // rewrite r with top mrver of stack(r)
277  // for each r = chi(r')
278  // rewrite r' with top mrver of stack(r)
279  // rewrite r with new name
280 
281  for (const auto& pNode: bb.getICFGNodeList())
282  {
283  if(mrGen->hasSVFStmtList(pNode))
284  {
285  SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(pNode);
286  for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end();
287  bit!=ebit; ++bit)
288  {
289  const PAGEdge* inst = *bit;
290  if (const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(inst))
291  RenameMuSet(getMUSet(load));
292 
293  else if (const StoreStmt* store = SVFUtil::dyn_cast<StoreStmt>(inst))
294  RenameChiSet(getCHISet(store),memRegs);
295 
296  }
297  }
298  if (isNonInstricCallSite(pNode))
299  {
300  const CallICFGNode* cs = cast<CallICFGNode>(pNode);
301  if(mrGen->hasRefMRSet(cs))
302  RenameMuSet(getMUSet(cs));
303 
304  if(mrGen->hasModMRSet(cs))
305  RenameChiSet(getCHISet(cs),memRegs);
306  }
307  else if(isRetInstNode(pNode))
308  {
309  const SVFFunction* fun = bb.getParent();
310  RenameMuSet(getReturnMuSet(fun));
311  }
312  }
313 
314 
315  // fill phi operands of succ basic blocks
316  for (const SVFBasicBlock* succ : bb.getSuccessors())
317  {
318  u32_t pos = bb.getBBPredecessorPos(succ);
319  if (hasPHISet(succ))
320  RenamePhiOps(getPHISet(succ),pos,memRegs);
321  }
322 
323  // for succ basic block in dominator tree
324  const SVFFunction* fun = bb.getParent();
326  Map<const SVFBasicBlock*,Set<const SVFBasicBlock*>>::const_iterator mapIter = dtBBsMap.find(&bb);
327  if (mapIter != dtBBsMap.end())
328  {
329  const Set<const SVFBasicBlock*>& dtBBs = mapIter->second;
330  for (const SVFBasicBlock* dtbb : dtBBs)
331  {
332  SSARenameBB(*dtbb);
333  }
334  }
335  // for each r = chi(..), and r = phi(..)
336  // pop ver stack(r)
337  while (!memRegs.empty())
338  {
339  const MemRegion* mr = memRegs.back();
340  memRegs.pop_back();
341  mr2VerStackMap[mr].pop_back();
342  }
343 
344 }
345 
347 {
348  assert(0 != mr2CounterMap.count(mr)
349  && "did not find initial version in map? ");
350  assert(0 != mr2VerStackMap.count(mr)
351  && "did not find initial stack in map? ");
352 
353  MRVERSION version = mr2CounterMap[mr];
354  mr2CounterMap[mr] = version + 1;
355  auto mrVer = std::make_unique<MRVer>(mr, version, def);
356  auto mrVerPtr = mrVer.get();
357  mr2VerStackMap[mr].push_back(mrVerPtr);
358  usedMRVers.push_back(std::move(mrVer));
359  return mrVerPtr;
360 }
361 
366 {
367 
368  for (LoadToMUSetMap::iterator iter = load2MuSetMap.begin(), eiter =
369  load2MuSetMap.end(); iter != eiter; ++iter)
370  {
371  for (MUSet::iterator it = iter->second.begin(), eit =
372  iter->second.end(); it != eit; ++it)
373  {
374  delete *it;
375  }
376  }
377 
378  for (StoreToChiSetMap::iterator iter = store2ChiSetMap.begin(), eiter =
379  store2ChiSetMap.end(); iter != eiter; ++iter)
380  {
381  for (CHISet::iterator it = iter->second.begin(), eit =
382  iter->second.end(); it != eit; ++it)
383  {
384  delete *it;
385  }
386  }
387 
388  for (CallSiteToMUSetMap::iterator iter = callsiteToMuSetMap.begin(),
389  eiter = callsiteToMuSetMap.end(); iter != eiter; ++iter)
390  {
391  for (MUSet::iterator it = iter->second.begin(), eit =
392  iter->second.end(); it != eit; ++it)
393  {
394  delete *it;
395  }
396  }
397 
398  for (CallSiteToCHISetMap::iterator iter = callsiteToChiSetMap.begin(),
399  eiter = callsiteToChiSetMap.end(); iter != eiter; ++iter)
400  {
401  for (CHISet::iterator it = iter->second.begin(), eit =
402  iter->second.end(); it != eit; ++it)
403  {
404  delete *it;
405  }
406  }
407 
408  for (FunToEntryChiSetMap::iterator iter = funToEntryChiSetMap.begin(),
409  eiter = funToEntryChiSetMap.end(); iter != eiter; ++iter)
410  {
411  for (CHISet::iterator it = iter->second.begin(), eit =
412  iter->second.end(); it != eit; ++it)
413  {
414  delete *it;
415  }
416  }
417 
418  for (FunToReturnMuSetMap::iterator iter = funToReturnMuSetMap.begin(),
419  eiter = funToReturnMuSetMap.end(); iter != eiter; ++iter)
420  {
421  for (MUSet::iterator it = iter->second.begin(), eit =
422  iter->second.end(); it != eit; ++it)
423  {
424  delete *it;
425  }
426  }
427 
428  for (BBToPhiSetMap::iterator iter = bb2PhiSetMap.begin(), eiter =
429  bb2PhiSetMap.end(); iter != eiter; ++iter)
430  {
431  for (PHISet::iterator it = iter->second.begin(), eit =
432  iter->second.end(); it != eit; ++it)
433  {
434  delete *it;
435  }
436  }
437 
438  delete mrGen;
439  mrGen = nullptr;
440  delete stat;
441  stat = nullptr;
442  pta = nullptr;
443 }
444 
449 {
450  if(pta->printStat())
451  stat->performStat();
452 }
453 
458 {
459  u32_t num = 0;
460  LoadToMUSetMap::const_iterator it = load2MuSetMap.begin();
461  LoadToMUSetMap::const_iterator eit = load2MuSetMap.end();
462  for (; it != eit; it++)
463  {
464  const MUSet & muSet = it->second;
465  num+= muSet.size();
466  }
467  return num;
468 }
469 
470 
475 {
476  u32_t num = 0;
477  StoreToChiSetMap::const_iterator it = store2ChiSetMap.begin();
478  StoreToChiSetMap::const_iterator eit = store2ChiSetMap.end();
479  for (; it != eit; it++)
480  {
481  const CHISet& chiSet = it->second;
482  num += chiSet.size();
483  }
484  return num;
485 }
486 
487 
492 {
493  u32_t num = 0;
494  FunToEntryChiSetMap::const_iterator it = funToEntryChiSetMap.begin();
495  FunToEntryChiSetMap::const_iterator eit = funToEntryChiSetMap.end();
496  for (; it != eit; it++)
497  {
498  const CHISet& chiSet = it->second;
499  num += chiSet.size();
500  }
501  return num;
502 }
503 
504 
509 {
510  u32_t num = 0;
511  FunToReturnMuSetMap::const_iterator it = funToReturnMuSetMap.begin();
512  FunToReturnMuSetMap::const_iterator eit = funToReturnMuSetMap.end();
513  for (; it != eit; it++)
514  {
515  const MUSet & muSet = it->second;
516  num+= muSet.size();
517  }
518  return num;
519 }
520 
521 
526 {
527  u32_t num = 0;
528  CallSiteToMUSetMap::const_iterator it = callsiteToMuSetMap.begin();
529  CallSiteToMUSetMap::const_iterator eit = callsiteToMuSetMap.end();
530  for (; it != eit; it++)
531  {
532  const MUSet & muSet = it->second;
533  num+= muSet.size();
534  }
535  return num;
536 }
537 
538 
543 {
544  u32_t num = 0;
545  CallSiteToCHISetMap::const_iterator it = callsiteToChiSetMap.begin();
546  CallSiteToCHISetMap::const_iterator eit = callsiteToChiSetMap.end();
547  for (; it != eit; it++)
548  {
549  const CHISet & chiSet = it->second;
550  num+= chiSet.size();
551  }
552  return num;
553 }
554 
555 
560 {
561  u32_t num = 0;
562  BBToPhiSetMap::const_iterator it = bb2PhiSetMap.begin();
563  BBToPhiSetMap::const_iterator eit = bb2PhiSetMap.end();
564  for (; it != eit; it++)
565  {
566  const PHISet & phiSet = it->second;
567  num+= phiSet.size();
568  }
569  return num;
570 }
571 
576 {
577 
578  PTACallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
579  for (const auto& item: *svfirCallGraph)
580  {
581  const SVFFunction* fun = item.second->getFunction();
582  if(Options::MSSAFun()!="" && Options::MSSAFun()!=fun->getName())
583  continue;
584 
585  Out << "==========FUNCTION: " << fun->getName() << "==========\n";
586  // dump function entry chi nodes
587  if (hasFuncEntryChi(fun))
588  {
589  CHISet & entry_chis = getFuncEntryChiSet(fun);
590  for (CHISet::iterator chi_it = entry_chis.begin(); chi_it != entry_chis.end(); chi_it++)
591  {
592  (*chi_it)->dump();
593  }
594  }
595 
596  for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end();
597  bit != ebit; ++bit)
598  {
599  const SVFBasicBlock* bb = *bit;
600  Out << bb->getName() << "\n";
601  PHISet& phiSet = getPHISet(bb);
602  for(PHISet::iterator pi = phiSet.begin(), epi = phiSet.end(); pi !=epi; ++pi)
603  {
604  (*pi)->dump();
605  }
606 
607  bool last_is_chi = false;
608  for (const auto& inst: bb->getICFGNodeList())
609  {
610  bool isAppCall = isNonInstricCallSite(inst) && !isExtCall(inst);
611  if (isAppCall || isHeapAllocExtCall(inst))
612  {
613  const CallICFGNode* cs = cast<CallICFGNode>(inst);
614  if(hasMU(cs))
615  {
616  if (!last_is_chi)
617  {
618  Out << "\n";
619  }
620  for (MUSet::iterator mit = getMUSet(cs).begin(), emit = getMUSet(cs).end();
621  mit != emit; ++mit)
622  {
623  (*mit)->dump();
624  }
625  }
626 
627  Out << inst->toString() << "\n";
628 
629  if(hasCHI(cs))
630  {
631  for (CHISet::iterator cit = getCHISet(cs).begin(), ecit = getCHISet(cs).end();
632  cit != ecit; ++cit)
633  {
634  (*cit)->dump();
635  }
636  Out << "\n";
637  last_is_chi = true;
638  }
639  else
640  last_is_chi = false;
641  }
642  else
643  {
644  bool dump_preamble = false;
645  SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst);
646  for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end();
647  bit!=ebit; ++bit)
648  {
649  const PAGEdge* edge = *bit;
650  if (const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(edge))
651  {
652  MUSet& muSet = getMUSet(load);
653  for(MUSet::iterator it = muSet.begin(), eit = muSet.end(); it!=eit; ++it)
654  {
655  if (!dump_preamble && !last_is_chi)
656  {
657  Out << "\n";
658  dump_preamble = true;
659  }
660  (*it)->dump();
661  }
662  }
663  }
664 
665  Out << inst->toString() << "\n";
666 
667  bool has_chi = false;
668  for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end();
669  bit!=ebit; ++bit)
670  {
671  const PAGEdge* edge = *bit;
672  if (const StoreStmt* store = SVFUtil::dyn_cast<StoreStmt>(edge))
673  {
674  CHISet& chiSet = getCHISet(store);
675  for(CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it!=eit; ++it)
676  {
677  has_chi = true;
678  (*it)->dump();
679  }
680  }
681  }
682  if (has_chi)
683  {
684  Out << "\n";
685  last_is_chi = true;
686  }
687  else
688  last_is_chi = false;
689  }
690  }
691  }
692 
693  // dump return mu nodes
694  if (hasReturnMu(fun))
695  {
696  MUSet & return_mus = getReturnMuSet(fun);
697  for (MUSet::iterator mu_it = return_mus.begin(); mu_it != return_mus.end(); mu_it++)
698  {
699  (*mu_it)->dump();
700  }
701  }
702  }
703 }
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define TIMEINTERVAL
Definition: SVFType.h:512
#define DMSSA
Definition: SVFType.h:501
cJSON * p
Definition: cJSON.cpp:2559
cJSON * item
Definition: cJSON.h:222
int count
Definition: cJSON.h:216
void setOpVer(MRVer *v)
Set operand ver.
Definition: MSSAMuChi.h:414
void setResVer(MRVer *v)
Set result operand ver.
Definition: MSSAMuChi.h:366
Memory Region class.
Definition: MemRegion.h:56
std::vector< const SVFBasicBlock * > BBList
For phi insertion.
Definition: MemSSA.h:93
u32_t getFunEntryChiNum() const
Definition: MemSSA.cpp:491
virtual void SSARename(const SVFFunction &fun)
SSA rename for a function.
Definition: MemSSA.cpp:248
u32_t getCallSiteChiNum() const
Definition: MemSSA.cpp:542
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
static double timeOfInsertingPHI
Time for inserting phis.
Definition: MemSSA.h:109
void destroy()
Release the memory.
Definition: MemSSA.cpp:365
SVFIR * getPAG()
Return SVFIR.
Definition: MemSSA.cpp:71
SVFIR::SVFStmtList SVFStmtList
SVFIR edge list.
Definition: MemSSA.h:103
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
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
MemSSA(BVDataPTAImpl *p, bool ptrOnlyMSSA)
Constructor.
Definition: MemSSA.cpp:46
void dumpMSSA(OutStream &Out=SVFUtil::outs())
Print Memory SSA.
Definition: MemSSA.cpp:575
std::vector< const MemRegion * > MRVector
Definition: MemSSA.h:76
Set< MU * > MUSet
Definition: MemSSA.h:70
void performStat()
Perform statistics.
Definition: MemSSA.cpp:448
Set< PHI * > PHISet
Definition: MemSSA.h:72
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
u32_t getLoadMuNum() const
Stat methods.
Definition: MemSSA.cpp:457
virtual void insertPHI(const SVFFunction &fun)
Insert phi for candidate regions in a function.
Definition: MemSSA.cpp:200
Map< const SVFBasicBlock *, MRSet > BBToMRSetMap
Definition: MemSSA.h:94
virtual void SSARenameBB(const SVFBasicBlock &bb)
SSA rename for a basic block.
Definition: MemSSA.cpp:261
Set< CHI * > CHISet
Definition: MemSSA.h:71
static const OptionMap< MemSSA::MemPartition > MemPar
Definition: Options.h:145
static const Option< std::string > MSSAFun
Definition: Options.h:143
@ Default_PTA
default pta without any analysis
const std::vector< const ICFGNode * > & getICFGNodeList() const
Definition: SVFValue.h:569
u32_t getBBPredecessorPos(const SVFBasicBlock *succbb)
Definition: SVFValue.cpp:241
const std::vector< const SVFBasicBlock * > & getSuccessors() const
Definition: SVFValue.h:606
const ICFGNode * back() const
Definition: SVFValue.h:600
const SVFFunction * getParent() const
Definition: SVFValue.h:584
const_iterator end() const
Definition: SVFValue.h:440
const_iterator begin() const
Definition: SVFValue.h:435
const Map< const SVFBasicBlock *, BBSet > & getDomFrontierMap() const
Definition: SVFValue.h:495
bool hasReturn() const
Definition: SVFValue.h:460
const Map< const SVFBasicBlock *, BBSet > & getDomTreeMap() const
Definition: SVFValue.h:490
const SVFBasicBlock * getEntryBlock() const
Definition: SVFValue.h:409
const std::vector< const SVFBasicBlock * > & getReachableBBs() const
Definition: SVFValue.h:450
std::vector< const SVFBasicBlock * >::const_iterator const_iterator
Definition: SVFValue.h:305
PTACallGraph * getCallGraph()
Definition: SVFIR.h:192
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
const std::string & getName() const
Definition: SVFValue.h:243
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447
bool isHeapAllocExtCall(const ICFGNode *cs)
Definition: SVFUtil.cpp:369
bool isNonInstricCallSite(const ICFGNode *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition: SVFUtil.h:189
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition: SVFUtil.cpp:66
bool isRetInstNode(const ICFGNode *node)
Definition: SVFUtil.cpp:388
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
NodeID MRVERSION
Definition: MemRegion.h:52
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::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96