Static Value-Flow Analysis
Loading...
Searching...
No Matches
PersistentPointsToDS.h
Go to the documentation of this file.
1
3
4/*
5 * PersistentPointsToDS.h
6 *
7 * Authors: Mohamad Barbar
8 *
9 * The implementation is based on
10 * Mohamad Barbar and Yulei Sui. Hash Consed Points-To Sets.
11 * 28th Static Analysis Symposium (SAS'21)
12 */
13
14#ifndef PERSISTENT_POINTSTO_H_
15#define PERSISTENT_POINTSTO_H_
16
19#include "Util/SVFUtil.h"
20
21namespace SVF
22{
23
24template <typename Key, typename KeySet, typename Data, typename DataSet>
25class PersistentDFPTData;
26template <typename Key, typename KeySet, typename Data, typename DataSet>
27class PersistentIncDFPTData;
28template <typename Key, typename KeySet, typename Data, typename DataSet, typename VersionedKey, typename VersionedKeySet>
29class PersistentVersionedPTData;
30
32template <typename Key, typename KeySet, typename Data, typename DataSet>
33class PersistentPTData : public PTData<Key, KeySet, Data, DataSet>
34{
35 template <typename K, typename KS, typename D, typename DS, typename VK, typename VKS>
37 friend class PersistentDFPTData<Key, KeySet, Data, DataSet>;
38 friend class PersistentIncDFPTData<Key, KeySet, Data, DataSet>;
39public:
42
45
49
50 ~PersistentPTData() override = default;
51
52 inline void clear() override
53 {
54 ptsMap.clear();
55 revPtsMap.clear();
56 }
57
58 inline const DataSet& getPts(const Key &var) override
59 {
60 PointsToID id = ptsMap[var];
61 return ptCache.getActualPts(id);
62 }
63
64 inline const KeySet& getRevPts(const Data &data) override
65 {
66 assert(this->rev && "PersistentPTData::getRevPts: constructed without reverse PT support!");
67 return revPtsMap[data];
68 }
69
70 inline bool addPts(const Key &dstKey, const Data &element) override
71 {
72 DataSet srcPts;
73 srcPts.set(element);
76 }
77
78 inline bool unionPts(const Key& dstKey, const Key& srcKey) override
79 {
82 }
83
84 inline bool unionPts(const Key& dstKey, const DataSet& srcData) override
85 {
88 }
89
90 inline void dumpPTData() override
91 {
92 }
93
107
113
114 void remapAllPts() override
115 {
117 }
118
120 {
122 if (liveOnly)
123 {
124 for (const typename KeyToIDMap::value_type &ki : ptsMap)
125 {
126 ++allPts[ptCache.getActualPts(ki.second)];
127 }
128 }
129 else
130 {
132 }
133
134 return allPts;
135 }
136
140 {
141 return true;
142 }
143
145 {
146 return ptd->getPTDTY() == PTDataTy::PersBase;
147 }
149
150private:
154 {
157
158 bool changed = newDstId != dstId;
159 if (changed)
160 {
162
163 // Reverse points-to only needs to be handled when dst's
164 // points-to set has changed (i.e., do it the first time only).
165 if (this->rev)
166 {
167 const DataSet &srcPts = ptCache.getActualPts(srcId);
168 for (const Data &d : srcPts) SVFUtil::insertKey(dstKey, revPtsMap[d]);
169 }
170 }
171
172 return changed;
173 }
174
175 inline void clearSingleRevPts(KeySet &revSet, const Key &k)
176 {
177 if (this->rev)
178 {
180 }
181 }
182
183 inline void clearRevPts(const DataSet &pts, const Key &k)
184 {
185 if (this->rev)
186 {
187 for (const Data &d : pts) clearSingleRevPts(revPtsMap[d], k);
188 }
189 }
190
191protected:
195};
196
198template <typename Key, typename KeySet, typename Data, typename DataSet>
199class PersistentDiffPTData : public DiffPTData<Key, KeySet, Data, DataSet>
200{
201public:
206
209
213
214 ~PersistentDiffPTData() override = default;
215
216 void clear() override
217 {
218 persPTData.clear();
219 diffPtsMap.clear();
220 propaPtsMap.clear();
221 }
222
223 inline const DataSet &getPts(const Key& var) override
224 {
225 return persPTData.getPts(var);
226 }
227
228 inline const KeySet& getRevPts(const Data &data) override
229 {
230 assert(this->rev && "PersistentDiffPTData::getRevPts: constructed without reverse PT support!");
231 return persPTData.getRevPts(data);
232 }
233
234 inline bool addPts(const Key &dstKey, const Data &element) override
235 {
236 return persPTData.addPts(dstKey, element);
237 }
238
239 inline bool unionPts(const Key& dstKey, const Key& srcKey) override
240 {
241 return persPTData.unionPts(dstKey, srcKey);
242 }
243
244 inline bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override
245 {
246 return persPTData.unionPts(dstKey, srcDataSet);
247 }
248
249 void clearPts(const Key &var, const Data &element) override
250 {
251 return persPTData.clearPts(var, element);
252 }
253
254 void clearFullPts(const Key &var) override
255 {
256 return persPTData.clearFullPts(var);
257 }
258
259 void remapAllPts() override
260 {
262 }
263
264 inline void dumpPTData() override
265 {
266 // TODO.
267 }
268
269 inline const DataSet &getDiffPts(Key &var) override
270 {
272 return ptCache.getActualPts(id);
273 }
274
275 inline bool computeDiffPts(Key &var, const DataSet &all) override
276 {
279 // Diff is made up of the entire points-to set minus what has been propagated.
282
283 // We've now propagated the entire thing.
285
286 // Whether diff is empty or not; just need to check against the ID since it
287 // is the only empty set.
288 return diffId != ptCache.emptyPointsToId();
289 }
290
291 inline void updatePropaPtsMap(Key &src, Key &dst) override
292 {
296 }
297
298 inline void clearPropaPts(Key &var) override
299 {
301 }
302
304 {
305 return persPTData.getAllPts(liveOnly);
306 }
307
311 {
312 return true;
313 }
314
316 {
317 return ptd->getPTDTY() == PTDataTy::PersDiff;
318 }
320
321private:
329};
330
332template <typename Key, typename KeySet, typename Data, typename DataSet>
333class PersistentDFPTData : public DFPTData<Key, KeySet, Data, DataSet>
334{
335public:
340
341 typedef typename BaseDFPTData::LocID LocID;
344
347
348 ~PersistentDFPTData() override = default;
349
350 inline void clear() override
351 {
352 dfInPtsMap.clear();
353 dfOutPtsMap.clear();
354 persPTData.clear();
355 }
356
357 inline const DataSet &getPts(const Key& var) override
358 {
359 return persPTData.getPts(var);
360 }
361
362 inline const KeySet& getRevPts(const Data&) override
363 {
364 assert(false && "PersistentDFPTData::getRevPts: not supported yet!");
365 abort();
366 }
367
368 inline bool unionPts(const Key& dstKey, const Key& srcKey) override
369 {
370 return persPTData.unionPts(dstKey, srcKey);
371 }
372
373 inline bool unionPts(const Key& dstKey, const DataSet &srcDataSet) override
374 {
375 return persPTData.unionPts(dstKey, srcDataSet);
376 }
377
378 inline bool addPts(const Key &dstKey, const Data &element) override
379 {
380 return persPTData.addPts(dstKey, element);
381 }
382
383 void clearPts(const Key& var, const Data &element) override
384 {
385 persPTData.clearPts(var, element);
386 }
387
388 void clearFullPts(const Key& var) override
389 {
390 persPTData.clearFullPts(var);
391 }
392
393 void remapAllPts() override
394 {
396 }
397
398 inline void dumpPTData() override
399 {
400 persPTData.dumpPTData();
401 }
402
403 bool hasDFInSet(LocID loc) const override
404 {
405 return dfInPtsMap.find(loc) != dfInPtsMap.end();
406 }
407
408 bool hasDFOutSet(LocID loc) const override
409 {
410 return dfOutPtsMap.find(loc) != dfOutPtsMap.end();
411 }
412
413 bool hasDFInSet(LocID loc, const Key& var) const override
414 {
415 typename DFKeyToIDMap::const_iterator foundInKeyToId = dfInPtsMap.find(loc);
416 if (foundInKeyToId == dfInPtsMap.end()) return false;
417 const KeyToIDMap &inKeyToId = foundInKeyToId->second;
418 return (inKeyToId.find(var) != inKeyToId.end());
419 }
420
421 bool hasDFOutSet(LocID loc, const Key& var) const override
422 {
423 typename DFKeyToIDMap::const_iterator foundOutKeyToId = dfOutPtsMap.find(loc);
424 if (foundOutKeyToId == dfOutPtsMap.end()) return false;
425 const KeyToIDMap &outKeyToId = foundOutKeyToId->second;
426 return (outKeyToId.find(var) != outKeyToId.end());
427 }
428
429 const DataSet &getDFInPtsSet(LocID loc, const Key& var) override
430 {
432 return ptCache.getActualPts(id);
433 }
434
435 const DataSet &getDFOutPtsSet(LocID loc, const Key& var) override
436 {
438 return ptCache.getActualPts(id);
439 }
440
445
447 {
449 }
450
455
457 {
459 }
460
465
467 {
468 bool changed = false;
469 if (this->hasDFInSet(loc))
470 {
472 for (const typename KeyToIDMap::value_type &ki : inKeyToId)
473 {
474 const Key var = ki.first;
476 if (strongUpdates && var == singleton) continue;
477
478 if (updateDFOutFromIn(loc, var, loc, var)) changed = true;
479 }
480 }
481
482 return changed;
483 }
484
486 {
487 }
488
490 bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar) override
491 {
493 }
494
495 bool updateATVPts(const Key& srcVar, LocID dstLoc, const Key& dstVar) override
496 {
498 }
499
501 {
503 for (const typename DFKeyToIDMap::value_type &lki : dfInPtsMap)
504 {
505 for (const typename KeyToIDMap::value_type &ki : lki.second)
506 {
507 ++allPts[ptCache.getActualPts(ki.second)];
508 }
509 }
510
511 for (const typename DFKeyToIDMap::value_type &lki : dfOutPtsMap)
512 {
513 for (const typename KeyToIDMap::value_type &ki : lki.second)
514 {
515 ++allPts[ptCache.getActualPts(ki.second)];
516 }
517 }
518
519 if (!liveOnly)
520 {
521 // Subtract 1 from each counted points-to set because the live points-to
522 // sets have already been inserted and accounted for how often they occur.
523 // They will each occur one more time in the cache.
524 // In essence, we want the ptCache.getAllPts() to just add the unused, non-GC'd
525 // points-to sets to allPts.
526 for (typename Map<DataSet, unsigned>::value_type pto : allPts) pto.second -= 1;
527 SVFUtil::mergePtsOccMaps<DataSet>(allPts, ptCache.getAllPts());
528 }
529
530 return allPts;
531 }
532
536 {
537 return true;
538 }
539
541 {
542 return ptd->getPTDTY() == PTDataTy::PersDataFlow
543 || ptd->getPTDTY() == PTDataTy::PersIncDataFlow;
544 }
546
547protected:
549 {
550 PointsToID oldDst = dst;
551 dst = ptCache.unionPts(dst, src);
552 return oldDst != dst;
553 }
554
556 {
557 return dfInPtsMap[loc][var];
558 }
559
561 {
562 return dfOutPtsMap[loc][var];
563 }
564
565protected:
567
570
575};
576
578template <typename Key, typename KeySet, typename Data, typename DataSet>
579class PersistentIncDFPTData : public PersistentDFPTData<Key, KeySet, Data, DataSet>
580{
581public:
587
588 typedef typename BaseDFPTData::LocID LocID;
590
591public:
595
596 ~PersistentIncDFPTData() override = default;
597
598 inline bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
599 {
601 && this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar)))
602 {
604 return true;
605 }
606
607 return false;
608 }
609
610 inline bool updateDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
611 {
613 && this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFOutPtIdRef(srcLoc, srcVar)))
614 {
616 return true;
617 }
618
619 return false;
620 }
621
622 inline bool updateDFOutFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
623 {
625 {
627 if (this->unionPtsThroughIds(this->getDFOutPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar)))
628 {
630 return true;
631 }
632 }
633
634 return false;
635 }
636
637 inline bool updateAllDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
638 {
639 if (this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFOutPtIdRef(srcLoc, srcVar)))
640 {
642 return true;
643 }
644
645 return false;
646 }
647
648 inline bool updateAllDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
649 {
650 if (this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar)))
651 {
653 return true;
654 }
655
656 return false;
657 }
658
659 inline bool updateAllDFOutFromIn(LocID loc, const Key& singleton, bool strongUpdates) override
660 {
661 bool changed = false;
662 if (this->hasDFInSet(loc))
663 {
666 for (const Key &var : vars)
667 {
669 if (strongUpdates && var == singleton) continue;
670 if (updateDFOutFromIn(loc, var, loc, var)) changed = true;
671 }
672 }
673
674 return changed;
675 }
676
677 inline bool updateTLVPts(LocID srcLoc, const Key& srcVar, const Key& dstVar) override
678 {
680 {
682 return this->unionPtsThroughIds(this->persPTData.ptsMap[dstVar], this->getDFInPtIdRef(srcLoc, srcVar));
683 }
684
685 return false;
686 }
687
688 inline bool updateATVPts(const Key& srcVar, LocID dstLoc, const Key& dstVar) override
689 {
690 if (this->unionPtsThroughIds(this->getDFOutPtIdRef(dstLoc, dstVar), this->persPTData.ptsMap[srcVar]))
691 {
693 return true;
694 }
695
696 return false;
697 }
698
699 inline void clearAllDFOutUpdatedVar(LocID loc) override
700 {
701 if (this->hasDFOutSet(loc))
702 {
704 for (const Key &var : vars)
705 {
707 }
708 }
709 }
710
711 inline void clear() override
712 {
713 outUpdatedVarMap.clear();
714 inUpdatedVarMap.clear();
716 }
717
721 {
722 return true;
723 }
724
726 {
727 return ptd->getPTDTY() == BasePTData::PersIncDataFlow;
728 }
730
731private:
732
734
735
740
743 {
744 typename UpdatedVarMap::iterator it = inUpdatedVarMap.find(loc);
745 if (it != inUpdatedVarMap.end()) it->second.erase(var);
746 }
747
749 inline bool varHasNewDFInPts(LocID loc, const Key& var)
750 {
751 typename UpdatedVarMap::iterator it = inUpdatedVarMap.find(loc);
752 if (it != inUpdatedVarMap.end()) return it->second.find(var) != it->second.end();
753 return false;
754 }
755
758 {
759 return inUpdatedVarMap[loc];
760 }
762
770
773 {
774 typename UpdatedVarMap::iterator it = outUpdatedVarMap.find(loc);
775 if (it != outUpdatedVarMap.end()) it->second.erase(var);
776 }
777
779 inline bool varHasNewDFOutPts(LocID loc, const Key& var)
780 {
781 typename UpdatedVarMap::iterator it = outUpdatedVarMap.find(loc);
782 if (it != outUpdatedVarMap.end()) return it->second.find(var) != it->second.end();
783 return false;
784 }
785
788 {
789 return outUpdatedVarMap[loc];
790 }
792
793
794private:
797};
798
803template <typename Key, typename KeySet, typename Data, typename DataSet, typename VersionedKey, typename VersionedKeySet>
804class PersistentVersionedPTData : public VersionedPTData<Key, KeySet, Data, DataSet, VersionedKey, VersionedKeySet>
805{
806public:
810
813
816
817 ~PersistentVersionedPTData() override = default;
818
819 inline void clear() override
820 {
821 tlPTData.clear();
822 atPTData.clear();
823 }
824
825 const DataSet &getPts(const Key& vk) override
826 {
827 return tlPTData.getPts(vk);
828 }
829 const DataSet &getPts(const VersionedKey& vk) override
830 {
831 return atPTData.getPts(vk);
832 }
833
834 const KeySet& getRevPts(const Data &data) override
835 {
836 assert(this->rev && "PersistentVersionedPTData::getRevPts: constructed without reverse PT support!");
837 return tlPTData.getRevPts(data);
838 }
839 const VersionedKeySet& getVersionedKeyRevPts(const Data &data) override
840 {
841 assert(this->rev && "PersistentVersionedPTData::getVersionedKeyRevPts: constructed without reverse PT support!");
842 return atPTData.getRevPts(data);
843 }
844
845 bool addPts(const Key& k, const Data &element) override
846 {
847 return tlPTData.addPts(k, element);
848 }
849 bool addPts(const VersionedKey& vk, const Data &element) override
850 {
851 return atPTData.addPts(vk, element);
852 }
853
854 bool unionPts(const Key& dstVar, const Key& srcVar) override
855 {
856 return tlPTData.unionPts(dstVar, srcVar);
857 }
858 bool unionPts(const VersionedKey& dstVar, const VersionedKey& srcVar) override
859 {
861 }
862 bool unionPts(const VersionedKey& dstVar, const Key& srcVar) override
863 {
865 }
866 bool unionPts(const Key& dstVar, const VersionedKey& srcVar) override
867 {
868 return tlPTData.unionPtsFromId(dstVar, atPTData.ptsMap[srcVar]);
869 }
870 bool unionPts(const Key &dstVar, const DataSet &srcDataSet) override
871 {
872 return tlPTData.unionPts(dstVar, srcDataSet);
873 }
874 bool unionPts(const VersionedKey &dstVar, const DataSet &srcDataSet) override
875 {
877 }
878
879 void clearPts(const Key& k, const Data &element) override
880 {
881 tlPTData.clearPts(k, element);
882 }
883 void clearPts(const VersionedKey& vk, const Data &element) override
884 {
886 }
887
888 void clearFullPts(const Key& k) override
889 {
890 tlPTData.clearFullPts(k);
891 }
892 void clearFullPts(const VersionedKey& vk) override
893 {
895 }
896
897 void remapAllPts() override
898 {
899 // tlPTData and atPTData use the same cache.
900 tlPTData.remapAllPts();
901 }
902
904 {
905 // Explicitly pass in true because if we call it with false,
906 // we will double up on the cache, since it is shared with atPTData.
907 // if liveOnly == false, we will handle it in the if below.
908 Map<DataSet, unsigned> allPts = tlPTData.getAllPts(true);
909 SVFUtil::mergePtsOccMaps<DataSet>(allPts, atPTData.getAllPts(true));
910
911 if (!liveOnly)
912 {
913 // Subtract 1 from each counted points-to set because the live points-to
914 // sets have already been inserted and accounted for how often they occur.
915 // They will each occur one more time in the cache.
916 // In essence, we want the ptCache.getAllPts() to just add the unused, non-GC'd
917 // points-to sets to allPts.
918 for (typename Map<DataSet, unsigned>::value_type &pto : allPts) pto.second -= 1;
919 SVFUtil::mergePtsOccMaps<DataSet>(allPts, tlPTData.ptCache.getAllPts());
920 }
921
922 return allPts;
923 }
924
925 inline void dumpPTData() override
926 {
927 SVFUtil::outs() << "== Top-level points-to information\n";
928 tlPTData.dumpPTData();
929 SVFUtil::outs() << "== Address-taken points-to information\n";
931 }
932
939
941 {
942 return ptd->getPTDTY() == PTDataTy::PersVersioned;
943 }
945
946private:
951};
952
953} // End namespace SVF
954#endif // PERSISTENT_POINTSTO_H_
bool rev
Whether we maintain reverse points-to sets or not.
PTDataTy
Types of a points-to data structures.
DFPTData backed by a PersistentPointsToCache.
void clearFullPts(const Key &var) override
Fully clears the points-to set of var.
Map< LocID, KeyToIDMap > DFKeyToIDMap
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.
bool hasDFInSet(LocID loc) const override
bool updateDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
bool updateDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc:dstVar], OUT[srcLoc:srcVar]).
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.
bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
bool unionPtsThroughIds(PointsToID &dst, PointsToID &src)
bool unionPts(const Key &dstKey, const Key &srcKey) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
PersistentPTData< Key, KeySet, Data, DataSet > persPTData
PTData for top-level pointers. We will also use its cache for address-taken pointers.
bool hasDFOutSet(LocID loc, const Key &var) const override
PTData< Key, KeySet, Data, DataSet > BasePTData
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
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.
Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
void clearPts(const Key &var, const Data &element) override
Clears element from the points-to set of var.
~PersistentDFPTData() override=default
void clearAllDFOutUpdatedVar(LocID) override
DFKeyToIDMap dfInPtsMap
Address-taken points-to sets in IN-sets.
PersistentDFPTData(PersistentPointsToCache< DataSet > &cache, bool reversePT=true, PTDataTy ty=PTDataTy::PersDataFlow)
bool addPts(const Key &dstKey, const Data &element) override
Adds element to the points-to set associated with var.
bool updateAllDFOutFromIn(LocID loc, const Key &singleton, bool strongUpdates) override
For each variable var in IN at loc, do updateDFOutFromIn(loc, var, loc, var).
bool updateDFOutFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (OUT[dstLoc:dstVar], IN[srcLoc:srcVar]).
void clear() override
Clears all points-to sets as if nothing is stored.
void dumpPTData() override
Dump stored keys and points-to sets.
BasePTData::PTDataTy PTDataTy
const DataSet & getDFInPtsSet(LocID loc, const Key &var) override
const KeySet & getRevPts(const Data &) override
Get reverse points-to set of a datum.
static bool classof(const PersistentDFPTData< Key, KeySet, Data, DataSet > *)
bool hasDFInSet(LocID loc, const Key &var) const override
DFKeyToIDMap dfOutPtsMap
Address-taken points-to sets in OUT-sets.
PointsToID & getDFInPtIdRef(LocID loc, const Key &var)
bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar) override
Update points-to set of top-level pointers with IN[srcLoc:srcVar].
PointsToID & getDFOutPtIdRef(LocID loc, const Key &var)
const DataSet & getDFOutPtsSet(LocID loc, const Key &var) override
BasePersPTData::KeyToIDMap KeyToIDMap
void remapAllPts() override
Remaps all points-to sets to use the current mapping.
PersistentPointsToCache< DataSet > & ptCache
bool hasDFOutSet(LocID loc) const override
DFPTData< Key, KeySet, Data, DataSet > BaseDFPTData
const DataSet & getPts(const Key &var) override
Get points-to set of var.
PersistentPTData< Key, KeySet, Data, DataSet > BasePersPTData
DiffPTData implemented with a persistent points-to backing.
bool computeDiffPts(Key &var, const DataSet &all) override
PersistentPTData< Key, KeySet, Data, DataSet > persPTData
Backing to implement basic PTData methods. Allows us to avoid multiple inheritance.
PersistentDiffPTData(PersistentPointsToCache< DataSet > &cache, bool reversePT=true, PTDataTy ty=PTDataTy::PersDiff)
Constructor.
Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
~PersistentDiffPTData() override=default
void dumpPTData() override
Dump stored keys and points-to sets.
DiffPTData< Key, KeySet, Data, DataSet > BaseDiffPTData
PersistentPointsToCache< DataSet > & ptCache
void clearPts(const Key &var, const Data &element) override
Clears element from the points-to set of var.
const DataSet & getPts(const Key &var) override
Get points-to set of var.
BasePersPTData::KeyToIDMap KeyToIDMap
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
void clearPropaPts(Key &var) override
Clear propagated points-to set of var.
const DataSet & getDiffPts(Key &var) override
Get diff points to.
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
PersistentPTData< Key, KeySet, Data, DataSet > BasePersPTData
void updatePropaPtsMap(Key &src, Key &dst) override
KeyToIDMap propaPtsMap
Points-to already propagated.
BasePersPTData::RevPtsMap RevPtsMap
void remapAllPts() override
Remaps all points-to sets to use the current mapping.
KeyToIDMap diffPtsMap
Diff points-to to be propagated.
const KeySet & getRevPts(const Data &data) override
Get reverse points-to set of a datum.
bool unionPts(const Key &dstKey, const Key &srcKey) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
void clear() override
Clears all points-to sets as if nothing is stored.
void clearFullPts(const Key &var) override
Fully clears the points-to set of var.
bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
static bool classof(const PersistentDiffPTData< Key, KeySet, Data, DataSet > *)
Incremental version of the persistent data-flow points-to data structure.
const KeySet & getDFOutUpdatedVar(LocID loc)
Get all variables which have new pts info in loc's OUT set.
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 setVarDFInSetUpdated(LocID loc, const Key &var)
Handle address-taken variables whose IN pts changed.
bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar) override
Update points-to set of top-level pointers with IN[srcLoc:srcVar].
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 PTData< Key, KeySet, Data, DataSet > *ptd)
PersistentIncDFPTData(PersistentPointsToCache< DataSet > &cache, bool reversePT=true, PTDataTy ty=BasePTData::PersIncDataFlow)
Constructor.
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.
bool varHasNewDFInPts(LocID loc, const Key &var)
Return TRUE if var has a new pts in loc's IN set.
bool updateDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
static bool classof(const PersistentIncDFPTData< Key, KeySet, Data, DataSet > *)
PTData< Key, KeySet, Data, DataSet > BasePTData
const KeySet & getDFInUpdatedVar(LocID loc)
Get all variables which have new pts information in loc's IN set.
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.
void setVarDFOutSetUpdated(LocID loc, const Key &var)
bool updateDFOutFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (OUT[dstLoc:dstVar], IN[srcLoc:srcVar]).
void clearAllDFOutUpdatedVar(LocID loc) override
Map< LocID, KeySet > UpdatedVarMap
PersistentDFPTData< Key, KeySet, Data, DataSet > BasePersDFPTData
PersistentPTData< Key, KeySet, Data, DataSet > BasePersPTData
void removeVarFromDFOutUpdatedSet(LocID loc, const Key &var)
Remove var from loc's OUT updated set.
void removeVarFromDFInUpdatedSet(LocID loc, const Key &var)
Remove var from loc's IN updated set.
void clear() override
Clears all points-to sets as if nothing is stored.
~PersistentIncDFPTData() override=default
bool varHasNewDFOutPts(LocID loc, const Key &var)
Return TRUE if var has a new pts in loc's OUT set.
DFPTData< Key, KeySet, Data, DataSet > BaseDFPTData
bool updateDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override
Union (IN[dstLoc:dstVar], OUT[srcLoc:srcVar]).
PTData backed by a PersistentPointsToCache.
const DataSet & getPts(const Key &var) override
Get points-to set of var.
bool unionPtsFromId(const Key &dstKey, PointsToID srcId)
PersistentPointsToCache< DataSet > & ptCache
static bool classof(const PersistentPTData< Key, KeySet, Data, DataSet > *)
void clearRevPts(const DataSet &pts, const Key &k)
void clearSingleRevPts(KeySet &revSet, const Key &k)
bool addPts(const Key &dstKey, const Data &element) override
Adds element to the points-to set associated with var.
void clear() override
Clears all points-to sets as if nothing is stored.
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
bool unionPts(const Key &dstKey, const Key &srcKey) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
PersistentPTData(PersistentPointsToCache< DataSet > &cache, bool reversePT=true, PTDataTy ty=PTDataTy::PersBase)
Constructor.
~PersistentPTData() override=default
BasePTData::PTDataTy PTDataTy
void remapAllPts() override
Remaps all points-to sets to use the current mapping.
PTData< Key, KeySet, Data, DataSet > BasePTData
void clearPts(const Key &var, const Data &element) override
Clears element from the points-to set of var.
void dumpPTData() override
Dump stored keys and points-to sets.
bool unionPts(const Key &dstKey, const DataSet &srcData) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
const KeySet & getRevPts(const Data &data) override
Get reverse points-to set of a datum.
Map< Key, PointsToID > KeyToIDMap
Map< Data, KeySet > RevPtsMap
void clearFullPts(const Key &var) override
Fully clears the points-to set of var.
PointsToID unionPts(PointsToID lhs, PointsToID rhs)
Unions lhs and rhs and returns their union's ID.
PointsToID intersectPts(PointsToID lhs, PointsToID rhs)
Intersects lhs and rhs (lhs AND rhs) and returns the intersection's ID.
Map< Data, unsigned > getAllPts(void)
const Data & getActualPts(PointsToID id) const
Returns the points-to set which id represents. id must be stored in the cache.
PointsToID complementPts(PointsToID lhs, PointsToID rhs)
Relatively complements lhs and rhs (lhs \ rhs) and returns it's ID.
void remapAllPts(void)
Remaps all points-to sets stored in the cache to the current mapping.
static PointsToID emptyPointsToId(void)
PointsToID emplacePts(const Data &pts)
void clearFullPts(const Key &k) override
Fully clears the points-to set of var.
bool unionPts(const Key &dstVar, const Key &srcVar) override
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
static bool classof(const PTData< Key, KeySet, Data, DataSet > *ptd)
PersistentPTData< VersionedKey, VersionedKeySet, Data, DataSet >::KeyToIDMap VersionedKeyToIDMap
static bool classof(const PersistentVersionedPTData< Key, KeySet, Data, DataSet, VersionedKey, VersionedKeySet > *)
PersistentPTData< Key, KeySet, Data, DataSet > tlPTData
PTData for Keys (top-level pointers, generally).
const DataSet & getPts(const VersionedKey &vk) override
PersistentPTData< Key, KeySet, Data, DataSet >::KeyToIDMap KeyToIDMap
bool addPts(const VersionedKey &vk, const Data &element) override
void clearPts(const Key &k, const Data &element) override
Clears element from the points-to set of var.
const KeySet & getRevPts(const Data &data) override
Get reverse points-to set of a datum.
void remapAllPts() override
Remaps all points-to sets to use the current mapping.
PersistentVersionedPTData(PersistentPointsToCache< DataSet > &cache, bool reversePT=true, PTDataTy ty=PTDataTy::PersVersioned)
bool unionPts(const VersionedKey &dstVar, const Key &srcVar) override
PersistentPTData< VersionedKey, VersionedKeySet, Data, DataSet > atPTData
PTData for VersionedKeys (address-taken objects, generally).
void clearPts(const VersionedKey &vk, const Data &element) override
~PersistentVersionedPTData() override=default
void clearFullPts(const VersionedKey &vk) override
const DataSet & getPts(const Key &vk) override
Get points-to set of var.
bool unionPts(const Key &dstVar, const DataSet &srcDataSet) override
Performs pts(dstVar) = pts(dstVar) U srcDataSet.
void dumpPTData() override
Dump stored keys and points-to sets.
bool unionPts(const VersionedKey &dstVar, const DataSet &srcDataSet) override
VersionedPTData< Key, KeySet, Data, DataSet, VersionedKey, VersionedKeySet > BaseVersionedPTData
bool addPts(const Key &k, const Data &element) override
Adds element to the points-to set associated with var.
PTData< Key, KeySet, Data, DataSet > BasePTData
bool unionPts(const Key &dstVar, const VersionedKey &srcVar) override
bool unionPts(const VersionedKey &dstVar, const VersionedKey &srcVar) override
const VersionedKeySet & getVersionedKeyRevPts(const Data &data) override
void clear() override
Clears all points-to sets as if nothing is stored.
Map< DataSet, unsigned > getAllPts(bool liveOnly) const override
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
void removeKey(const Key &key, KeySet &keySet)
Removes an element from a Set/CondSet (or anything implementing ::erase).
Definition SVFUtil.h:245
void insertKey(const Key &key, KeySet &keySet)
Inserts an element into a Set/CondSet (with ::insert).
Definition SVFUtil.h:232
for isBitcode
Definition BasicTypes.h:70
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned PointsToID
Definition GeneralType.h:83