36 using namespace SVFUtil;
50 &&
"please specify a pointer analysis");
59 assert(
false &&
"unrecognised memory partition strategy");
65 double mrStart = stat->getClk(
true);
67 double mrEnd = stat->getClk(
true);
68 timeOfGeneratingMemRegions = (mrEnd - mrStart)/
TIMEINTERVAL;
82 assert(!
isExtCall(&fun) &&
"we do not build memory ssa for external functions");
91 double muchiStart = stat->getClk(
true);
93 double muchiEnd = stat->getClk(
true);
94 timeOfCreateMUCHI += (muchiEnd - muchiStart)/
TIMEINTERVAL;
97 double phiStart = stat->getClk(
true);
99 double phiEnd = stat->getClk(
true);
103 double renameStart = stat->getClk(
true);
105 double renameEnd = stat->getClk(
true);
106 timeOfSSARenaming += (renameEnd - renameStart)/
TIMEINTERVAL;
119 outs() <<
"\t creating mu chi for function " << fun.
getName()
139 for (BBList::const_iterator iter = reachableBBs.begin(), eiter = reachableBBs.end();
140 iter != eiter; ++iter)
146 if(mrGen->hasSVFStmtList(inst))
148 SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst);
149 for (SVFStmtList::const_iterator bit = pagEdgeList.begin(),
150 ebit = pagEdgeList.end(); bit != ebit; ++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));
162 if(mrGen->hasRefMRSet(cs))
163 AddCallSiteMU(cs,mrGen->getCallSiteRefMRSet(cs));
165 if(mrGen->hasModMRSet(cs))
166 AddCallSiteCHI(cs,mrGen->getCallSiteModMRSet(cs));
173 for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end();
174 iter != eiter; ++iter)
178 mr2CounterMap[mr] = 0;
179 mr2VerStackMap[mr].clear();
183 funToEntryChiSetMap[&fun].insert(chi);
190 funToReturnMuSetMap[&fun].insert(mu);
204 outs() <<
"\t insert phi for function " << fun.
getName() <<
"\n");
211 for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end();
212 iter != eiter; ++iter)
216 BBList bbs = reg2BBMap[mr];
224 writeWrnMsg(
"bb not in the dominance frontier map??");
231 if (0 == bb2MRSetMap[pbb].
count(mr))
233 bb2MRSetMap[pbb].insert(mr);
252 outs() <<
"\t ssa rename for function " << fun.
getName() <<
"\n");
271 RenamePhiRes(getPHISet(&bb),memRegs);
283 if(mrGen->hasSVFStmtList(pNode))
285 SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(pNode);
286 for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end();
290 if (
const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(inst))
291 RenameMuSet(getMUSet(load));
293 else if (
const StoreStmt* store = SVFUtil::dyn_cast<StoreStmt>(inst))
294 RenameChiSet(getCHISet(store),memRegs);
301 if(mrGen->hasRefMRSet(cs))
302 RenameMuSet(getMUSet(cs));
304 if(mrGen->hasModMRSet(cs))
305 RenameChiSet(getCHISet(cs),memRegs);
310 RenameMuSet(getReturnMuSet(fun));
320 RenamePhiOps(getPHISet(succ),pos,memRegs);
327 if (mapIter != dtBBsMap.end())
337 while (!memRegs.empty())
341 mr2VerStackMap[mr].pop_back();
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? ");
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);
368 for (LoadToMUSetMap::iterator iter = load2MuSetMap.begin(), eiter =
369 load2MuSetMap.end(); iter != eiter; ++iter)
371 for (MUSet::iterator it = iter->second.begin(), eit =
372 iter->second.end(); it != eit; ++it)
378 for (StoreToChiSetMap::iterator iter = store2ChiSetMap.begin(), eiter =
379 store2ChiSetMap.end(); iter != eiter; ++iter)
381 for (CHISet::iterator it = iter->second.begin(), eit =
382 iter->second.end(); it != eit; ++it)
388 for (CallSiteToMUSetMap::iterator iter = callsiteToMuSetMap.begin(),
389 eiter = callsiteToMuSetMap.end(); iter != eiter; ++iter)
391 for (MUSet::iterator it = iter->second.begin(), eit =
392 iter->second.end(); it != eit; ++it)
398 for (CallSiteToCHISetMap::iterator iter = callsiteToChiSetMap.begin(),
399 eiter = callsiteToChiSetMap.end(); iter != eiter; ++iter)
401 for (CHISet::iterator it = iter->second.begin(), eit =
402 iter->second.end(); it != eit; ++it)
408 for (FunToEntryChiSetMap::iterator iter = funToEntryChiSetMap.begin(),
409 eiter = funToEntryChiSetMap.end(); iter != eiter; ++iter)
411 for (CHISet::iterator it = iter->second.begin(), eit =
412 iter->second.end(); it != eit; ++it)
418 for (FunToReturnMuSetMap::iterator iter = funToReturnMuSetMap.begin(),
419 eiter = funToReturnMuSetMap.end(); iter != eiter; ++iter)
421 for (MUSet::iterator it = iter->second.begin(), eit =
422 iter->second.end(); it != eit; ++it)
428 for (BBToPhiSetMap::iterator iter = bb2PhiSetMap.begin(), eiter =
429 bb2PhiSetMap.end(); iter != eiter; ++iter)
431 for (PHISet::iterator it = iter->second.begin(), eit =
432 iter->second.end(); it != eit; ++it)
460 LoadToMUSetMap::const_iterator it = load2MuSetMap.begin();
461 LoadToMUSetMap::const_iterator eit = load2MuSetMap.end();
462 for (; it != eit; it++)
464 const MUSet & muSet = it->second;
477 StoreToChiSetMap::const_iterator it = store2ChiSetMap.begin();
478 StoreToChiSetMap::const_iterator eit = store2ChiSetMap.end();
479 for (; it != eit; it++)
481 const CHISet& chiSet = it->second;
482 num += chiSet.size();
494 FunToEntryChiSetMap::const_iterator it = funToEntryChiSetMap.begin();
495 FunToEntryChiSetMap::const_iterator eit = funToEntryChiSetMap.end();
496 for (; it != eit; it++)
498 const CHISet& chiSet = it->second;
499 num += chiSet.size();
511 FunToReturnMuSetMap::const_iterator it = funToReturnMuSetMap.begin();
512 FunToReturnMuSetMap::const_iterator eit = funToReturnMuSetMap.end();
513 for (; it != eit; it++)
515 const MUSet & muSet = it->second;
528 CallSiteToMUSetMap::const_iterator it = callsiteToMuSetMap.begin();
529 CallSiteToMUSetMap::const_iterator eit = callsiteToMuSetMap.end();
530 for (; it != eit; it++)
532 const MUSet & muSet = it->second;
545 CallSiteToCHISetMap::const_iterator it = callsiteToChiSetMap.begin();
546 CallSiteToCHISetMap::const_iterator eit = callsiteToChiSetMap.end();
547 for (; it != eit; it++)
549 const CHISet & chiSet = it->second;
562 BBToPhiSetMap::const_iterator it = bb2PhiSetMap.begin();
563 BBToPhiSetMap::const_iterator eit = bb2PhiSetMap.end();
564 for (; it != eit; it++)
566 const PHISet & phiSet = it->second;
579 for (
const auto&
item: *svfirCallGraph)
585 Out <<
"==========FUNCTION: " << fun->
getName() <<
"==========\n";
587 if (hasFuncEntryChi(fun))
589 CHISet & entry_chis = getFuncEntryChiSet(fun);
590 for (CHISet::iterator chi_it = entry_chis.begin(); chi_it != entry_chis.end(); chi_it++)
601 PHISet& phiSet = getPHISet(bb);
602 for(PHISet::iterator pi = phiSet.begin(), epi = phiSet.end(); pi !=epi; ++pi)
607 bool last_is_chi =
false;
620 for (MUSet::iterator mit = getMUSet(cs).begin(), emit = getMUSet(cs).end();
627 Out << inst->toString() <<
"\n";
631 for (CHISet::iterator cit = getCHISet(cs).begin(), ecit = getCHISet(cs).end();
644 bool dump_preamble =
false;
645 SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst);
646 for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end();
650 if (
const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(edge))
652 MUSet& muSet = getMUSet(load);
653 for(MUSet::iterator it = muSet.begin(), eit = muSet.end(); it!=eit; ++it)
655 if (!dump_preamble && !last_is_chi)
658 dump_preamble =
true;
665 Out << inst->toString() <<
"\n";
667 bool has_chi =
false;
668 for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end();
672 if (
const StoreStmt* store = SVFUtil::dyn_cast<StoreStmt>(edge))
674 CHISet& chiSet = getCHISet(store);
675 for(CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it!=eit; ++it)
694 if (hasReturnMu(fun))
696 MUSet & return_mus = getReturnMuSet(fun);
697 for (MUSet::iterator mu_it = return_mus.begin(); mu_it != return_mus.end(); mu_it++)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
void setOpVer(MRVer *v)
Set operand ver.
void setResVer(MRVer *v)
Set result operand ver.
std::vector< const SVFBasicBlock * > BBList
For phi insertion.
u32_t getFunEntryChiNum() const
virtual void SSARename(const SVFFunction &fun)
SSA rename for a function.
u32_t getCallSiteChiNum() const
static double timeOfGeneratingMemRegions
Statistics.
MRVer * newSSAName(const MemRegion *mr, MSSADEF *def)
Get a new SSA name of a memory region.
static double timeOfInsertingPHI
Time for inserting phis.
void destroy()
Release the memory.
SVFIR * getPAG()
Return SVFIR.
SVFIR::SVFStmtList SVFStmtList
SVFIR edge list.
static double timeOfCreateMUCHI
Time for generating mu/chi for load/store/calls.
virtual void buildMemSSA(const SVFFunction &fun)
We start from here.
u32_t getFunRetMuNum() const
virtual void createMUCHI(const SVFFunction &fun)
Create mu chi for candidate regions in a function.
MemSSA(BVDataPTAImpl *p, bool ptrOnlyMSSA)
Constructor.
void dumpMSSA(OutStream &Out=SVFUtil::outs())
Print Memory SSA.
std::vector< const MemRegion * > MRVector
void performStat()
Perform statistics.
static double timeOfSSARenaming
Time for SSA rename.
u32_t getBBPhiNum() const
u32_t getCallSiteMuNum() const
u32_t getStoreChiNum() const
u32_t getLoadMuNum() const
Stat methods.
virtual void insertPHI(const SVFFunction &fun)
Insert phi for candidate regions in a function.
Map< const SVFBasicBlock *, MRSet > BBToMRSetMap
virtual void SSARenameBB(const SVFBasicBlock &bb)
SSA rename for a basic block.
static const OptionMap< MemSSA::MemPartition > MemPar
static const Option< std::string > MSSAFun
@ Default_PTA
default pta without any analysis
const std::vector< const ICFGNode * > & getICFGNodeList() const
u32_t getBBPredecessorPos(const SVFBasicBlock *succbb)
const std::vector< const SVFBasicBlock * > & getSuccessors() const
const ICFGNode * back() const
const SVFFunction * getParent() const
const_iterator end() const
const_iterator begin() const
const Map< const SVFBasicBlock *, BBSet > & getDomFrontierMap() const
const Map< const SVFBasicBlock *, BBSet > & getDomTreeMap() const
const SVFBasicBlock * getEntryBlock() const
const std::vector< const SVFBasicBlock * > & getReachableBBs() const
std::vector< const SVFBasicBlock * >::const_iterator const_iterator
PTACallGraph * getCallGraph()
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
const std::string & getName() const
bool isExtCall(const SVFFunction *fun)
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
bool isHeapAllocExtCall(const ICFGNode *cs)
bool isNonInstricCallSite(const ICFGNode *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
bool isRetInstNode(const ICFGNode *node)
std::ostream & outs()
Overwrite llvm::outs()
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set