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
20#include "Util/SVFUtil.h"
21
22namespace SVF
23{
24
25template <typename Key, typename KeySet, typename Data, typename DataSet>
26class PersistentDFPTData;
27template <typename Key, typename KeySet, typename Data, typename DataSet>
28class PersistentIncDFPTData;
29template <typename Key, typename KeySet, typename Data, typename DataSet, typename VersionedKey, typename VersionedKeySet>
30class PersistentVersionedPTData;
31
33template <typename Key, typename KeySet, typename Data, typename DataSet>
34class PersistentPTData : public PTData<Key, KeySet, Data, DataSet>
35{
36 template <typename K, typename KS, typename D, typename DS, typename VK, typename VKS>
38 friend class PersistentDFPTData<Key, KeySet, Data, DataSet>;
39 friend class PersistentIncDFPTData<Key, KeySet, Data, DataSet>;
40public:
43
46
50
51 ~PersistentPTData() override = default;
52
53 inline void clear() override
54 {
55 ptsMap.clear();
56 revPtsMap.clear();
57 }
58
59 inline const DataSet& getPts(const Key &var) override
60 {
61 PointsToID id = ptsMap[var];
62 return ptCache.getActualPts(id);
63 }
64
65 inline const KeySet& getRevPts(const Data &data) override
66 {
67 assert(this->rev && "PersistentPTData::getRevPts: constructed without reverse PT support!");
68 return revPtsMap[data];
69 }
70
71 inline bool addPts(const Key &dstKey, const Data &element) override
72 {
73 DataSet srcPts;
74 srcPts.set(element);
77 }
78
79 inline bool unionPts(const Key& dstKey, const Key& srcKey) override
80 {
83 }
84
85 inline bool unionPts(const Key& dstKey, const DataSet& srcData) override
86 {
89 }
90
91 inline void dumpPTData() override
92 {
93 }
94
108
114
115 void remapAllPts() override
116 {
118 }
119
121 {
123 if (liveOnly)
124 {
125 for (const typename KeyToIDMap::value_type &ki : ptsMap)
126 {
127 ++allPts[ptCache.getActualPts(ki.second)];
128 }
129 }
130 else
131 {
133 }
134
135 return allPts;
136 }
137
141 {
142 return true;
143 }
144
146 {
147 return ptd->getPTDTY() == PTDataTy::PersBase;
148 }
150
151private:
155 {
158
159 bool changed = newDstId != dstId;
160 if (changed)
161 {
163
164 // Reverse points-to only needs to be handled when dst's
165 // points-to set has changed (i.e., do it the first time only).
166 if (this->rev)
167 {
168 const DataSet &srcPts = ptCache.getActualPts(srcId);
169 for (const Data &d : srcPts) SVFUtil::insertKey(dstKey, revPtsMap[d]);
170 }
171 }
172
173 return changed;
174 }
175
176 inline void clearSingleRevPts(KeySet &revSet, const Key &k)
177 {
178 if (this->rev)
179 {
181 }
182 }
183
184 inline void clearRevPts(const DataSet &pts, const Key &k)
185 {
186 if (this->rev)
187 {
188 for (const Data &d : pts) clearSingleRevPts(revPtsMap[d], k);
189 }
190 }
191
192protected:
196};
197
199template <typename Key, typename KeySet, typename Data, typename DataSet>
200class PersistentDiffPTData : public DiffPTData<Key, KeySet, Data, DataSet>
201{
202public:
207
210
214
215 ~PersistentDiffPTData() override = default;
216
217 void clear() override
218 {
219 persPTData.clear();
220 diffPtsMap.clear();
221 propaPtsMap.clear();
222 }
223
224 inline const DataSet &getPts(const Key& var) override
225 {
226 return persPTData.getPts(var);
227 }
228
229 inline const KeySet& getRevPts(const Data &data) override
230 {
231 assert(this->rev && "PersistentDiffPTData::getRevPts: constructed without reverse PT support!");
232 return persPTData.getRevPts(data);
233 }
234
235 inline bool addPts(const Key &dstKey, const Data &element) override
236 {
237 return persPTData.addPts(dstKey, element);
238 }
239
240 inline bool unionPts(const Key& dstKey, const Key& srcKey) override
241 {
242 return persPTData.unionPts(dstKey, srcKey);
243 }
244
245 inline bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override
246 {
247 return persPTData.unionPts(dstKey, srcDataSet);
248 }
249
250 void clearPts(const Key &var, const Data &element) override
251 {
252 return persPTData.clearPts(var, element);
253 }
254
255 void clearFullPts(const Key &var) override
256 {
257 return persPTData.clearFullPts(var);
258 }
259
260 void remapAllPts() override
261 {
263 }
264
265 inline void dumpPTData() override
266 {
267 // TODO.
268 }
269
270 inline const DataSet &getDiffPts(Key &var) override
271 {
273 return ptCache.getActualPts(id);
274 }
275
276 inline bool computeDiffPts(Key &var, const DataSet &all) override
277 {
280 // Diff is made up of the entire points-to set minus what has been propagated.
283
284 // We've now propagated the entire thing.
286
287 // Whether diff is empty or not; just need to check against the ID since it
288 // is the only empty set.
289 return diffId != ptCache.emptyPointsToId();
290 }
291
292 inline void updatePropaPtsMap(Key &src, Key &dst) override
293 {
297 }
298
299 inline void clearPropaPts(Key &var) override
300 {
302 }
303
305 {
306 return persPTData.getAllPts(liveOnly);
307 }
308
312 {
313 return true;
314 }
315
317 {
318 return ptd->getPTDTY() == PTDataTy::PersDiff;
319 }
321
322private:
330};
331
333template <typename Key, typename KeySet, typename Data, typename DataSet>
334class PersistentDFPTData : public DFPTData<Key, KeySet, Data, DataSet>
335{
336public:
341
342 typedef typename BaseDFPTData::LocID LocID;
345
348
349 ~PersistentDFPTData() override = default;
350
351 inline void clear() override
352 {
353 dfInPtsMap.clear();
354 dfOutPtsMap.clear();
355 persPTData.clear();
356 }
357
358 inline const DataSet &getPts(const Key& var) override
359 {
360 return persPTData.getPts(var);
361 }
362
363 inline const KeySet& getRevPts(const Data&) override
364 {
365 assert(false && "PersistentDFPTData::getRevPts: not supported yet!");
366 abort();
367 }
368
369 inline bool unionPts(const Key& dstKey, const Key& srcKey) override
370 {
371 return persPTData.unionPts(dstKey, srcKey);
372 }
373
374 inline bool unionPts(const Key& dstKey, const DataSet &srcDataSet) override
375 {
376 return persPTData.unionPts(dstKey, srcDataSet);
377 }
378
379 inline bool addPts(const Key &dstKey, const Data &element) override
380 {
381 return persPTData.addPts(dstKey, element);
382 }
383
384 void clearPts(const Key& var, const Data &element) override
385 {
386 persPTData.clearPts(var, element);
387 }
388
389 void clearFullPts(const Key& var) override
390 {
391 persPTData.clearFullPts(var);
392 }
393
394 void remapAllPts() override
395 {
397 }
398
399 inline void dumpPTData() override
400 {
401 persPTData.dumpPTData();
402 }
403
404 bool hasDFInSet(LocID loc) const override
405 {
406 return dfInPtsMap.find(loc) != dfInPtsMap.end();
407 }
408
409 bool hasDFOutSet(LocID loc) const override
410 {
411 return dfOutPtsMap.find(loc) != dfOutPtsMap.end();
412 }
413
414 bool hasDFInSet(LocID loc, const Key& var) const override
415 {
416 typename DFKeyToIDMap::const_iterator foundInKeyToId = dfInPtsMap.find(loc);
417 if (foundInKeyToId == dfInPtsMap.end()) return false;
418 const KeyToIDMap &inKeyToId = foundInKeyToId->second;
419 return (inKeyToId.find(var) != inKeyToId.end());
420 }
421
422 bool hasDFOutSet(LocID loc, const Key& var) const override
423 {
424 typename DFKeyToIDMap::const_iterator foundOutKeyToId = dfOutPtsMap.find(loc);
425 if (foundOutKeyToId == dfOutPtsMap.end()) return false;
426 const KeyToIDMap &outKeyToId = foundOutKeyToId->second;
427 return (outKeyToId.find(var) != outKeyToId.end());
428 }
429
430 const DataSet &getDFInPtsSet(LocID loc, const Key& var) override
431 {
433 return ptCache.getActualPts(id);
434 }
435
436 const DataSet &getDFOutPtsSet(LocID loc, const Key& var) override
437 {
439 return ptCache.getActualPts(id);
440 }
441
446
448 {
450 }
451
456
458 {
460 }
461
466
468 {
469 bool changed = false;
470 if (this->hasDFInSet(loc))
471 {
473 for (const typename KeyToIDMap::value_type &ki : inKeyToId)
474 {
475 const Key var = ki.first;
477 if (strongUpdates && var == singleton) continue;
478
479 if (updateDFOutFromIn(loc, var, loc, var)) changed = true;
480 }
481 }
482
483 return changed;
484 }
485
487 {
488 }
489
491 bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar) override
492 {
494 }
495
496 bool updateATVPts(const Key& srcVar, LocID dstLoc, const Key& dstVar) override
497 {
499 }
500
502 {
504 for (const typename DFKeyToIDMap::value_type &lki : dfInPtsMap)
505 {
506 for (const typename KeyToIDMap::value_type &ki : lki.second)
507 {
508 ++allPts[ptCache.getActualPts(ki.second)];
509 }
510 }
511
512 for (const typename DFKeyToIDMap::value_type &lki : dfOutPtsMap)
513 {
514 for (const typename KeyToIDMap::value_type &ki : lki.second)
515 {
516 ++allPts[ptCache.getActualPts(ki.second)];
517 }
518 }
519
520 if (!liveOnly)
521 {
522 // Subtract 1 from each counted points-to set because the live points-to
523 // sets have already been inserted and accounted for how often they occur.
524 // They will each occur one more time in the cache.
525 // In essence, we want the ptCache.getAllPts() to just add the unused, non-GC'd
526 // points-to sets to allPts.
527 for (typename Map<DataSet, unsigned>::value_type pto : allPts) pto.second -= 1;
528 SVFUtil::mergePtsOccMaps<DataSet>(allPts, ptCache.getAllPts());
529 }
530
531 return allPts;
532 }
533
537 {
538 return true;
539 }
540
542 {
543 return ptd->getPTDTY() == PTDataTy::PersDataFlow
544 || ptd->getPTDTY() == PTDataTy::PersIncDataFlow;
545 }
547
548protected:
550 {
551 PointsToID oldDst = dst;
552 dst = ptCache.unionPts(dst, src);
553 return oldDst != dst;
554 }
555
557 {
558 return dfInPtsMap[loc][var];
559 }
560
562 {
563 return dfOutPtsMap[loc][var];
564 }
565
566protected:
568
571
576};
577
579template <typename Key, typename KeySet, typename Data, typename DataSet>
580class PersistentIncDFPTData : public PersistentDFPTData<Key, KeySet, Data, DataSet>
581{
582public:
588
589 typedef typename BaseDFPTData::LocID LocID;
591
592public:
596
597 ~PersistentIncDFPTData() override = default;
598
599 inline bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
600 {
602 && this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar)))
603 {
605 return true;
606 }
607
608 return false;
609 }
610
611 inline bool updateDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
612 {
614 && this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFOutPtIdRef(srcLoc, srcVar)))
615 {
617 return true;
618 }
619
620 return false;
621 }
622
623 inline bool updateDFOutFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
624 {
626 {
628 if (this->unionPtsThroughIds(this->getDFOutPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar)))
629 {
631 return true;
632 }
633 }
634
635 return false;
636 }
637
638 inline bool updateAllDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
639 {
640 if (this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFOutPtIdRef(srcLoc, srcVar)))
641 {
643 return true;
644 }
645
646 return false;
647 }
648
649 inline bool updateAllDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override
650 {
651 if (this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar)))
652 {
654 return true;
655 }
656
657 return false;
658 }
659
660 inline bool updateAllDFOutFromIn(LocID loc, const Key& singleton, bool strongUpdates) override
661 {
662 bool changed = false;
663 if (this->hasDFInSet(loc))
664 {
667 for (const Key &var : vars)
668 {
670 if (strongUpdates && var == singleton) continue;
671 if (updateDFOutFromIn(loc, var, loc, var)) changed = true;
672 }
673 }
674
675 return changed;
676 }
677
678 inline bool updateTLVPts(LocID srcLoc, const Key& srcVar, const Key& dstVar) override
679 {
681 {
683 return this->unionPtsThroughIds(this->persPTData.ptsMap[dstVar], this->getDFInPtIdRef(srcLoc, srcVar));
684 }
685
686 return false;
687 }
688
689 inline bool updateATVPts(const Key& srcVar, LocID dstLoc, const Key& dstVar) override
690 {
691 if (this->unionPtsThroughIds(this->getDFOutPtIdRef(dstLoc, dstVar), this->persPTData.ptsMap[srcVar]))
692 {
694 return true;
695 }
696
697 return false;
698 }
699
700 inline void clearAllDFOutUpdatedVar(LocID loc) override
701 {
702 if (this->hasDFOutSet(loc))
703 {
705 for (const Key &var : vars)
706 {
708 }
709 }
710 }
711
712 inline void clear() override
713 {
714 outUpdatedVarMap.clear();
715 inUpdatedVarMap.clear();
717 }
718
722 {
723 return true;
724 }
725
727 {
728 return ptd->getPTDTY() == BasePTData::PersIncDataFlow;
729 }
731
732private:
733
735
736
741
744 {
745 typename UpdatedVarMap::iterator it = inUpdatedVarMap.find(loc);
746 if (it != inUpdatedVarMap.end()) it->second.erase(var);
747 }
748
750 inline bool varHasNewDFInPts(LocID loc, const Key& var)
751 {
752 typename UpdatedVarMap::iterator it = inUpdatedVarMap.find(loc);
753 if (it != inUpdatedVarMap.end()) return it->second.find(var) != it->second.end();
754 return false;
755 }
756
759 {
760 return inUpdatedVarMap[loc];
761 }
763
771
774 {
775 typename UpdatedVarMap::iterator it = outUpdatedVarMap.find(loc);
776 if (it != outUpdatedVarMap.end()) it->second.erase(var);
777 }
778
780 inline bool varHasNewDFOutPts(LocID loc, const Key& var)
781 {
782 typename UpdatedVarMap::iterator it = outUpdatedVarMap.find(loc);
783 if (it != outUpdatedVarMap.end()) return it->second.find(var) != it->second.end();
784 return false;
785 }
786
789 {
790 return outUpdatedVarMap[loc];
791 }
793
794
795private:
798};
799
804template <typename Key, typename KeySet, typename Data, typename DataSet, typename VersionedKey, typename VersionedKeySet>
805class PersistentVersionedPTData : public VersionedPTData<Key, KeySet, Data, DataSet, VersionedKey, VersionedKeySet>
806{
807public:
811
814
817
818 ~PersistentVersionedPTData() override = default;
819
820 inline void clear() override
821 {
822 tlPTData.clear();
823 atPTData.clear();
824 }
825
826 const DataSet &getPts(const Key& vk) override
827 {
828 return tlPTData.getPts(vk);
829 }
830 const DataSet &getPts(const VersionedKey& vk) override
831 {
832 return atPTData.getPts(vk);
833 }
834
835 const KeySet& getRevPts(const Data &data) override
836 {
837 assert(this->rev && "PersistentVersionedPTData::getRevPts: constructed without reverse PT support!");
838 return tlPTData.getRevPts(data);
839 }
840 const VersionedKeySet& getVersionedKeyRevPts(const Data &data) override
841 {
842 assert(this->rev && "PersistentVersionedPTData::getVersionedKeyRevPts: constructed without reverse PT support!");
843 return atPTData.getRevPts(data);
844 }
845
846 bool addPts(const Key& k, const Data &element) override
847 {
848 return tlPTData.addPts(k, element);
849 }
850 bool addPts(const VersionedKey& vk, const Data &element) override
851 {
852 return atPTData.addPts(vk, element);
853 }
854
855 bool unionPts(const Key& dstVar, const Key& srcVar) override
856 {
857 return tlPTData.unionPts(dstVar, srcVar);
858 }
859 bool unionPts(const VersionedKey& dstVar, const VersionedKey& srcVar) override
860 {
862 }
863 bool unionPts(const VersionedKey& dstVar, const Key& srcVar) override
864 {
866 }
867 bool unionPts(const Key& dstVar, const VersionedKey& srcVar) override
868 {
869 return tlPTData.unionPtsFromId(dstVar, atPTData.ptsMap[srcVar]);
870 }
871 bool unionPts(const Key &dstVar, const DataSet &srcDataSet) override
872 {
873 return tlPTData.unionPts(dstVar, srcDataSet);
874 }
875 bool unionPts(const VersionedKey &dstVar, const DataSet &srcDataSet) override
876 {
878 }
879
880 void clearPts(const Key& k, const Data &element) override
881 {
882 tlPTData.clearPts(k, element);
883 }
884 void clearPts(const VersionedKey& vk, const Data &element) override
885 {
887 }
888
889 void clearFullPts(const Key& k) override
890 {
891 tlPTData.clearFullPts(k);
892 }
893 void clearFullPts(const VersionedKey& vk) override
894 {
896 }
897
898 void remapAllPts() override
899 {
900 // tlPTData and atPTData use the same cache.
901 tlPTData.remapAllPts();
902 }
903
905 {
906 // Explicitly pass in true because if we call it with false,
907 // we will double up on the cache, since it is shared with atPTData.
908 // if liveOnly == false, we will handle it in the if below.
909 Map<DataSet, unsigned> allPts = tlPTData.getAllPts(true);
910 SVFUtil::mergePtsOccMaps<DataSet>(allPts, atPTData.getAllPts(true));
911
912 if (!liveOnly)
913 {
914 // Subtract 1 from each counted points-to set because the live points-to
915 // sets have already been inserted and accounted for how often they occur.
916 // They will each occur one more time in the cache.
917 // In essence, we want the ptCache.getAllPts() to just add the unused, non-GC'd
918 // points-to sets to allPts.
919 for (typename Map<DataSet, unsigned>::value_type &pto : allPts) pto.second -= 1;
920 SVFUtil::mergePtsOccMaps<DataSet>(allPts, tlPTData.ptCache.getAllPts());
921 }
922
923 return allPts;
924 }
925
926 inline void dumpPTData() override
927 {
928 SVFUtil::outs() << "== Top-level points-to information\n";
929 tlPTData.dumpPTData();
930 SVFUtil::outs() << "== Address-taken points-to information\n";
932 }
933
940
942 {
943 return ptd->getPTDTY() == PTDataTy::PersVersioned;
944 }
946
947private:
952};
953
954} // End namespace SVF
955#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: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
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned PointsToID
Definition GeneralType.h:63