Static Value-Flow Analysis
MutablePointsToDS.h
Go to the documentation of this file.
1 //===- MutablePointsToDS.h -- Mutable points-to data structure-------------//
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 
25 
26 /*
27  * MutablePointsToDS.h
28  *
29  * Authors: Mohamad Barbar and Yulei Sui
30  *
31  * The implementation is based on
32  * Mohamad Barbar and Yulei Sui. Hash Consed Points-To Sets.
33  * 28th Static Analysis Symposium (SAS'21)
34  */
35 
36 #ifndef MUTABLE_POINTSTO_H_
37 #define MUTABLE_POINTSTO_H_
38 
39 #include<fstream>
40 
42 #include "SVFIR/SVFType.h"
43 #include "Util/SVFUtil.h"
44 
45 namespace SVF
46 {
47 
48 template <typename Key, typename KeySet, typename Data, typename DataSet>
49 class MutableDFPTData;
50 
52 template <typename Key, typename KeySet, typename Data, typename DataSet>
53 class MutablePTData : public PTData<Key, KeySet, Data, DataSet>
54 {
55  friend class MutableDFPTData<Key, KeySet, Data, DataSet>;
56 public:
58  typedef typename BasePTData::PTDataTy PTDataTy;
59 
62  typedef typename PtsMap::iterator PtsMapIter;
63  typedef typename PtsMap::const_iterator PtsMapConstIter;
64  typedef typename DataSet::iterator iterator;
65 
67  MutablePTData(bool reversePT = true, PTDataTy ty = PTDataTy::MutBase) : BasePTData(reversePT, ty) { }
68 
69  virtual ~MutablePTData() { }
70 
72  virtual inline const PtsMap& getPtsMap() const
73  {
74  return ptsMap;
75  }
76 
77  virtual inline void clear() override
78  {
79  ptsMap.clear();
80  revPtsMap.clear();
81  }
82 
83  virtual inline const DataSet& getPts(const Key& var) override
84  {
85  return ptsMap[var];
86  }
87 
88  virtual inline const KeySet& getRevPts(const Data& datum) override
89  {
90  assert(this->rev && "MutablePTData::getRevPts: constructed without reverse PT support!");
91  return revPtsMap[datum];
92  }
93 
94  virtual inline bool addPts(const Key &dstKey, const Data& element) override
95  {
96  addSingleRevPts(revPtsMap[element], dstKey);
97  return addPts(ptsMap[dstKey], element);
98  }
99 
100  virtual inline bool unionPts(const Key& dstKey, const Key& srcKey) override
101  {
102  addRevPts(ptsMap[srcKey], dstKey);
103  return unionPts(ptsMap[dstKey], getPts(srcKey));
104  }
105 
106  virtual inline bool unionPts(const Key& dstKey, const DataSet& srcDataSet) override
107  {
108  addRevPts(srcDataSet,dstKey);
109  return unionPts(ptsMap[dstKey], srcDataSet);
110  }
111 
112  virtual inline void dumpPTData() override
113  {
114  dumpPts(ptsMap);
115  }
116 
117  virtual void clearPts(const Key& var, const Data& element) override
118  {
119  clearSingleRevPts(revPtsMap[element], var);
120  ptsMap[var].reset(element);
121  }
122 
123  virtual void clearFullPts(const Key& var) override
124  {
125  DataSet &pts = ptsMap[var];
126  clearRevPts(pts, var);
127  pts.clear();
128  }
129 
130  virtual void remapAllPts(void) override
131  {
132  for (typename PtsMap::value_type &ppt : ptsMap) ppt.second.checkAndRemap();
133  }
134 
135  virtual inline Map<DataSet, unsigned> getAllPts(bool liveOnly) const override
136  {
137  Map<DataSet, unsigned> allPts;
138  for (typename PtsMap::value_type ppt : ptsMap)
139  {
140  const DataSet &pt = ppt.second;
141  ++allPts[pt];
142  }
143 
144  return allPts;
145  }
146 
150  {
151  return true;
152  }
153 
154  static inline bool classof(const PTData<Key, KeySet, Data, DataSet>* ptd)
155  {
156  return ptd->getPTDTY() == PTDataTy::MutBase;
157  }
159 
160 protected:
161  virtual inline void dumpPts(const PtsMap & ptsSet,OutStream & O = SVFUtil::outs()) const
162  {
163  for (PtsMapConstIter nodeIt = ptsSet.begin(); nodeIt != ptsSet.end(); nodeIt++)
164  {
165  const Key& var = nodeIt->first;
166  const DataSet & pts = nodeIt->second;
167  if (pts.empty())
168  continue;
169  O << var << " ==> { ";
170  for(typename DataSet::iterator cit = pts.begin(), ecit=pts.end(); cit!=ecit; ++cit)
171  {
172  O << *cit << " ";
173  }
174  O << "}\n";
175  }
176  }
177 
178 private:
181  inline bool unionPts(DataSet& dstDataSet, const DataSet& srcDataSet)
182  {
183  return dstDataSet |= srcDataSet;
184  }
185  inline bool addPts(DataSet &d, const Data& e)
186  {
187  return d.test_and_set(e);
188  }
189  inline void addSingleRevPts(KeySet &revData, const Key& tgr)
190  {
191  if (this->rev)
192  {
193  SVFUtil::insertKey(tgr, revData);
194  }
195  }
196  inline void addRevPts(const DataSet &ptsData, const Key& tgr)
197  {
198  if (this->rev)
199  {
200  for(iterator it = ptsData.begin(), eit = ptsData.end(); it!=eit; ++it)
201  addSingleRevPts(revPtsMap[*it], tgr);
202  }
203  }
204  inline void clearSingleRevPts(KeySet &revSet, const Key &k)
205  {
206  if (this->rev)
207  {
208  SVFUtil::removeKey(k, revSet);
209  }
210  }
211  inline void clearRevPts(const DataSet &pts, const Key &k)
212  {
213  if (this->rev)
214  {
215  for (const Data &d : pts) clearSingleRevPts(revPtsMap[d], k);
216  }
217  }
219 
220 protected:
223 };
224 
226 template <typename Key, typename KeySet, typename Data, typename DataSet>
227 class MutableDiffPTData : public DiffPTData<Key, KeySet, Data, DataSet>
228 {
229 public:
232  typedef typename BasePTData::PTDataTy PTDataTy;
233 
235 
237  explicit MutableDiffPTData(bool reversePT = true, PTDataTy ty = PTDataTy::Diff) : BaseDiffPTData(reversePT, ty), mutPTData(reversePT) { }
238 
239  ~MutableDiffPTData() override = default;
240 
241  virtual inline const PtsMap& getPtsMap() const
242  {
243  return mutPTData.getPtsMap();
244  }
245 
246  inline void clear() override
247  {
248  mutPTData.clear();
249  }
250 
251  virtual inline const DataSet& getPts(const Key& var) override
252  {
253  return mutPTData.getPts(var);
254  }
255 
256  virtual inline const KeySet& getRevPts(const Data& datum) override
257  {
258  assert(this->rev && "MutableDiffPTData::getRevPts: constructed without reverse PT support!");
259  return mutPTData.getRevPts(datum);
260  }
261 
262  virtual inline bool addPts(const Key &dstKey, const Data& element) override
263  {
264  return mutPTData.addPts(dstKey, element);
265  }
266 
267  virtual inline bool unionPts(const Key& dstKey, const Key& srcKey) override
268  {
269  return mutPTData.unionPts(dstKey, srcKey);
270  }
271 
272  virtual inline bool unionPts(const Key& dstKey, const DataSet& srcDataSet) override
273  {
274  return mutPTData.unionPts(dstKey, srcDataSet);
275  }
276 
277  virtual void clearPts(const Key& var, const Data& element) override
278  {
279  mutPTData.clearPts(var, element);
280  }
281 
282  virtual void clearFullPts(const Key& var) override
283  {
284  mutPTData.clearFullPts(var);
285  }
286 
287  virtual void remapAllPts(void) override
288  {
289  mutPTData.remapAllPts();
290  for (typename PtsMap::value_type &ppt : diffPtsMap) ppt.second.checkAndRemap();
291  for (typename PtsMap::value_type &ppt : propaPtsMap) ppt.second.checkAndRemap();
292  }
293 
294  virtual inline void dumpPTData() override
295  {
296  mutPTData.dumpPTData();
297  }
298 
299  virtual inline const DataSet &getDiffPts(Key &var) override
300  {
301  return diffPtsMap[var];
302  }
303 
304  virtual inline bool computeDiffPts(Key &var, const DataSet &all) override
305  {
307  DataSet& diff = diffPtsMap[var];
308  diff.clear();
310  DataSet& propa = getPropaPts(var);
311  diff.intersectWithComplement(all, propa);
312  propa = all;
313  return !diff.empty();
314  }
315 
316  virtual inline void updatePropaPtsMap(Key &src, Key &dst) override
317  {
318  DataSet& srcPropa = getPropaPts(src);
319  DataSet& dstPropa = getPropaPts(dst);
320  dstPropa &= srcPropa;
321  }
322 
323  virtual inline void clearPropaPts(Key &var) override
324  {
325  getPropaPts(var).clear();
326  }
327 
328  virtual inline Map<DataSet, unsigned> getAllPts(bool liveOnly) const override
329  {
330  return mutPTData.getAllPts(liveOnly);
331  }
332 
336  {
337  return true;
338  }
339 
340  static inline bool classof(const PTData<Key, KeySet, Data, DataSet>* ptd)
341  {
342  return ptd->getPTDTY() == PTDataTy::MutDiff;
343  }
345 
346 protected:
348  inline DataSet &getPropaPts(Key &var)
349  {
350  return propaPtsMap[var];
351  }
352 
353 private:
360 };
361 
362 template <typename Key, typename KeySet, typename Data, typename DataSet>
363 class MutableDFPTData : public DFPTData<Key, KeySet, Data, DataSet>
364 {
365 public:
369  typedef typename BasePTData::PTDataTy PTDataTy;
370 
371  typedef typename BaseDFPTData::LocID LocID;
372  typedef typename BaseMutPTData::PtsMap PtsMap;
375  typedef typename DFPtsMap::iterator DFPtsMapIter;
376  typedef typename DFPtsMap::const_iterator DFPtsMapconstIter;
377 
379  MutableDFPTData(bool reversePT = true, PTDataTy ty = BaseDFPTData::MutDataFlow) : BaseDFPTData(reversePT, ty), mutPTData(reversePT) { }
380 
381  virtual ~MutableDFPTData() { }
382 
383  virtual inline const PtsMap& getPtsMap() const
384  {
385  return mutPTData.getPtsMap();
386  }
387 
388  virtual inline void clear() override
389  {
390  mutPTData.clear();
391  }
392 
393  virtual inline const DataSet& getPts(const Key& var) override
394  {
395  return mutPTData.getPts(var);
396  }
397 
398  virtual inline const KeySet& getRevPts(const Data& datum) override
399  {
400  assert(this->rev && "MutableDFPTData::getRevPts: constructed without reverse PT support!");
401  return mutPTData.getRevPts(datum);
402  }
403 
404  virtual inline bool hasDFInSet(LocID loc) const override
405  {
406  return (dfInPtsMap.find(loc) != dfInPtsMap.end());
407  }
408 
409  virtual inline bool hasDFOutSet(LocID loc) const override
410  {
411  return (dfOutPtsMap.find(loc) != dfOutPtsMap.end());
412  }
413 
414  virtual inline bool hasDFInSet(LocID loc,const Key& var) const override
415  {
416  DFPtsMapconstIter it = dfInPtsMap.find(loc);
417  if ( it == dfInPtsMap.end())
418  return false;
419  const PtsMap& ptsMap = it->second;
420  return (ptsMap.find(var) != ptsMap.end());
421  }
422 
423  virtual inline bool hasDFOutSet(LocID loc, const Key& var) const override
424  {
425  DFPtsMapconstIter it = dfOutPtsMap.find(loc);
426  if ( it == dfOutPtsMap.end())
427  return false;
428  const PtsMap& ptsMap = it->second;
429  return (ptsMap.find(var) != ptsMap.end());
430  }
431 
432  virtual inline DataSet& getDFInPtsSet(LocID loc, const Key& var) override
433  {
434  PtsMap& inSet = dfInPtsMap[loc];
435  return inSet[var];
436  }
437 
438  virtual inline DataSet& getDFOutPtsSet(LocID loc, const Key& var) override
439  {
440  PtsMap& outSet = dfOutPtsMap[loc];
441  return outSet[var];
442  }
443 
446  inline const PtsMap& getDFInPtsMap(LocID loc)
447  {
448  return dfInPtsMap[loc];
449  }
450  inline const PtsMap& getDFOutPtsMap(LocID loc)
451  {
452  return dfOutPtsMap[loc];
453  }
454  inline const DFPtsMap& getDFIn()
455  {
456  return dfInPtsMap;
457  }
458  inline const DFPtsMap& getDFOut()
459  {
460  return dfOutPtsMap;
461  }
463 
464  virtual inline bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
465  {
466  return this->unionPts(getDFInPtsSet(dstLoc,dstVar), getDFInPtsSet(srcLoc,srcVar));
467  }
468 
469  virtual inline bool updateDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
470  {
471  return this->unionPts(getDFInPtsSet(dstLoc,dstVar), getDFOutPtsSet(srcLoc,srcVar));
472  }
473 
474  virtual inline bool updateDFOutFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
475  {
476  return this->unionPts(getDFOutPtsSet(dstLoc,dstVar), getDFInPtsSet(srcLoc,srcVar));
477  }
478 
479  virtual inline bool updateAllDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
480  {
481  return this->updateDFInFromOut(srcLoc,srcVar,dstLoc,dstVar);
482  }
483 
484  virtual inline bool updateAllDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
485  {
486  return this->updateDFInFromIn(srcLoc,srcVar,dstLoc,dstVar);
487  }
488 
489  virtual inline bool updateAllDFOutFromIn(LocID loc, const Key& singleton, bool strongUpdates) override
490  {
491  bool changed = false;
492  if (this->hasDFInSet(loc))
493  {
495  const PtsMap & ptsMap = getDFInPtsMap(loc);
496  for (typename PtsMap::const_iterator ptsIt = ptsMap.begin(), ptsEit = ptsMap.end(); ptsIt != ptsEit; ++ptsIt)
497  {
498  const Key var = ptsIt->first;
500  if (strongUpdates && var == singleton)
501  continue;
502  if (updateDFOutFromIn(loc, var, loc, var))
503  changed = true;
504  }
505  }
506  return changed;
507  }
508 
509  virtual inline bool updateTLVPts(LocID srcLoc, const Key& srcVar, const Key& dstVar) override
510  {
511  return this->unionPts(dstVar, this->getDFInPtsSet(srcLoc,srcVar));
512  }
513 
514  virtual inline bool updateATVPts(const Key& srcVar, LocID dstLoc, const Key& dstVar) override
515  {
516  return (this->unionPts(this->getDFOutPtsSet(dstLoc, dstVar), this->getPts(srcVar)));
517  }
518 
519  virtual inline void clearAllDFOutUpdatedVar(LocID) override
520  {
521  }
522 
526  virtual inline bool addPts(const Key &dstKey, const Key& srcKey) override
527  {
528  return addPts(mutPTData.ptsMap[dstKey], srcKey);
529  }
530  virtual inline bool unionPts(const Key& dstKey, const Key& srcKey) override
531  {
532  return unionPts(mutPTData.ptsMap[dstKey], getPts(srcKey));
533  }
534  virtual inline bool unionPts(const Key& dstKey, const DataSet& srcDataSet) override
535  {
536  return unionPts(mutPTData.ptsMap[dstKey], srcDataSet);
537  }
538  virtual void clearPts(const Key& var, const Data& element) override
539  {
540  mutPTData.clearPts(var, element);
541  }
542  virtual void clearFullPts(const Key& var) override
543  {
544  mutPTData.clearFullPts(var);
545  }
546  virtual void remapAllPts(void) override
547  {
548  mutPTData.remapAllPts();
549  for (typename DFPtsMap::value_type &lopt : dfInPtsMap)
550  {
551  for (typename PtsMap::value_type &opt : lopt.second) opt.second.checkAndRemap();
552  }
553 
554  for (typename DFPtsMap::value_type &lopt : dfOutPtsMap)
555  {
556  for (typename PtsMap::value_type &opt : lopt.second) opt.second.checkAndRemap();
557  }
558  }
560 
561  virtual inline Map<DataSet, unsigned> getAllPts(bool liveOnly) const override
562  {
563  Map<DataSet, unsigned> allPts = mutPTData.getAllPts(liveOnly);
564  for (typename DFPtsMap::value_type lptsmap : dfInPtsMap)
565  {
566  for (typename PtsMap::value_type vpt : lptsmap.second)
567  {
568  ++allPts[vpt.second];
569  }
570  }
571 
572  for (typename DFPtsMap::value_type lptm : dfOutPtsMap)
573  {
574  for (typename PtsMap::value_type vpt : lptm.second)
575  {
576  ++allPts[vpt.second];
577  }
578  }
579 
580  return allPts;
581  }
582 
586  {
587  return true;
588  }
589  static inline bool classof(const PTData<Key, KeySet, Data, DataSet>* ptd)
590  {
591  return ptd->getPTDTY() == BaseDFPTData::MutDataFlow
593  }
595 
596 protected:
599  inline bool unionPts(DataSet& dstDataSet, const DataSet& srcDataSet)
600  {
601  return dstDataSet |= srcDataSet;
602  }
603  inline bool addPts(DataSet &d, const Data& e)
604  {
605  return d.test_and_set(e);
606  }
608 
609 public:
612  virtual inline void dumpPTData() override
613  {
615  mutPTData.dumpPTData();
617  std::error_code ErrInfo;
618  std::fstream f("svfg_pts.data", std::ios_base::out);
619  if (f.good())
620  {
621  NodeBS locs;
622  for(DFPtsMapconstIter it = dfInPtsMap.begin(), eit = dfInPtsMap.end(); it!=eit; ++it)
623  locs.set(it->first);
624 
625  for(DFPtsMapconstIter it = dfOutPtsMap.begin(), eit = dfOutPtsMap.end(); it!=eit; ++it)
626  locs.set(it->first);
627 
628  for (NodeBS::iterator it = locs.begin(), eit = locs.end(); it != eit; it++)
629  {
630  LocID loc = *it;
631  if (this->hasDFInSet(loc))
632  {
633  f << "Loc:" << loc << " IN:{";
634  this->dumpPts(this->getDFInPtsMap(loc), f);
635  f << "}\n";
636  }
637 
638  if (this->hasDFOutSet(loc))
639  {
640  f << "Loc:" << loc << " OUT:{";
641  this->dumpPts(this->getDFOutPtsMap(loc), f);
642  f << "}\n";
643  }
644  }
645  f.close();
646  if (f.good())
647  {
648  SVFUtil::outs() << "\n";
649  return;
650  }
651  }
652  SVFUtil::outs() << " error opening file for writing!\n";
653  }
654 
655  virtual inline void dumpPts(const PtsMap & ptsSet,OutStream & O = SVFUtil::outs()) const
656  {
657  for (PtsMapConstIter nodeIt = ptsSet.begin(); nodeIt != ptsSet.end(); nodeIt++)
658  {
659  const Key& var = nodeIt->first;
660  const DataSet & pts = nodeIt->second;
661  if (pts.empty())
662  continue;
663  O << "<" << var << ",{";
664  SVFUtil::dumpSet(pts,O);
665  O << "}> ";
666  }
667  }
669 
670 protected:
678 };
679 
681 template <typename Key, typename KeySet, typename Data, typename DataSet>
682 class MutableIncDFPTData : public MutableDFPTData<Key, KeySet, Data, DataSet>
683 {
684 public:
689  typedef typename BasePTData::PTDataTy PTDataTy;
690 
691  typedef typename BaseDFPTData::LocID LocID;
693  typedef typename UpdatedVarMap::iterator UpdatedVarMapIter;
694  typedef typename UpdatedVarMap::const_iterator UpdatedVarconstIter;
695  typedef typename DataSet::iterator DataIter;
696 
697 private:
700 
701 public:
703  MutableIncDFPTData(bool reversePT = true, PTDataTy ty = BasePTData::MutIncDataFlow) : BaseMutDFPTData(reversePT, ty) { }
704 
705  virtual ~MutableIncDFPTData() { }
706 
707  virtual inline bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
708  {
709  if(varHasNewDFInPts(srcLoc, srcVar) &&
710  this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFInPtsSet(srcLoc,srcVar)))
711  {
712  setVarDFInSetUpdated(dstLoc,dstVar);
713  return true;
714  }
715  return false;
716  }
717 
718  virtual inline bool updateDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
719  {
720  if(varHasNewDFOutPts(srcLoc, srcVar) &&
721  this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFOutPtsSet(srcLoc,srcVar)))
722  {
723  setVarDFInSetUpdated(dstLoc,dstVar);
724  return true;
725  }
726  return false;
727  }
728 
729  virtual inline bool updateDFOutFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
730  {
731  if(varHasNewDFInPts(srcLoc,srcVar))
732  {
733  removeVarFromDFInUpdatedSet(srcLoc,srcVar);
734  if (this->unionPts(this->getDFOutPtsSet(dstLoc,dstVar), this->getDFInPtsSet(srcLoc,srcVar)))
735  {
736  setVarDFOutSetUpdated(dstLoc,dstVar);
737  return true;
738  }
739  }
740  return false;
741  }
742 
743  virtual inline bool updateAllDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
744  {
745  if(this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFOutPtsSet(srcLoc,srcVar)))
746  {
747  setVarDFInSetUpdated(dstLoc,dstVar);
748  return true;
749  }
750  return false;
751  }
752 
753  virtual inline bool updateAllDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
754  {
755  if(this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFInPtsSet(srcLoc,srcVar)))
756  {
757  setVarDFInSetUpdated(dstLoc,dstVar);
758  return true;
759  }
760  return false;
761  }
762 
763  virtual inline bool updateAllDFOutFromIn(LocID loc, const Key& singleton, bool strongUpdates) override
764  {
765  bool changed = false;
766  if (this->hasDFInSet(loc))
767  {
769  DataSet pts = getDFInUpdatedVar(loc);
770  for (DataIter ptsIt = pts.begin(), ptsEit = pts.end(); ptsIt != ptsEit; ++ptsIt)
771  {
772  const Key var = *ptsIt;
774  if (strongUpdates && var == singleton)
775  continue;
776  if (updateDFOutFromIn(loc, var, loc, var))
777  changed = true;
778  }
779  }
780  return changed;
781  }
782 
783  virtual inline bool updateTLVPts(LocID srcLoc, const Key& srcVar, const Key& dstVar) override
784  {
785  if(varHasNewDFInPts(srcLoc,srcVar))
786  {
787  removeVarFromDFInUpdatedSet(srcLoc,srcVar);
788  return this->mutPTData.unionPts(dstVar, this->getDFInPtsSet(srcLoc,srcVar));
789  }
790  return false;
791  }
792 
793  virtual inline bool updateATVPts(const Key& srcVar, LocID dstLoc, const Key& dstVar) override
794  {
795  if (this->unionPts(this->getDFOutPtsSet(dstLoc, dstVar), this->mutPTData.getPts(srcVar)))
796  {
797  setVarDFOutSetUpdated(dstLoc, dstVar);
798  return true;
799  }
800  return false;
801  }
802 
803  virtual inline void clearAllDFOutUpdatedVar(LocID loc) override
804  {
805  if (this->hasDFOutSet(loc))
806  {
807  DataSet pts = getDFOutUpdatedVar(loc);
808  for (DataIter ptsIt = pts.begin(), ptsEit = pts.end(); ptsIt != ptsEit; ++ptsIt)
809  {
810  const Key var = *ptsIt;
812  }
813  }
814  }
815 
819  {
820  return true;
821  }
822 
823  static inline bool classof(const PTData<Key, KeySet, Data, DataSet>* ptd)
824  {
825  return ptd->getPTDTY() == BasePTData::MutIncDataFlow;
826  }
828 private:
830 
831  inline void setVarDFInSetUpdated(LocID loc,const Key& var)
833  {
834  inUpdatedVarMap[loc].set(var);
835  }
837  inline void removeVarFromDFInUpdatedSet(LocID loc,const Key& var)
838  {
839  UpdatedVarMapIter it = inUpdatedVarMap.find(loc);
840  if (it != inUpdatedVarMap.end())
841  it->second.reset(var);
842  }
844  inline bool varHasNewDFInPts(LocID loc,const Key& var)
845  {
846  UpdatedVarMapIter it = inUpdatedVarMap.find(loc);
847  if (it != inUpdatedVarMap.end())
848  return it->second.test(var);
849  return false;
850  }
852  inline const DataSet& getDFInUpdatedVar(LocID loc)
853  {
854  return inUpdatedVarMap[loc];
855  }
857 
859 
860  inline void setVarDFOutSetUpdated(LocID loc,const Key& var)
862  {
863  outUpdatedVarMap[loc].set(var);
864  }
866  inline void removeVarFromDFOutUpdatedSet(LocID loc,const Key& var)
867  {
868  UpdatedVarMapIter it = outUpdatedVarMap.find(loc);
869  if (it != outUpdatedVarMap.end())
870  it->second.reset(var);
871  }
873  inline bool varHasNewDFOutPts(LocID loc,const Key& var)
874  {
875  UpdatedVarMapIter it = outUpdatedVarMap.find(loc);
876  if (it != outUpdatedVarMap.end())
877  return it->second.test(var);
878  return false;
879  }
881  inline const DataSet& getDFOutUpdatedVar(LocID loc)
882  {
883  return outUpdatedVarMap[loc];
884  }
886 };
887 
891 template <typename Key, typename KeySet, typename Data, typename DataSet, typename VersionedKey, typename VersionedKeySet>
892 class MutableVersionedPTData : public VersionedPTData<Key, KeySet, Data, DataSet, VersionedKey, VersionedKeySet>
893 {
894 public:
897  typedef typename BasePTData::PTDataTy PTDataTy;
898 
899  MutableVersionedPTData(bool reversePT = true, PTDataTy ty = PTDataTy::MutVersioned)
900  : BaseVersionedPTData(reversePT, ty), tlPTData(reversePT), atPTData(reversePT) { }
901 
903 
904  virtual inline void clear() override
905  {
906  tlPTData.clear();
907  atPTData.clear();
908  }
909 
910  virtual const DataSet& getPts(const Key& vk) override
911  {
912  return tlPTData.getPts(vk);
913  }
914  virtual const DataSet& getPts(const VersionedKey& vk) override
915  {
916  return atPTData.getPts(vk);
917  }
918 
919  virtual const KeySet& getRevPts(const Data& datum) override
920  {
921  assert(this->rev && "MutableVersionedPTData::getRevPts: constructed without reverse PT support!");
922  return tlPTData.getRevPts(datum);
923  }
924  virtual const VersionedKeySet& getVersionedKeyRevPts(const Data& datum) override
925  {
926  assert(this->rev && "MutableVersionedPTData::getVersionedKeyRevPts: constructed without reverse PT support!");
927  return atPTData.getRevPts(datum);
928  }
929 
930  virtual bool addPts(const Key& k, const Data& element) override
931  {
932  return tlPTData.addPts(k, element);
933  }
934  virtual bool addPts(const VersionedKey& vk, const Data& element) override
935  {
936  return atPTData.addPts(vk, element);
937  }
938 
939  virtual bool unionPts(const Key& dstVar, const Key& srcVar) override
940  {
941  return tlPTData.unionPts(dstVar, srcVar);
942  }
943  virtual bool unionPts(const VersionedKey& dstVar, const VersionedKey& srcVar) override
944  {
945  return atPTData.unionPts(dstVar, srcVar);
946  }
947  virtual bool unionPts(const VersionedKey& dstVar, const Key& srcVar) override
948  {
949  return atPTData.unionPts(dstVar, tlPTData.getPts(srcVar));
950  }
951  virtual bool unionPts(const Key& dstVar, const VersionedKey& srcVar) override
952  {
953  return tlPTData.unionPts(dstVar, atPTData.getPts(srcVar));
954  }
955  virtual bool unionPts(const Key& dstVar, const DataSet& srcDataSet) override
956  {
957  return tlPTData.unionPts(dstVar, srcDataSet);
958  }
959  virtual bool unionPts(const VersionedKey& dstVar, const DataSet& srcDataSet) override
960  {
961  return atPTData.unionPts(dstVar, srcDataSet);
962  }
963 
964  virtual void clearPts(const Key& k, const Data& element) override
965  {
966  tlPTData.clearPts(k, element);
967  }
968  virtual void clearPts(const VersionedKey& vk, const Data& element) override
969  {
970  atPTData.clearPts(vk, element);
971  }
972 
973  virtual void clearFullPts(const Key& k) override
974  {
975  tlPTData.clearFullPts(k);
976  }
977  virtual void clearFullPts(const VersionedKey& vk) override
978  {
980  }
981 
982  virtual void remapAllPts(void) override
983  {
984  tlPTData.remapAllPts();
986  }
987 
988  virtual inline Map<DataSet, unsigned> getAllPts(bool liveOnly) const override
989  {
990  Map<DataSet, unsigned> allPts = tlPTData.getAllPts(liveOnly);
991  SVFUtil::mergePtsOccMaps<DataSet>(allPts, atPTData.getAllPts(liveOnly));
992  return allPts;
993  }
994 
995  virtual inline void dumpPTData() override
996  {
997  SVFUtil::outs() << "== Top-level points-to information\n";
998  tlPTData.dumpPTData();
999  SVFUtil::outs() << "== Address-taken points-to information\n";
1000  atPTData.dumpPTData();
1001  }
1002 
1006  {
1007  return true;
1008  }
1009 
1010  static inline bool classof(const PTData<Key, KeySet, Data, DataSet>* ptd)
1011  {
1012  return ptd->getPTDTY() == PTDataTy::MutVersioned;
1013  }
1015 
1016 private:
1021 };
1022 
1023 } // End namespace SVF
1024 
1025 #endif // MUTABLE_POINTSTO_H_
const PtsMap & getDFOutPtsMap(LocID loc)
Map< LocID, PtsMap > DFPtsMap
Data-flow point-to map.
virtual bool updateATVPts(const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Update address-taken variables OUT[dstLoc:dstVar] with points-to of top-level pointers.
DFPTData< Key, KeySet, Data, DataSet > BaseDFPTData
virtual bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar) override
Update points-to set of top-level pointers with IN[srcLoc:srcVar].
virtual bool updateAllDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc::dstVar], IN[srcLoc:srcVar]. There is no flag check, unlike the above.
PTData< Key, KeySet, Data, DataSet > BasePTData
virtual const KeySet & getRevPts(const Data &datum) override
Get reverse points-to set of a datum.
DFPtsMap::iterator DFPtsMapIter
BaseMutPTData::PtsMapConstIter PtsMapConstIter
virtual void clearAllDFOutUpdatedVar(LocID) override
virtual void clear() override
Clears all points-to sets as if nothing is stored.
virtual DataSet & getDFInPtsSet(LocID loc, const Key &var) override
virtual const DataSet & getPts(const Key &var) override
Get points-to set of var.
virtual bool updateAllDFOutFromIn(LocID loc, const Key &singleton, bool strongUpdates) override
For each variable var in IN at loc, do updateDFOutFromIn(loc, var, loc, var).
static bool classof(const MutableDFPTData< Key, KeySet, Data, DataSet > *)
const DFPtsMap & getDFOut()
const PtsMap & getDFInPtsMap(LocID loc)
virtual bool updateAllDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc::dstVar], OUT[srcLoc:srcVar]. There is no flag check, unlike the above.
virtual bool updateDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc:dstVar], OUT[srcLoc:srcVar]).
virtual const PtsMap & getPtsMap() const
bool unionPts(DataSet &dstDataSet, const DataSet &srcDataSet)
virtual void dumpPTData() override
virtual bool hasDFInSet(LocID loc) const override
virtual bool hasDFInSet(LocID loc, const Key &var) const override
virtual void clearFullPts(const Key &var) override
Fully clears the points-to set of var.
virtual bool updateDFOutFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (OUT[dstLoc:dstVar], IN[srcLoc:srcVar]).
virtual bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
virtual DataSet & getDFOutPtsSet(LocID loc, const Key &var) override
virtual bool addPts(const Key &dstKey, const Key &srcKey) override
bool addPts(DataSet &d, const Data &e)
DFPtsMap dfInPtsMap
Data-flow IN set.
virtual bool updateDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
virtual bool hasDFOutSet(LocID loc) const override
virtual Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
MutablePTData< Key, KeySet, Data, DataSet > mutPTData
MutablePTData< Key, KeySet, Data, DataSet > BaseMutPTData
virtual void remapAllPts(void) override
Remaps all points-to sets to use the current mapping.
DFPtsMap dfOutPtsMap
Data-flow OUT set.
virtual bool unionPts(const Key &dstKey, const Key &srcKey) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
DFPtsMap::const_iterator DFPtsMapconstIter
virtual void clearPts(const Key &var, const Data &element) override
Clears element from the points-to set of var.
BaseMutPTData::PtsMap PtsMap
BaseDFPTData::LocID LocID
virtual void dumpPts(const PtsMap &ptsSet, OutStream &O=SVFUtil::outs()) const
const DFPtsMap & getDFIn()
MutableDFPTData(bool reversePT=true, PTDataTy ty=BaseDFPTData::MutDataFlow)
Constructor.
BasePTData::PTDataTy PTDataTy
virtual bool hasDFOutSet(LocID loc, const Key &var) const override
DiffPTData implemented with points-to sets which are updated continuously.
virtual bool unionPts(const Key &dstKey, const Key &srcKey) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
static bool classof(const MutableDiffPTData< Key, KeySet, Data, DataSet > *)
virtual void updatePropaPtsMap(Key &src, Key &dst) override
MutablePTData< Key, KeySet, Data, DataSet > mutPTData
Backing to implement the basic PTData methods. This allows us to avoid multiple-inheritance.
virtual void clearPropaPts(Key &var) override
Clear propagated points-to set of var.
~MutableDiffPTData() override=default
DataSet & getPropaPts(Key &var)
Get propagated points to.
PTData< Key, KeySet, Data, DataSet > BasePTData
MutablePTData< Key, KeySet, Data, DataSet >::PtsMap PtsMap
virtual void clearPts(const Key &var, const Data &element) override
Clears element from the points-to set of var.
void clear() override
Clears all points-to sets as if nothing is stored.
virtual bool addPts(const Key &dstKey, const Data &element) override
Adds element to the points-to set associated with var.
virtual bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
virtual void remapAllPts(void) override
Remaps all points-to sets to use the current mapping.
virtual const PtsMap & getPtsMap() const
virtual const DataSet & getDiffPts(Key &var) override
Get diff points to.
virtual void clearFullPts(const Key &var) override
Fully clears the points-to set of var.
BasePTData::PTDataTy PTDataTy
PtsMap diffPtsMap
Diff points-to to be propagated.
DiffPTData< Key, KeySet, Data, DataSet > BaseDiffPTData
virtual const DataSet & getPts(const Key &var) override
Get points-to set of var.
virtual bool computeDiffPts(Key &var, const DataSet &all) override
PtsMap propaPtsMap
Points-to already propagated.
virtual const KeySet & getRevPts(const Data &datum) override
Get reverse points-to set of a datum.
virtual Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
virtual void dumpPTData() override
Dump stored keys and points-to sets.
MutableDiffPTData(bool reversePT=true, PTDataTy ty=PTDataTy::Diff)
Constructor.
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
Incremental version of the mutable data-flow points-to data structure.
PTData< Key, KeySet, Data, DataSet > BasePTData
DataSet::iterator DataIter
virtual bool updateAllDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc::dstVar], OUT[srcLoc:srcVar]. There is no flag check, unlike the above.
void setVarDFInSetUpdated(LocID loc, const Key &var)
Handle address-taken variables whose IN pts changed.
virtual bool updateAllDFOutFromIn(LocID loc, const Key &singleton, bool strongUpdates) override
For each variable var in IN at loc, do updateDFOutFromIn(loc, var, loc, var).
DFPTData< Key, KeySet, Data, DataSet > BaseDFPTData
bool varHasNewDFOutPts(LocID loc, const Key &var)
Return TRUE if var has new pts in loc's OUT set.
MutableDFPTData< Key, KeySet, Data, DataSet > BaseMutDFPTData
BasePTData::PTDataTy PTDataTy
Map< LocID, DataSet > UpdatedVarMap
for propagating only newly added variable in IN/OUT set
BaseDFPTData::LocID LocID
virtual bool updateDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
virtual bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar) override
Update points-to set of top-level pointers with IN[srcLoc:srcVar].
void setVarDFOutSetUpdated(LocID loc, const Key &var)
Handle address-taken variables whose OUT pts changed.
static bool classof(const MutableIncDFPTData< Key, KeySet, Data, DataSet > *)
UpdatedVarMap::iterator UpdatedVarMapIter
void removeVarFromDFInUpdatedSet(LocID loc, const Key &var)
Remove var from loc's IN updated set.
MutablePTData< Key, KeySet, Data, DataSet > BaseMutPTData
MutableIncDFPTData(bool reversePT=true, PTDataTy ty=BasePTData::MutIncDataFlow)
Constructor.
virtual bool updateDFOutFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (OUT[dstLoc:dstVar], IN[srcLoc:srcVar]).
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
virtual bool updateATVPts(const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Update address-taken variables OUT[dstLoc:dstVar] with points-to of top-level pointers.
void removeVarFromDFOutUpdatedSet(LocID loc, const Key &var)
Remove var from loc's OUT updated set.
virtual void clearAllDFOutUpdatedVar(LocID loc) override
virtual bool updateDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc:dstVar], OUT[srcLoc:srcVar]).
const DataSet & getDFOutUpdatedVar(LocID loc)
Get all var which have new pts information in loc's OUT set.
virtual bool updateAllDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc::dstVar], IN[srcLoc:srcVar]. There is no flag check, unlike the above.
const DataSet & getDFInUpdatedVar(LocID loc)
Get all var which have new pts information in loc's IN set.
bool varHasNewDFInPts(LocID loc, const Key &var)
Return TRUE if var has new pts in loc's IN set.
UpdatedVarMap::const_iterator UpdatedVarconstIter
PTData implemented using points-to sets which are created once and updated continuously.
virtual bool unionPts(const Key &dstKey, const Key &srcKey) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
virtual bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
virtual void dumpPTData() override
Dump stored keys and points-to sets.
virtual const KeySet & getRevPts(const Data &datum) override
Get reverse points-to set of a datum.
virtual void remapAllPts(void) override
Remaps all points-to sets to use the current mapping.
virtual void clearFullPts(const Key &var) override
Fully clears the points-to set of var.
void addSingleRevPts(KeySet &revData, const Key &tgr)
MutablePTData(bool reversePT=true, PTDataTy ty=PTDataTy::MutBase)
Constructor.
void clearSingleRevPts(KeySet &revSet, const Key &k)
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
static bool classof(const MutablePTData< Key, KeySet, Data, DataSet > *)
virtual void clearPts(const Key &var, const Data &element) override
Clears element from the points-to set of var.
Map< Data, KeySet > RevPtsMap
void clearRevPts(const DataSet &pts, const Key &k)
virtual const PtsMap & getPtsMap() const
Return Points-to map.
bool addPts(DataSet &d, const Data &e)
BasePTData::PTDataTy PTDataTy
virtual bool addPts(const Key &dstKey, const Data &element) override
Adds element to the points-to set associated with var.
PTData< Key, KeySet, Data, DataSet > BasePTData
bool unionPts(DataSet &dstDataSet, const DataSet &srcDataSet)
virtual const DataSet & getPts(const Key &var) override
Get points-to set of var.
virtual void clear() override
Clears all points-to sets as if nothing is stored.
PtsMap::iterator PtsMapIter
virtual Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
void addRevPts(const DataSet &ptsData, const Key &tgr)
Map< Key, DataSet > PtsMap
DataSet::iterator iterator
PtsMap::const_iterator PtsMapConstIter
virtual void dumpPts(const PtsMap &ptsSet, OutStream &O=SVFUtil::outs()) const
virtual bool addPts(const Key &k, const Data &element) override
Adds element to the points-to set associated with var.
MutablePTData< Key, KeySet, Data, DataSet > tlPTData
PTData for Keys (top-level pointers, generally).
virtual void clearPts(const VersionedKey &vk, const Data &element) override
PTData< Key, KeySet, Data, DataSet > BasePTData
MutablePTData< VersionedKey, VersionedKeySet, Data, DataSet > atPTData
PTData for VersionedKeys (address-taken objects, generally).
virtual bool unionPts(const VersionedKey &dstVar, const Key &srcVar) override
virtual bool unionPts(const VersionedKey &dstVar, const VersionedKey &srcVar) override
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
static bool classof(const MutableVersionedPTData< Key, KeySet, Data, DataSet, VersionedKey, VersionedKeySet > *)
virtual Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
virtual void remapAllPts(void) override
Remaps all points-to sets to use the current mapping.
virtual void dumpPTData() override
Dump stored keys and points-to sets.
virtual const KeySet & getRevPts(const Data &datum) override
Get reverse points-to set of a datum.
virtual bool unionPts(const Key &dstVar, const VersionedKey &srcVar) override
virtual void clearFullPts(const Key &k) override
Fully clears the points-to set of var.
VersionedPTData< Key, KeySet, Data, DataSet, VersionedKey, VersionedKeySet > BaseVersionedPTData
virtual bool unionPts(const Key &dstVar, const DataSet &srcDataSet) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
virtual bool unionPts(const VersionedKey &dstVar, const DataSet &srcDataSet) override
virtual void clearFullPts(const VersionedKey &vk) override
virtual const DataSet & getPts(const Key &vk) override
Get points-to set of var.
virtual void clearPts(const Key &k, const Data &element) override
Clears element from the points-to set of var.
virtual void clear() override
Clears all points-to sets as if nothing is stored.
MutableVersionedPTData(bool reversePT=true, PTDataTy ty=PTDataTy::MutVersioned)
virtual bool unionPts(const Key &dstVar, const Key &srcVar) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
virtual bool addPts(const VersionedKey &vk, const Data &element) override
BasePTData::PTDataTy PTDataTy
virtual const VersionedKeySet & getVersionedKeyRevPts(const Data &datum) override
virtual const DataSet & getPts(const VersionedKey &vk) override
bool rev
Whether we maintain reverse points-to sets or not.
PTDataTy
Types of a points-to data structures.
PTDataTy getPTDTY() const
Get the type of points-to data structure that this is.
iterator end() const
void set(unsigned Idx)
iterator begin() const
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition: SVFUtil.cpp:147
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
void removeKey(const Key &key, KeySet &keySet)
Removes an element from a Set/CondSet (or anything implementing ::erase).
Definition: SVFUtil.h:252
void insertKey(const Key &key, KeySet &keySet)
Inserts an element into a Set/CondSet (with ::insert).
Definition: SVFUtil.h:239
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