Static Value-Flow Analysis
DDAVFSolver.h
Go to the documentation of this file.
1 //===- DDAVFSolver.h -- Demand-driven analysis value-flow solver------------//
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  * DDAVFSolver.h
25  *
26  * Created on: Jul 3, 2014
27  * Author: Yulei Sui
28  */
29 
30 #ifndef VALUEFLOWDDA_H_
31 #define VALUEFLOWDDA_H_
32 
33 #include "DDA/DDAStat.h"
34 #include "Graphs/SCC.h"
35 #include "MSSA/SVFGBuilder.h"
36 #include "MemoryModel/PointsTo.h"
37 #include "WPA/Andersen.h"
38 #include <algorithm>
39 
40 namespace SVF
41 {
42 
46 template<class CVar, class CPtSet, class DPIm>
48 {
49  friend class DDAStat;
50 public:
63 
65  DDAVFSolver(): outOfBudgetQuery(false),_pag(nullptr),_svfg(nullptr),_ander(nullptr),_callGraph(nullptr), _callGraphSCC(nullptr), _svfgSCC(nullptr), ddaStat(nullptr)
66  {
67  }
69  virtual ~DDAVFSolver()
70  {
71  if(_ander != nullptr)
72  {
73  // AndersenWaveDiff::releaseAndersenWaveDiff();
74  _ander = nullptr;
75  }
76 
77  if (_svfg != nullptr)
78  {
79  // DDASVFGBuilder::releaseDDASVFG();
80  _svfg = nullptr;
81  }
82 
83  if (_svfgSCC != nullptr)
84  delete _svfgSCC;
85  _svfgSCC = nullptr;
86 
87  _callGraph = nullptr;
88  _callGraphSCC = nullptr;
89  }
92  {
93  return candidateQueries;
94  }
96  virtual inline DPIm getDPIm(const CVar& var, const SVFGNode* loc) const
97  {
98  DPIm dpm(var,loc);
99  return dpm;
100  }
102  virtual bool unionDDAPts(CPtSet& pts, const CPtSet& targetPts)
103  {
104  return (pts |= targetPts);
105  }
107  virtual bool unionDDAPts(DPIm dpm, const CPtSet& targetPts)
108  {
109  CPtSet& pts = isTopLevelPtrStmt(dpm.getLoc()) ? dpmToTLCPtSetMap[dpm] : dpmToADCPtSetMap[dpm];
110  return pts |= targetPts;
111  }
113  virtual void addDDAPts(CPtSet& pts, const CVar& var)
114  {
115  pts.set(var);
116  }
118  inline SVFG* getSVFG() const
119  {
120  return _svfg;
121  }
123  inline SVFGSCC* getSVFGSCC() const
124  {
125  return _svfgSCC;
126  }
127  // Dump cptsSet
128  inline void dumpCPtSet(const CPtSet& cpts) const
129  {
130  SVFUtil::outs() << "{";
131  for(typename CPtSet::iterator it = cpts.begin(), eit = cpts.end(); it!=eit; ++it)
132  {
133  SVFUtil::outs() << (*it) << " ";
134  }
135  SVFUtil::outs() << "}\n";
136  }
138  virtual const CPtSet& findPT(const DPIm& dpm)
139  {
140 
141  if(isbkVisited(dpm))
142  {
143  const CPtSet& cpts = getCachedPointsTo(dpm);
144  DBOUT(DDDA, SVFUtil::outs() << "\t already backward visited dpm: ");
145  DBOUT(DDDA, dpm.dump());
146  DBOUT(DDDA, SVFUtil::outs() << "\t return points-to: ");
147  DBOUT(DDDA, dumpCPtSet(cpts));
148  return cpts;
149  }
150 
151  DBOUT(DDDA, SVFUtil::outs() << "\t backward visit dpm: ");
152  DBOUT(DDDA, dpm.dump());
153  markbkVisited(dpm);
154  addDpmToLoc(dpm);
155 
156  if(testOutOfBudget(dpm) == false)
157  {
158 
159  CPtSet pts;
160  handleSingleStatement(dpm, pts);
161 
163  updateCachedPointsTo(dpm, pts);
164  }
165  return getCachedPointsTo(dpm);
166  }
167 
168 protected:
170  virtual void handleSingleStatement(const DPIm& dpm, CPtSet& pts)
171  {
173  resolveFunPtr(dpm);
174 
175  const SVFGNode* node = dpm.getLoc();
176  if(SVFUtil::isa<AddrSVFGNode>(node))
177  {
178  handleAddr(pts,dpm,SVFUtil::cast<AddrSVFGNode>(node));
179  }
183  {
184  backtraceAlongDirectVF(pts,dpm);
185  }
186  else if(SVFUtil::isa<GepSVFGNode>(node))
187  {
188  CPtSet gepPts;
189  backtraceAlongDirectVF(gepPts,dpm);
190  unionDDAPts(pts, processGepPts(SVFUtil::cast<GepSVFGNode>(node),gepPts));
191  }
192  else if(const LoadSVFGNode* load = SVFUtil::dyn_cast<LoadSVFGNode>(node))
193  {
194  if(load->getPAGDstNode()->isPointer() == false)
195  return;
196 
197  CPtSet loadpts;
198  startNewPTCompFromLoadSrc(loadpts,dpm);
199  for(typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it!=eit; ++it)
200  {
201  backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,load));
202  }
203  }
204  else if(const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
205  {
206  if(store->getPAGSrcNode()->isPointer() == false)
207  return;
208 
209  if(isMustAlias(getLoadDpm(dpm),dpm))
210  {
211  DBOUT(DDDA, SVFUtil::outs() << "+++must alias for load and store:");
212  DBOUT(DDDA, getLoadDpm(dpm).dump());
213  DBOUT(DDDA, dpm.dump());
214  DBOUT(DDDA, SVFUtil::outs() << "+++\n");
216  backtraceToStoreSrc(pts,dpm);
217  }
218  else
219  {
220  CPtSet storepts;
221  startNewPTCompFromStoreDst(storepts,dpm);
222  for(typename CPtSet::iterator it = storepts.begin(), eit = storepts.end(); it!=eit; ++it)
223  {
224  if(propagateViaObj(*it,getLoadCVar(dpm)))
225  {
226  backtraceToStoreSrc(pts,getDPImWithOldCond(dpm,*it,store));
227 
228  if(isStrongUpdate(storepts,store))
229  {
230  DBOUT(DDDA, SVFUtil::outs() << "backward strong update for obj " << dpm.getCurNodeID() << "\n");
231  DOSTAT(addSUStat(dpm,store);)
232  }
233  else
234  {
235  DOSTAT(rmSUStat(dpm,store);)
236  backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,store));
237  }
238  }
239  else
240  {
241  backtraceAlongIndirectVF(pts,dpm);
242  }
243  }
244  }
245  }
246  else if(SVFUtil::isa<MRSVFGNode>(node))
247  {
248  backtraceAlongIndirectVF(pts,dpm);
249  }
250  else
251  assert(false && "unexpected kind of SVFG nodes");
252  }
253 
255  void reCompute(const DPIm& dpm)
256  {
258  SVFGEdgeSet newIndirectEdges;
259  if(_pag->isFunPtr(dpm.getCurNodeID()))
260  {
261  const CallSiteSet& csSet = _pag->getIndCallSites(dpm.getCurNodeID());
262  for(CallSiteSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
263  updateCallGraphAndSVFG(dpm, (*it),newIndirectEdges);
264  }
266  if(!newIndirectEdges.empty())
267  _callGraphSCC->find();
268  reComputeForEdges(dpm,newIndirectEdges,true);
269 
271  SVFGEdgeSet edgeSet(dpm.getLoc()->getOutEdges());
272  reComputeForEdges(dpm,edgeSet,false);
273  }
274 
276  void reComputeForEdges(const DPIm& dpm, const SVFGEdgeSet& edgeSet, bool indirectCall = false)
277  {
278  for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
279  {
280  const SVFGEdge* edge = *it;
281  const SVFGNode* dst = edge->getDstNode();
282  typename LocToDPMVecMap::const_iterator locIt = getLocToDPMVecMap().find(dst->getId());
284  if (locIt == getLocToDPMVecMap().end())
285  continue;
286  DPTItemSet dpmSet(locIt->second.begin(), locIt->second.end());
287  for(typename DPTItemSet::const_iterator it = dpmSet.begin(),eit = dpmSet.end(); it!=eit; ++it)
288  {
289  const DPIm& dstDpm = *it;
290  if(!indirectCall && SVFUtil::isa<IndirectSVFGEdge>(edge) && !SVFUtil::isa<LoadSVFGNode>(edge->getDstNode()))
291  {
292  if(dstDpm.getCurNodeID() == dpm.getCurNodeID())
293  {
294  DBOUT(DDDA,SVFUtil::outs() << "\t Recompute, forward from :");
295  DBOUT(DDDA, dpm.dump());
297  clearbkVisited(dstDpm);
298  findPT(dstDpm);
299  }
300  }
301  else
302  {
303  if(indirectCall)
304  DBOUT(DDDA,SVFUtil::outs() << "\t Recompute for indirect call from :");
305  else
306  DBOUT(DDDA,SVFUtil::outs() << "\t Recompute forward from :");
307  DBOUT(DDDA, dpm.dump());
309  clearbkVisited(dstDpm);
310  findPT(dstDpm);
311  }
312  }
313  }
314  }
315 
317  virtual inline void buildSVFG(SVFIR* pag)
318  {
321  _pag = _svfg->getPAG();
322  }
324  virtual inline void resetQuery()
325  {
326  if(outOfBudgetQuery)
327  OOBResetVisited();
328 
329  locToDpmSetMap.clear();
330  dpmToloadDpmMap.clear();
331  loadToPTCVarMap.clear();
332  outOfBudgetQuery = false;
333  ddaStat->_NumOfStep = 0;
334  }
336  inline void OOBResetVisited()
337  {
338  for(typename LocToDPMVecMap::const_iterator it = locToDpmSetMap.begin(),eit = locToDpmSetMap.end(); it!=eit; ++it)
339  {
340  DPTItemSet dpmSet(it->second.begin(), it->second.end());
341  for(typename DPTItemSet::const_iterator dit = dpmSet.begin(),deit=dpmSet.end(); dit!=deit; ++dit)
342  if(isOutOfBudgetDpm(*dit)==false)
343  clearbkVisited(*dit);
344  }
345  }
347  inline const SVFGNode* getDefSVFGNode(const PAGNode* pagNode) const
348  {
349  return getSVFG()->getDefSVFGNode(pagNode);
350  }
352  void backtraceAlongIndirectVF(CPtSet& pts, const DPIm& oldDpm)
353  {
354  const SVFGNode* node = oldDpm.getLoc();
355  NodeID obj = oldDpm.getCurNodeID();
356  if (_pag->isConstantObj(obj))
357  return;
358  const SVFGEdgeSet edgeSet(node->getInEdges());
359  for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
360  {
361  if(const IndirectSVFGEdge* indirEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(*it))
362  {
363  const NodeBS& guard = indirEdge->getPointsTo();
364  if(guard.test(obj))
365  {
366  DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace indirectVF svfgNode " <<
367  indirEdge->getDstID() << " --> " << indirEdge->getSrcID() << "\n");
368  backwardPropDpm(pts,oldDpm.getCurNodeID(),oldDpm,indirEdge);
369  }
370  }
371  }
372  }
374  void backtraceAlongDirectVF(CPtSet& pts, const DPIm& oldDpm)
375  {
376  const SVFGNode* node = oldDpm.getLoc();
377  const SVFGEdgeSet edgeSet(node->getInEdges());
378  for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
379  {
380  if(const DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast<DirectSVFGEdge>(*it))
381  {
382  DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace directVF svfgNode " <<
383  dirEdge->getDstID() << " --> " << dirEdge->getSrcID() << "\n");
384  const SVFGNode* srcNode = dirEdge->getSrcNode();
385  backwardPropDpm(pts,getSVFG()->getLHSTopLevPtr(srcNode)->getId(),oldDpm,dirEdge);
386  }
387  }
388  }
389 
392  inline void startNewPTCompFromLoadSrc(CPtSet& pts, const DPIm& oldDpm)
393  {
394  const LoadSVFGNode* load = SVFUtil::cast<LoadSVFGNode>(oldDpm.getLoc());
395  const SVFGNode* loadSrc = getDefSVFGNode(load->getPAGSrcNode());
396  DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from loadSrc svfgNode " <<
397  load->getId() << " --> " << loadSrc->getId() << "\n");
398  const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(loadSrc,load,SVFGEdge::IntraDirectVF);
399  assert(edge && "Edge not found!!");
400  backwardPropDpm(pts,load->getPAGSrcNodeID(),oldDpm,edge);
401 
402  }
403  inline void startNewPTCompFromStoreDst(CPtSet& pts, const DPIm& oldDpm)
404  {
405  const StoreSVFGNode* store = SVFUtil::cast<StoreSVFGNode>(oldDpm.getLoc());
406  const SVFGNode* storeDst = getDefSVFGNode(store->getPAGDstNode());
407  DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from storeDst svfgNode " <<
408  store->getId() << " --> " << storeDst->getId() << "\n");
409  const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(storeDst,store,SVFGEdge::IntraDirectVF);
410  assert(edge && "Edge not found!!");
411  backwardPropDpm(pts,store->getPAGDstNodeID(),oldDpm,edge);
412  }
413  inline void backtraceToStoreSrc(CPtSet& pts, const DPIm& oldDpm)
414  {
415  const StoreSVFGNode* store = SVFUtil::cast<StoreSVFGNode>(oldDpm.getLoc());
416  const SVFGNode* storeSrc = getDefSVFGNode(store->getPAGSrcNode());
417  DBOUT(DDDA, SVFUtil::outs() << "++backtrace to storeSrc from svfgNode " << getLoadDpm(oldDpm).getLoc()->getId() << " to "<<
418  store->getId() << " to " << storeSrc->getId() <<"\n");
419  const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(storeSrc,store,SVFGEdge::IntraDirectVF);
420  assert(edge && "Edge not found!!");
421  backwardPropDpm(pts,store->getPAGSrcNodeID(),oldDpm,edge);
422  }
424 
426  virtual void backwardPropDpm(CPtSet& pts, NodeID ptr,const DPIm& oldDpm,const SVFGEdge* edge)
427  {
428  DPIm dpm(oldDpm);
429  dpm.setLocVar(edge->getSrcNode(),ptr);
430  DOTIMESTAT(double start = DDAStat::getClk(true));
432  if(handleBKCondition(dpm,edge)==false)
433  {
435  DBOUT(DDDA, SVFUtil::outs() << "\t!!! infeasible path svfgNode: " << edge->getDstID() << " --| " << edge->getSrcID() << "\n");
437  return;
438  }
439 
441  if(SVFUtil::isa<IndirectSVFGEdge>(edge))
442  addLoadDpmAndCVar(dpm,getLoadDpm(oldDpm),getLoadCVar(oldDpm));
443 
446  unionDDAPts(pts,findPT(dpm));
447  }
449  virtual bool isMustAlias(const DPIm&, const DPIm&)
450  {
451  return false;
452  }
454  virtual bool isStrongUpdate(const CPtSet& dstCPSet, const StoreSVFGNode* store)
455  {
456  if (dstCPSet.count() == 1)
457  {
459  typename CPtSet::iterator it = dstCPSet.begin();
460  const CVar& var = *it;
461  // Strong update can be made if this points-to target is not heap, array or field-insensitive.
462  if (!isHeapCondMemObj(var,store) && !isArrayCondMemObj(var)
464  {
465  return true;
466  }
467  }
468  return false;
469  }
471  virtual inline bool isLocalCVarInRecursion(const CVar& var) const
472  {
473  NodeID id = getPtrNodeID(var);
474  const MemObj* obj = _pag->getObject(id);
475  assert(obj && "object not found!!");
476  if(obj->isStack())
477  {
478  if(const SVFFunction* svffun = _pag->getGNode(id)->getFunction())
479  {
481  }
482  }
483  return false;
484  }
485 
487  virtual inline bool propagateViaObj(const CVar& storeObj, const CVar& loadObj)
488  {
489  return getPtrNodeID(storeObj) == getPtrNodeID(loadObj);
490  }
492  void resolveFunPtr(const DPIm& dpm)
493  {
494  if(const CallICFGNode* cbn= getSVFG()->isCallSiteRetSVFGNode(dpm.getLoc()))
495  {
496  if(_pag->isIndirectCallSites(cbn))
497  {
498  NodeID funPtr = _pag->getFunPtr(cbn);
499  DPIm funPtrDpm(dpm);
500  funPtrDpm.setLocVar(getSVFG()->getDefSVFGNode(_pag->getGNode(funPtr)),funPtr);
501  findPT(funPtrDpm);
502  }
503  }
504  else if(const SVFFunction* fun = getSVFG()->isFunEntrySVFGNode(dpm.getLoc()))
505  {
506  CallInstSet csSet;
509  for(CallInstSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
510  {
511  NodeID funPtr = _pag->getFunPtr(*it);
512  DPIm funPtrDpm(dpm);
513  funPtrDpm.setLocVar(getSVFG()->getDefSVFGNode(_pag->getGNode(funPtr)),funPtr);
514  findPT(funPtrDpm);
515  }
516  }
517  }
519 
520  virtual NodeID getPtrNodeID(const CVar& var) const = 0;
523  virtual CPtSet processGepPts(const GepSVFGNode* gep, const CPtSet& srcPts) = 0;
525  virtual void handleAddr(CPtSet& pts,const DPIm& dpm,const AddrSVFGNode* addr) = 0;
527  virtual CPtSet getConservativeCPts(const DPIm& dpm) = 0;
529  virtual inline bool handleBKCondition(DPIm&, const SVFGEdge*)
530  {
531  return true;
532  }
534  virtual inline void updateCallGraphAndSVFG(const DPIm&, const CallICFGNode*, SVFGEdgeSet&) {}
536 
538 
539  inline void markbkVisited(const DPIm& dpm)
540  {
541  backwardVisited.insert(dpm);
542  }
543  inline bool isbkVisited(const DPIm& dpm)
544  {
545  return backwardVisited.find(dpm)!=backwardVisited.end();
546  }
547  inline void clearbkVisited(const DPIm& dpm)
548  {
549  assert(backwardVisited.find(dpm)!=backwardVisited.end() && "dpm not found!");
550  backwardVisited.erase(dpm);
551  }
553 
555 
556  virtual inline const CPtSet& getCachedPointsTo(const DPIm& dpm)
557  {
558  if (isTopLevelPtrStmt(dpm.getLoc()))
559  return getCachedTLPointsTo(dpm);
560  else
561  return getCachedADPointsTo(dpm);
562  }
563  virtual inline void updateCachedPointsTo(const DPIm& dpm, const CPtSet& pts)
564  {
565  if (unionDDAPts(dpm, pts))
566  {
567  DOSTAT(double start = DDAStat::getClk(true));
568  reCompute(dpm);
570  }
571  }
572  virtual inline const CPtSet& getCachedTLPointsTo(const DPIm& dpm)
573  {
574  return dpmToTLCPtSetMap[dpm];
575  }
576  virtual inline const CPtSet& getCachedADPointsTo(const DPIm& dpm)
577  {
578  return dpmToADCPtSetMap[dpm];
579  }
581 
583  inline bool isTopLevelPtrStmt(const SVFGNode* stmt)
584  {
585  return !SVFUtil::isa<StoreSVFGNode, MRSVFGNode>(stmt);
586  }
588  virtual inline DPIm getDPImWithOldCond(const DPIm& oldDpm,const CVar& var, const SVFGNode* loc)
589  {
590  DPIm dpm(oldDpm);
591  dpm.setLocVar(loc,getPtrNodeID(var));
592 
593  if(SVFUtil::isa<StoreSVFGNode>(loc))
594  addLoadDpmAndCVar(dpm,getLoadDpm(oldDpm),var);
595 
596  if(SVFUtil::isa<LoadSVFGNode>(loc))
597  addLoadDpmAndCVar(dpm,oldDpm,var);
598 
600  return dpm;
601  }
603  inline void SVFGSCCDetection()
604  {
605  if(_svfgSCC==nullptr)
606  {
607  _svfgSCC = new SVFGSCC(getSVFG());
608  }
609  _svfgSCC->find();
610  }
613  {
614  return _svfgSCC->repNode(id);
615  }
617  inline bool isSVFGNodeInCycle(const SVFGNode* node)
618  {
619  return _svfgSCC->isInCycle(node->getId());
620  }
622  inline bool edgeInSVFGSCC(const SVFGEdge* edge)
623  {
624  return (getSVFGSCCRepNode(edge->getSrcID()) == getSVFGSCCRepNode(edge->getDstID()));
625  }
627  inline void setCallGraph (PTACallGraph* cg)
628  {
629  _callGraph = cg;
630  }
632  inline void setCallGraphSCC (CallGraphSCC* scc)
633  {
634  _callGraphSCC = scc;
635  }
637 
638  virtual inline bool isHeapCondMemObj(const CVar& var, const StoreSVFGNode*)
639  {
640  const MemObj* mem = _pag->getObject(getPtrNodeID(var));
641  assert(mem && "memory object is null??");
642  return mem->isHeap();
643  }
644 
645  inline bool isArrayCondMemObj(const CVar& var) const
646  {
647  const MemObj* mem = _pag->getObject(getPtrNodeID(var));
648  assert(mem && "memory object is null??");
649  return mem->isArray();
650  }
651  inline bool isFieldInsenCondMemObj(const CVar& var) const
652  {
653  const MemObj* mem = _pag->getBaseObj(getPtrNodeID(var));
654  return mem->isFieldInsensitive();
655  }
657 private:
659 
660  inline const LocToDPMVecMap& getLocToDPMVecMap() const
661  {
662  return locToDpmSetMap;
663  }
664  inline const DPTItemSet& getDpmSetAtLoc(const SVFGNode* loc)
665  {
666  return locToDpmSetMap[loc->getId()];
667  }
668  inline void addDpmToLoc(const DPIm& dpm)
669  {
670  locToDpmSetMap[dpm.getLoc()->getId()].insert(dpm);
671  }
672  inline void removeDpmFromLoc(const DPIm& dpm)
673  {
674  assert(dpm == locToDpmSetMap[dpm.getLoc()].back() && "dpm not match with the end of vector");
675  locToDpmSetMap[dpm.getLoc()->getId()].erase(dpm);
676  }
678 protected:
680 
681  inline void addLoadDpmAndCVar(const DPIm& dpm,const DPIm& loadDpm,const CVar& loadVar)
682  {
683  addLoadCVar(dpm,loadVar);
684  addLoadDpm(dpm,loadDpm);
685  }
687  inline void addLoadDpm(const DPIm& dpm,const DPIm& loadDpm)
688  {
689  typename DPMToDPMMap::iterator it = dpmToloadDpmMap.find(dpm);
690  if(it!=dpmToloadDpmMap.end())
691  it->second = loadDpm;
692  else
693  dpmToloadDpmMap.insert(std::make_pair(dpm,loadDpm));
694  }
695  inline const DPIm& getLoadDpm(const DPIm& dpm) const
696  {
697  typename DPMToDPMMap::const_iterator it = dpmToloadDpmMap.find(dpm);
698  assert(it!=dpmToloadDpmMap.end() && "not found??");
699  return it->second;
700  }
701  inline void addLoadCVar(const DPIm& dpm, const CVar& loadVar)
702  {
703  typename DPMToCVarMap::iterator it = loadToPTCVarMap.find(dpm);
704  if(it!=loadToPTCVarMap.end())
705  it->second = loadVar;
706  else
707  loadToPTCVarMap.insert(std::make_pair(dpm,loadVar));
708  }
709  inline const CVar& getLoadCVar(const DPIm& dpm) const
710  {
711  typename DPMToCVarMap::const_iterator it = loadToPTCVarMap.find(dpm);
712  assert(it!=loadToPTCVarMap.end() && "not found??");
713  return it->second;
714  }
716  inline AndersenWaveDiff* getAndersenAnalysis() const
718  {
719  return _ander;
720  }
722 
723  inline void handleOutOfBudgetDpm(const DPIm& dpm) {}
725  inline bool testOutOfBudget(const DPIm& dpm)
726  {
727  if(outOfBudgetQuery) return true;
728  if(++ddaStat->_NumOfStep > DPIm::getMaxBudget())
729  outOfBudgetQuery = true;
730  return isOutOfBudgetDpm(dpm) || outOfBudgetQuery;
731  }
732  inline bool isOutOfBudgetQuery() const
733  {
734  return outOfBudgetQuery;
735  }
736  inline void addOutOfBudgetDpm(const DPIm& dpm)
737  {
738  outOfBudgetDpms.insert(dpm);
739  }
740  inline bool isOutOfBudgetDpm(const DPIm& dpm) const
741  {
742  return outOfBudgetDpms.find(dpm) != outOfBudgetDpms.end();
743  }
745 
748  {
749  ddaStat = s;
750  return ddaStat;
751  }
753  inline void addSUStat(const DPIm& dpm, const SVFGNode* node)
754  {
755  if (storeToDPMs[node].insert(dpm).second)
756  {
759  }
760  }
762  inline void rmSUStat(const DPIm& dpm, const SVFGNode* node)
763  {
764  DPTItemSet& dpmSet = storeToDPMs[node];
765  if (dpmSet.erase(dpm))
766  {
768  if(dpmSet.empty())
770  }
771  }
772 
791 };
792 
793 } // End namespace SVF
794 
795 #endif /* VALUEFLOWDDA_H_ */
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DDDA
Definition: SVFType.h:496
#define DOSTAT(X)
Definition: SVFType.h:485
#define DOTIMESTAT(X)
Definition: SVFType.h:486
#define false
Definition: cJSON.cpp:70
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition: Andersen.h:408
u32_t _NumOfMustAliases
Definition: DDAStat.h:56
u32_t _NumOfDPM
Definition: DDAStat.h:54
u32_t _NumOfStrongUpdates
Definition: DDAStat.h:55
u32_t _NumOfInfeasiblePath
Definition: DDAStat.h:57
u64_t _NumOfStep
Definition: DDAStat.h:59
double _TotalTimeOfBKCondition
Definition: DDAStat.h:64
u64_t _NumOfStepInCycle
Definition: DDAStat.h:60
double _AnaTimeCyclePerQuery
Definition: DDAStat.h:62
NodeBS _StrongUpdateStores
Definition: DDAStat.h:66
void removeDpmFromLoc(const DPIm &dpm)
Definition: DDAVFSolver.h:672
bool edgeInSVFGSCC(const SVFGEdge *edge)
Return TRUE if this edge is inside a SVFG SCC, i.e., src node and dst node are in the same SCC on the...
Definition: DDAVFSolver.h:622
void backtraceAlongIndirectVF(CPtSet &pts, const DPIm &oldDpm)
Backward traverse along indirect value flows.
Definition: DDAVFSolver.h:352
OrderedSet< DPIm > DPTItemSet
Definition: DDAVFSolver.h:55
bool isOutOfBudgetDpm(const DPIm &dpm) const
Definition: DDAVFSolver.h:740
SVFIR::CallSiteSet CallSiteSet
Definition: DDAVFSolver.h:54
SVFGBuilder svfgBuilder
SVFG Builder.
Definition: DDAVFSolver.h:790
NodeID getSVFGSCCRepNode(NodeID id)
Get SCC rep node of a SVFG node.
Definition: DDAVFSolver.h:612
void addLoadDpmAndCVar(const DPIm &dpm, const DPIm &loadDpm, const CVar &loadVar)
LoadDpm for must-alias analysis.
Definition: DDAVFSolver.h:681
SVFGSCC * getSVFGSCC() const
Return SVFGSCC.
Definition: DDAVFSolver.h:123
virtual bool isLocalCVarInRecursion(const CVar &var) const
Whether a local variable is in function recursions.
Definition: DDAVFSolver.h:471
virtual ~DDAVFSolver()
Destructor.
Definition: DDAVFSolver.h:69
virtual void updateCachedPointsTo(const DPIm &dpm, const CPtSet &pts)
Definition: DDAVFSolver.h:563
DPImToCPtSetMap dpmToADCPtSetMap
points-to caching map for address-taken vars
Definition: DDAVFSolver.h:783
virtual const CPtSet & getCachedADPointsTo(const DPIm &dpm)
Definition: DDAVFSolver.h:576
OrderedMap< DPIm, DPIm > DPMToDPMMap
Definition: DDAVFSolver.h:58
DPImToCPtSetMap dpmToTLCPtSetMap
points-to caching map for top-level vars
Definition: DDAVFSolver.h:782
virtual bool isMustAlias(const DPIm &, const DPIm &)
whether load and store are aliased
Definition: DDAVFSolver.h:449
bool isFieldInsenCondMemObj(const CVar &var) const
Definition: DDAVFSolver.h:651
virtual CPtSet getConservativeCPts(const DPIm &dpm)=0
Get conservative points-to results when the query is out of budget.
virtual NodeID getPtrNodeID(const CVar &var) const =0
Methods to be implemented in child class.
bool testOutOfBudget(const DPIm &dpm)
Definition: DDAVFSolver.h:725
void addLoadDpm(const DPIm &dpm, const DPIm &loadDpm)
Note that simply use "dpmToloadDpmMap[dpm]=loadDpm", requires DPIm have a default constructor.
Definition: DDAVFSolver.h:687
CallGraphSCC * _callGraphSCC
SCC for PTACallGraph.
Definition: DDAVFSolver.h:779
SCCDetection< SVFG * > SVFGSCC
Definition: DDAVFSolver.h:51
virtual const CPtSet & findPT(const DPIm &dpm)
Compute points-to.
Definition: DDAVFSolver.h:138
SVFGSCC * _svfgSCC
SCC for SVFG.
Definition: DDAVFSolver.h:780
SVFIR * _pag
SVFIR.
Definition: DDAVFSolver.h:774
const SVFGNode * getDefSVFGNode(const PAGNode *pagNode) const
GetDefinition SVFG.
Definition: DDAVFSolver.h:347
virtual void addDDAPts(CPtSet &pts, const CVar &var)
Add pts.
Definition: DDAVFSolver.h:113
virtual bool handleBKCondition(DPIm &, const SVFGEdge *)
Handle condition for context or path analysis (backward analysis)
Definition: DDAVFSolver.h:529
const DPIm & getLoadDpm(const DPIm &dpm) const
Definition: DDAVFSolver.h:695
virtual void updateCallGraphAndSVFG(const DPIm &, const CallICFGNode *, SVFGEdgeSet &)
Update call graph.
Definition: DDAVFSolver.h:534
DPTItemSet backwardVisited
visited map during backward traversing
Definition: DDAVFSolver.h:781
virtual bool isHeapCondMemObj(const CVar &var, const StoreSVFGNode *)
Check heap and array object.
Definition: DDAVFSolver.h:638
SVFGEdge::SVFGEdgeSetTy SVFGEdgeSet
Definition: DDAVFSolver.h:61
const DPTItemSet & getDpmSetAtLoc(const SVFGNode *loc)
Definition: DDAVFSolver.h:664
DPMToCVarMap loadToPTCVarMap
map a load dpm to its cvar pointed by its pointer operand
Definition: DDAVFSolver.h:786
void markbkVisited(const DPIm &dpm)
Visited flags to avoid cycles.
Definition: DDAVFSolver.h:539
NodeBS & getCandidateQueries()
Return candidate pointers for DDA.
Definition: DDAVFSolver.h:91
SVFG * _svfg
SVFG.
Definition: DDAVFSolver.h:775
void addLoadCVar(const DPIm &dpm, const CVar &loadVar)
Definition: DDAVFSolver.h:701
bool isOutOfBudgetQuery() const
Definition: DDAVFSolver.h:732
void backtraceAlongDirectVF(CPtSet &pts, const DPIm &oldDpm)
Backward traverse along direct value flows.
Definition: DDAVFSolver.h:374
bool isTopLevelPtrStmt(const SVFGNode *stmt)
Whether this is a top-level pointer statement.
Definition: DDAVFSolver.h:583
void rmSUStat(const DPIm &dpm, const SVFGNode *node)
remove strong updates num if the dpm goes to weak updates branch
Definition: DDAVFSolver.h:762
DDAVFSolver()
Constructor.
Definition: DDAVFSolver.h:65
OrderedMap< DPIm, CPtSet > DPImToCPtSetMap
Definition: DDAVFSolver.h:56
void reCompute(const DPIm &dpm)
recompute points-to for value-flow cycles and indirect calls
Definition: DDAVFSolver.h:255
void handleOutOfBudgetDpm(const DPIm &dpm)
handle out-of-budget queries
Definition: DDAVFSolver.h:724
virtual bool isStrongUpdate(const CPtSet &dstCPSet, const StoreSVFGNode *store)
Return TRUE if this is a strong update STORE statement.
Definition: DDAVFSolver.h:454
virtual bool unionDDAPts(CPtSet &pts, const CPtSet &targetPts)
Union pts.
Definition: DDAVFSolver.h:102
virtual void handleSingleStatement(const DPIm &dpm, CPtSet &pts)
Handle single statement.
Definition: DDAVFSolver.h:170
bool isbkVisited(const DPIm &dpm)
Definition: DDAVFSolver.h:543
bool isArrayCondMemObj(const CVar &var) const
Definition: DDAVFSolver.h:645
DPMToDPMMap dpmToloadDpmMap
dpms at loads for may/must-alias analysis with stores
Definition: DDAVFSolver.h:785
AndersenWaveDiff * _ander
Andersen's analysis.
Definition: DDAVFSolver.h:776
void dumpCPtSet(const CPtSet &cpts) const
Definition: DDAVFSolver.h:128
LocToDPMVecMap locToDpmSetMap
map location to its dpms
Definition: DDAVFSolver.h:784
void clearbkVisited(const DPIm &dpm)
Definition: DDAVFSolver.h:547
OrderedMap< NodeID, DPTItemSet > LocToDPMVecMap
Definition: DDAVFSolver.h:59
virtual const CPtSet & getCachedTLPointsTo(const DPIm &dpm)
Definition: DDAVFSolver.h:572
DPTItemSet outOfBudgetDpms
out of budget dpm set
Definition: DDAVFSolver.h:787
virtual CPtSet processGepPts(const GepSVFGNode *gep, const CPtSet &srcPts)=0
ProcessGep node to generate field object nodes of a struct.
void OOBResetVisited()
Reset visited map if the current query is out-of-budget.
Definition: DDAVFSolver.h:336
void SVFGSCCDetection()
SVFG SCC detection.
Definition: DDAVFSolver.h:603
void setCallGraphSCC(CallGraphSCC *scc)
Set callgraphSCC.
Definition: DDAVFSolver.h:632
PTACallGraph * _callGraph
PTACallGraph.
Definition: DDAVFSolver.h:778
PTACallGraphEdge::CallInstSet CallInstSet
Definition: DDAVFSolver.h:53
AndersenWaveDiff * getAndersenAnalysis() const
Return Andersen's analysis.
Definition: DDAVFSolver.h:717
virtual DPIm getDPImWithOldCond(const DPIm &oldDpm, const CVar &var, const SVFGNode *loc)
Return dpm with old context and path conditions.
Definition: DDAVFSolver.h:588
SVFG * getSVFG() const
Return SVFG.
Definition: DDAVFSolver.h:118
OrderedMap< const SVFGNode *, DPTItemSet > StoreToPMSetMap
Definition: DDAVFSolver.h:62
void startNewPTCompFromLoadSrc(CPtSet &pts, const DPIm &oldDpm)
Definition: DDAVFSolver.h:392
void reComputeForEdges(const DPIm &dpm, const SVFGEdgeSet &edgeSet, bool indirectCall=false)
Traverse along out edges to find all nodes which may be affected by locDPM.
Definition: DDAVFSolver.h:276
virtual bool propagateViaObj(const CVar &storeObj, const CVar &loadObj)
If the points-to contain the object obj, we could move forward along indirect value-flow edge.
Definition: DDAVFSolver.h:487
virtual void handleAddr(CPtSet &pts, const DPIm &dpm, const AddrSVFGNode *addr)=0
Handle AddrSVFGNode to add proper points-to.
const CVar & getLoadCVar(const DPIm &dpm) const
Definition: DDAVFSolver.h:709
virtual DPIm getDPIm(const CVar &var, const SVFGNode *loc) const
Given CVar and location (SVFGNode) return a new DPItem.
Definition: DDAVFSolver.h:96
const LocToDPMVecMap & getLocToDPMVecMap() const
Map a SVFGNode to its dpms for handling value-flow cycles.
Definition: DDAVFSolver.h:660
void backtraceToStoreSrc(CPtSet &pts, const DPIm &oldDpm)
Definition: DDAVFSolver.h:413
DDAStat * setDDAStat(DDAStat *s)
Set DDAStat.
Definition: DDAVFSolver.h:747
bool isSVFGNodeInCycle(const SVFGNode *node)
Return whether this SVFGNode is in cycle.
Definition: DDAVFSolver.h:617
NodeBS candidateQueries
candidate pointers;
Definition: DDAVFSolver.h:777
void addOutOfBudgetDpm(const DPIm &dpm)
Definition: DDAVFSolver.h:736
virtual const CPtSet & getCachedPointsTo(const DPIm &dpm)
Points-to Caching for top-level pointers and address-taken objects.
Definition: DDAVFSolver.h:556
DDAStat * ddaStat
DDA stat.
Definition: DDAVFSolver.h:789
virtual bool unionDDAPts(DPIm dpm, const CPtSet &targetPts)
Union pts.
Definition: DDAVFSolver.h:107
void addSUStat(const DPIm &dpm, const SVFGNode *node)
stat strong updates num
Definition: DDAVFSolver.h:753
OrderedSet< const SVFGEdge * > ConstSVFGEdgeSet
Definition: DDAVFSolver.h:60
OrderedMap< DPIm, CVar > DPMToCVarMap
Definition: DDAVFSolver.h:57
virtual void buildSVFG(SVFIR *pag)
Build SVFG.
Definition: DDAVFSolver.h:317
StoreToPMSetMap storeToDPMs
map store to set of DPM which have been stong updated there
Definition: DDAVFSolver.h:788
virtual void backwardPropDpm(CPtSet &pts, NodeID ptr, const DPIm &oldDpm, const SVFGEdge *edge)
dpm transit during backward tracing
Definition: DDAVFSolver.h:426
SCCDetection< PTACallGraph * > CallGraphSCC
Definition: DDAVFSolver.h:52
void addDpmToLoc(const DPIm &dpm)
Definition: DDAVFSolver.h:668
void setCallGraph(PTACallGraph *cg)
Set callgraph.
Definition: DDAVFSolver.h:627
void resolveFunPtr(const DPIm &dpm)
resolve function pointer
Definition: DDAVFSolver.h:492
bool outOfBudgetQuery
Whether the current query is out of step limits.
Definition: DDAVFSolver.h:773
virtual void resetQuery()
Reset visited map for next points-to query.
Definition: DDAVFSolver.h:324
void startNewPTCompFromStoreDst(CPtSet &pts, const DPIm &oldDpm)
Definition: DDAVFSolver.h:403
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeID getDstID() const
Definition: GenericGraph.h:85
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:81
NodeType * getDstNode() const
Definition: GenericGraph.h:101
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
bool isFieldInsensitive() const
Return true if its field limit is 0.
bool isHeap() const
bool isArray() const
bool isStack() const
Set< const CallICFGNode * > CallInstSet
Definition: PTACallGraph.h:55
void getIndCallSitesInvokingCallee(const SVFFunction *callee, PTACallGraphEdge::CallInstSet &csSet)
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.
Definition: PTACallGraph.h:339
PTACallGraph * getCallGraph() const
Return call graph.
void find(void)
Definition: SCC.h:308
NodeID repNode(NodeID n) const
get the rep node if not found return itself
Definition: SCC.h:139
bool isInCycle(NodeID n) const
whether the node is in a cycle
Definition: SCC.h:149
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
SVFG * buildPTROnlySVFG(BVDataPTAImpl *pta)
Definition: SVFGBuilder.cpp:41
Definition: SVFG.h:66
const SVFGNode * getDefSVFGNode(const PAGNode *pagNode) const
Given a pagNode, return its definition site.
Definition: SVFG.h:171
NodeID getFunPtr(const CallICFGNode *cs) const
Definition: SVFIR.h:354
Set< const CallICFGNode * > CallSiteSet
Definition: SVFIR.h:54
const MemObj * getObject(NodeID id) const
Definition: SVFIR.h:395
bool isIndirectCallSites(const CallICFGNode *cs) const
Definition: SVFIR.h:366
bool isConstantObj(NodeID id) const
Definition: SVFIR.h:443
bool isFunPtr(NodeID id) const
Definition: SVFIR.h:370
const CallSiteSet & getIndCallSites(NodeID funPtr) const
Definition: SVFIR.h:360
const MemObj * getBaseObj(NodeID id) const
Definition: SVFIR.h:459
static double getClk(bool mark=false)
Definition: SVFStat.cpp:47
virtual const SVFFunction * getFunction() const
Return the function that this SVFVar resides in. Return nullptr if it is a global or constantexpr nod...
Definition: SVFVariables.h:122
bool test(unsigned Idx) const
void set(unsigned Idx)
void reset(unsigned Idx)
NodeID getPAGDstNodeID() const
Definition: VFGNode.h:157
NodeID getPAGSrcNodeID() const
Definition: VFGNode.h:152
PAGNode * getPAGSrcNode() const
Definition: VFGNode.h:162
PAGNode * getPAGDstNode() const
Definition: VFGNode.h:167
@ IntraDirectVF
Definition: VFGEdge.h:53
VFGEdgeSetTy SVFGEdgeSetTy
Definition: VFGEdge.h:118
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
Definition: VFGNode.h:55
SVFIR * getPAG() const
Return SVFIR.
Definition: VFG.h:133
VFGEdge * getIntraVFGEdge(const VFGNode *src, const VFGNode *dst, VFGEdge::VFGEdgeK kind)
Get a SVFG edge according to src and dst.
Definition: VFG.cpp:928
LLVM_NODISCARD bool isa(const Y &Val)
Definition: Casting.h:241
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
std::set< Key, Compare, Allocator > OrderedSet
Definition: GeneralType.h:105
void dump(const SparseBitVector< ElementSize > &LHS, std::ostream &out)
std::map< Key, Value, Compare, Allocator > OrderedMap
Definition: GeneralType.h:109