Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
SVF::PersistentPointsToCache< Data > Class Template Reference

#include <PersistentPointsToCache.h>

Public Types

typedef Map< Data, PointsToIDPTSToIDMap
 
typedef std::function< Data(const Data &, const Data &)> DataOp
 
typedef Map< std::pair< PointsToID, PointsToID >, PointsToIDOpCache
 

Public Member Functions

 PersistentPointsToCache (void)
 
void clear ()
 Clear the cache.
 
void reset (void)
 Resets the cache removing everything except the emptyData it was initialised with.
 
void remapAllPts (void)
 Remaps all points-to sets stored in the cache to the current mapping.
 
PointsToID emplacePts (const Data &pts)
 
const DatagetActualPts (PointsToID id) const
 Returns the points-to set which id represents. id must be stored in the cache.
 
PointsToID unionPts (PointsToID lhs, PointsToID rhs)
 Unions lhs and rhs and returns their union's ID.
 
PointsToID complementPts (PointsToID lhs, PointsToID rhs)
 Relatively complements lhs and rhs (lhs \ rhs) and returns it's ID.
 
PointsToID intersectPts (PointsToID lhs, PointsToID rhs)
 Intersects lhs and rhs (lhs AND rhs) and returns the intersection's ID.
 
void printStats (const std::string subtitle) const
 Print statistics on operations and points-to set numbers.
 
Map< Data, unsignedgetAllPts (void)
 

Static Public Member Functions

static PointsToID emptyPointsToId (void)
 

Private Member Functions

PointsToID newPointsToId (void)
 
PointsToID opPts (PointsToID lhs, PointsToID rhs, const DataOp &dataOp, OpCache &opCache, bool commutative, bool &opPerformed)
 
void initStats (void)
 Initialises statistics variables to 0.
 

Private Attributes

std::vector< std::unique_ptr< Data > > idToPts
 
PTSToIDMap ptsToId
 Maps points-to sets to their corresponding ID.
 
OpCache unionCache
 Maps two IDs to their union. Keys must be sorted.
 
OpCache complementCache
 Maps two IDs to their relative complement.
 
OpCache intersectionCache
 Maps two IDs to their intersection. Keys must be sorted.
 
PointsToID idCounter
 Used to generate new PointsToIDs. Any non-zero is valid.
 
u64_t totalUnions
 
u64_t uniqueUnions
 
u64_t propertyUnions
 
u64_t lookupUnions
 
u64_t preemptiveUnions
 
u64_t totalComplements
 
u64_t uniqueComplements
 
u64_t propertyComplements
 
u64_t lookupComplements
 
u64_t preemptiveComplements
 
u64_t totalIntersections
 
u64_t uniqueIntersections
 
u64_t propertyIntersections
 
u64_t lookupIntersections
 
u64_t preemptiveIntersections
 

Detailed Description

template<typename Data>
class SVF::PersistentPointsToCache< Data >

Persistent points-to set store. Can be used as a backing for points-to data structures like PointsToDS and PointsToDFDS. Hides points-to sets and union operations from users and hands out PointsToIDs. Points-to sets are interned, and union operations are lazy and hash-consed.

Definition at line 32 of file PersistentPointsToCache.h.

Member Typedef Documentation

◆ DataOp

template<typename Data >
typedef std::function<Data(const Data &, const Data &)> SVF::PersistentPointsToCache< Data >::DataOp

Definition at line 36 of file PersistentPointsToCache.h.

◆ OpCache

Definition at line 38 of file PersistentPointsToCache.h.

◆ PTSToIDMap

Definition at line 35 of file PersistentPointsToCache.h.

Constructor & Destructor Documentation

◆ PersistentPointsToCache()

template<typename Data >
SVF::PersistentPointsToCache< Data >::PersistentPointsToCache ( void  )
inline

Definition at line 46 of file PersistentPointsToCache.h.

46 : idCounter(1)
47 {
48 idToPts.push_back(std::make_unique<Data>());
50
51 initStats();
52 }
std::vector< std::unique_ptr< Data > > idToPts
PTSToIDMap ptsToId
Maps points-to sets to their corresponding ID.
static PointsToID emptyPointsToId(void)
void initStats(void)
Initialises statistics variables to 0.
PointsToID idCounter
Used to generate new PointsToIDs. Any non-zero is valid.
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

Member Function Documentation

◆ clear()

template<typename Data >
void SVF::PersistentPointsToCache< Data >::clear ( )
inline

Clear the cache.

Definition at line 55 of file PersistentPointsToCache.h.

56 {
57 idToPts.clear();
58 ptsToId.clear();
59
60 unionCache.clear();
61 complementCache.clear();
62 intersectionCache.clear();
63 }
OpCache intersectionCache
Maps two IDs to their intersection. Keys must be sorted.
OpCache unionCache
Maps two IDs to their union. Keys must be sorted.
OpCache complementCache
Maps two IDs to their relative complement.

◆ complementPts()

template<typename Data >
PointsToID SVF::PersistentPointsToCache< Data >::complementPts ( PointsToID  lhs,
PointsToID  rhs 
)
inline

Relatively complements lhs and rhs (lhs \ rhs) and returns it's ID.

Definition at line 173 of file PersistentPointsToCache.h.

174 {
175 static const DataOp complementOp = [](const Data &lhs, const Data &rhs)
176 {
177 return lhs - rhs;
178 };
179
181
182 // Property cases.
183 // x - x
184 if (lhs == rhs)
185 {
187 return emptyPointsToId();
188 }
189
190 // x - EMPTY_SET
191 if (rhs == emptyPointsToId())
192 {
194 return lhs;
195 }
196
197 // EMPTY_SET - x
198 if (lhs == emptyPointsToId())
199 {
201 return emptyPointsToId();
202 }
203
204 bool opPerformed = false;
206
207 if (opPerformed)
208 {
210
211 // We performed lhs - rhs = result, so...
212 if (result != emptyPointsToId())
213 {
214 // result AND rhs = EMPTY_SET,
215 intersectionCache[std::minmax(result, rhs)] = emptyPointsToId();
218
219 // and result AND lhs = result,
220 intersectionCache[std::minmax(result, lhs)] = result;
223
224 // and result - rhs = result.
225 complementCache[std::make_pair(result, rhs)] = result;
228 }
229 }
230 else ++lookupComplements;
231
232 return result;
233 }
std::function< Data(const Data &, const Data &)> DataOp
PointsToID opPts(PointsToID lhs, PointsToID rhs, const DataOp &dataOp, OpCache &opCache, bool commutative, bool &opPerformed)
unsigned PointsToID
Definition GeneralType.h:63

◆ emplacePts()

template<typename Data >
PointsToID SVF::PersistentPointsToCache< Data >::emplacePts ( const Data pts)
inline

If pts is not in the PersistentPointsToCache, inserts it, assigns an ID, and returns that ID. If it is, then the ID is returned.

Definition at line 91 of file PersistentPointsToCache.h.

92 {
93 // Is it already in the cache?
94 typename PTSToIDMap::const_iterator foundId = ptsToId.find(pts);
95 if (foundId != ptsToId.end()) return foundId->second;
96
97 // Otherwise, insert it.
99 idToPts.push_back(std::make_unique<Data>(pts));
100 ptsToId[pts] = id;
101
102 return id;
103 }

◆ emptyPointsToId()

template<typename Data >
static PointsToID SVF::PersistentPointsToCache< Data >::emptyPointsToId ( void  )
inlinestatic

Definition at line 40 of file PersistentPointsToCache.h.

41 {
42 return 0;
43 };

◆ getActualPts()

template<typename Data >
const Data & SVF::PersistentPointsToCache< Data >::getActualPts ( PointsToID  id) const
inline

Returns the points-to set which id represents. id must be stored in the cache.

Definition at line 106 of file PersistentPointsToCache.h.

107 {
108 // Check if the points-to set for ID has already been stored.
109 assert(idToPts.size() > id && "PPTC::getActualPts: points-to set not stored!");
110 return *idToPts.at(id);
111 }

◆ getAllPts()

template<typename Data >
Map< Data, unsigned > SVF::PersistentPointsToCache< Data >::getAllPts ( void  )
inline

Returns all points-to sets stored by this cache as keys to a map. Values are all 1. We use the map to be more compatible with getAllPts in the various PTDatas. Performance is a non-issue (for now) since this is just used for evaluation's sake.

Definition at line 345 of file PersistentPointsToCache.h.

346 {
348 for (const auto &d : idToPts) allPts[*d] = 1;
349 return allPts;
350 }

◆ initStats()

template<typename Data >
void SVF::PersistentPointsToCache< Data >::initStats ( void  )
inlineprivate

◆ intersectPts()

template<typename Data >
PointsToID SVF::PersistentPointsToCache< Data >::intersectPts ( PointsToID  lhs,
PointsToID  rhs 
)
inline

Intersects lhs and rhs (lhs AND rhs) and returns the intersection's ID.

Definition at line 236 of file PersistentPointsToCache.h.

237 {
238 static const DataOp intersectionOp = [](const Data &lhs, const Data &rhs)
239 {
240 return lhs & rhs;
241 };
242
244
245 // Order operands so we don't perform x U y and y U x separately.
246 std::pair<PointsToID, PointsToID> operands = std::minmax(lhs, rhs);
247
248 // Property cases.
249 // EMPTY_SET & x
250 if (operands.first == emptyPointsToId())
251 {
253 return emptyPointsToId();
254 }
255
256 // x & x
257 if (operands.first == operands.second)
258 {
260 return operands.first;
261 }
262
263 bool opPerformed = false;
265 if (opPerformed)
266 {
268
269 // When the result is empty, we won't be adding anything of substance.
270 if (result != emptyPointsToId())
271 {
272 // We performed lhs AND rhs = result, so...
273 // result AND rhs = result,
274 if (result != rhs)
275 {
276 intersectionCache[std::minmax(result, rhs)] = result;
279 }
280
281 // and result AND lhs = result,
282 if (result != lhs)
283 {
284 intersectionCache[std::minmax(result, lhs)] = result;
287 }
288
289 // Also (thanks reviewer #2)
290 // result U lhs = result,
291 if (result != emptyPointsToId() && result != lhs)
292 {
293 unionCache[std::minmax(lhs, result)] = lhs;
295 ++totalUnions;
296 }
297
298 // And result U rhs = rhs.
299 if (result != emptyPointsToId() && result != rhs)
300 {
301 unionCache[std::minmax(rhs, result)] = rhs;
303 ++totalUnions;
304 }
305 }
306 }
307 else ++lookupIntersections;
308
309 return result;
310 }

◆ newPointsToId()

template<typename Data >
PointsToID SVF::PersistentPointsToCache< Data >::newPointsToId ( void  )
inlineprivate

Definition at line 355 of file PersistentPointsToCache.h.

356 {
357 // Make sure we don't overflow.
358 assert(idCounter != emptyPointsToId() && "PPTC::newPointsToId: PointsToIDs exhausted! Try a larger type.");
359 return idCounter++;
360 }

◆ opPts()

template<typename Data >
PointsToID SVF::PersistentPointsToCache< Data >::opPts ( PointsToID  lhs,
PointsToID  rhs,
const DataOp dataOp,
OpCache opCache,
bool  commutative,
bool opPerformed 
)
inlineprivate

Performs dataOp on lhs and rhs, checking the opCache first and updating it afterwards. commutative indicates whether the operation in question is commutative or not. opPerformed is set to true if the operation was not cached and thus performed, false otherwise.

Definition at line 365 of file PersistentPointsToCache.h.

367 {
368 std::pair<PointsToID, PointsToID> operands;
369 // If we're commutative, we want to always perform the same operation: x op y.
370 // Performing x op y sometimes and y op x other times is a waste of time.
371 if (commutative) operands = std::minmax(lhs, rhs);
372 else operands = std::make_pair(lhs, rhs);
373
374 // Check if we have performed this operation
375 OpCache::const_iterator foundResult = opCache.find(operands);
376 if (foundResult != opCache.end()) return foundResult->second;
377
378 opPerformed = true;
379
380 const Data &lhsPts = getActualPts(lhs);
381 const Data &rhsPts = getActualPts(rhs);
382
384
386 // Intern points-to set: check if result already exists.
387 typename PTSToIDMap::const_iterator foundId = ptsToId.find(result);
388 if (foundId != ptsToId.end()) resultId = foundId->second;
389 else
390 {
392 idToPts.push_back(std::make_unique<Data>(result));
394 }
395
396 // Cache the result, for hash-consing.
398
399 return resultId;
400 }
const Data & getActualPts(PointsToID id) const
Returns the points-to set which id represents. id must be stored in the cache.

◆ printStats()

template<typename Data >
void SVF::PersistentPointsToCache< Data >::printStats ( const std::string  subtitle) const
inline

Print statistics on operations and points-to set numbers.

Definition at line 313 of file PersistentPointsToCache.h.

314 {
315 static const unsigned fieldWidth = 25;
316 SVFUtil::outs().flags(std::ios::left);
317
318 SVFUtil::outs() << std::setw(fieldWidth) << "UniquePointsToSets" << idToPts.size() << "\n";
319
320 SVFUtil::outs() << std::setw(fieldWidth) << "TotalUnions" << totalUnions << "\n";
321 SVFUtil::outs() << std::setw(fieldWidth) << "PropertyUnions" << propertyUnions << "\n";
322 SVFUtil::outs() << std::setw(fieldWidth) << "UniqueUnions" << uniqueUnions << "\n";
323 SVFUtil::outs() << std::setw(fieldWidth) << "LookupUnions" << lookupUnions << "\n";
324 SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveUnions" << preemptiveUnions << "\n";
325
326 SVFUtil::outs() << std::setw(fieldWidth) << "TotalComplements" << totalComplements << "\n";
327 SVFUtil::outs() << std::setw(fieldWidth) << "PropertyComplements" << propertyComplements << "\n";
328 SVFUtil::outs() << std::setw(fieldWidth) << "UniqueComplements" << uniqueComplements << "\n";
329 SVFUtil::outs() << std::setw(fieldWidth) << "LookupComplements" << lookupComplements << "\n";
330 SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveComplements" << preemptiveComplements << "\n";
331
332 SVFUtil::outs() << std::setw(fieldWidth) << "TotalIntersections" << totalIntersections << "\n";
333 SVFUtil::outs() << std::setw(fieldWidth) << "PropertyIntersections" << propertyIntersections << "\n";
334 SVFUtil::outs() << std::setw(fieldWidth) << "UniqueIntersections" << uniqueIntersections << "\n";
335 SVFUtil::outs() << std::setw(fieldWidth) << "LookupIntersections" << lookupIntersections << "\n";
336 SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveIntersections" << preemptiveIntersections << "\n";
337
338 SVFUtil::outs().flush();
339 }
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50

◆ remapAllPts()

template<typename Data >
void SVF::PersistentPointsToCache< Data >::remapAllPts ( void  )
inline

Remaps all points-to sets stored in the cache to the current mapping.

Definition at line 80 of file PersistentPointsToCache.h.

81 {
82 for (auto &d : idToPts) d->checkAndRemap();
83
84 // Rebuild ptsToId from idToPts.
85 ptsToId.clear();
86 for (PointsToID i = 0; i < idToPts.size(); ++i) ptsToId[*idToPts[i]] = i;
87 }

◆ reset()

template<typename Data >
void SVF::PersistentPointsToCache< Data >::reset ( void  )
inline

Resets the cache removing everything except the emptyData it was initialised with.

Definition at line 66 of file PersistentPointsToCache.h.

67 {
68 clear();
69
70 // Put the empty data back in.
72 idToPts.push_back(std::make_unique<Data>());
73
74 idCounter = 1;
75 // Cache is empty...
76 initStats();
77 }

◆ unionPts()

template<typename Data >
PointsToID SVF::PersistentPointsToCache< Data >::unionPts ( PointsToID  lhs,
PointsToID  rhs 
)
inline

Unions lhs and rhs and returns their union's ID.

Definition at line 114 of file PersistentPointsToCache.h.

115 {
116 static const DataOp unionOp = [](const Data &lhs, const Data &rhs)
117 {
118 return lhs | rhs;
119 };
120
121 ++totalUnions;
122
123 // Order operands so we don't perform x U y and y U x separately.
124 std::pair<PointsToID, PointsToID> operands = std::minmax(lhs, rhs);
125
126 // Property cases.
127 // EMPTY_SET U x
128 if (operands.first == emptyPointsToId())
129 {
131 return operands.second;
132 }
133
134 // x U x
135 if (operands.first == operands.second)
136 {
138 return operands.first;
139 }
140
141 bool opPerformed = false;
143
144 if (opPerformed)
145 {
146 ++uniqueUnions;
147
148 // We can use lhs/rhs here rather than our ordered operands,
149 // because the operation was commutative.
150
151 // if x U y = z, then x U z = z,
152 if (lhs != result)
153 {
154 unionCache[std::minmax(lhs, result)] = result;
156 ++totalUnions;
157 }
158
159 // and y U z = z.
160 if (rhs != result)
161 {
162 unionCache[std::minmax(rhs, result)] = result;
164 ++totalUnions;
165 }
166 }
167 else ++lookupUnions;
168
169 return result;
170 }

Member Data Documentation

◆ complementCache

template<typename Data >
OpCache SVF::PersistentPointsToCache< Data >::complementCache
private

Maps two IDs to their relative complement.

Definition at line 436 of file PersistentPointsToCache.h.

◆ idCounter

template<typename Data >
PointsToID SVF::PersistentPointsToCache< Data >::idCounter
private

Used to generate new PointsToIDs. Any non-zero is valid.

Definition at line 441 of file PersistentPointsToCache.h.

◆ idToPts

template<typename Data >
std::vector<std::unique_ptr<Data> > SVF::PersistentPointsToCache< Data >::idToPts
private

Maps points-to IDs (indices) to their corresponding points-to set. Reverse of idToPts. Elements are only added through push_back, so the number of elements stored is the size of the vector. Not const so we can remap.

Definition at line 429 of file PersistentPointsToCache.h.

◆ intersectionCache

template<typename Data >
OpCache SVF::PersistentPointsToCache< Data >::intersectionCache
private

Maps two IDs to their intersection. Keys must be sorted.

Definition at line 438 of file PersistentPointsToCache.h.

◆ lookupComplements

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::lookupComplements
private

Definition at line 452 of file PersistentPointsToCache.h.

◆ lookupIntersections

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::lookupIntersections
private

Definition at line 457 of file PersistentPointsToCache.h.

◆ lookupUnions

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::lookupUnions
private

Definition at line 447 of file PersistentPointsToCache.h.

◆ preemptiveComplements

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::preemptiveComplements
private

Definition at line 453 of file PersistentPointsToCache.h.

◆ preemptiveIntersections

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::preemptiveIntersections
private

Definition at line 458 of file PersistentPointsToCache.h.

◆ preemptiveUnions

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::preemptiveUnions
private

Definition at line 448 of file PersistentPointsToCache.h.

◆ propertyComplements

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::propertyComplements
private

Definition at line 451 of file PersistentPointsToCache.h.

◆ propertyIntersections

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::propertyIntersections
private

Definition at line 456 of file PersistentPointsToCache.h.

◆ propertyUnions

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::propertyUnions
private

Definition at line 446 of file PersistentPointsToCache.h.

◆ ptsToId

template<typename Data >
PTSToIDMap SVF::PersistentPointsToCache< Data >::ptsToId
private

Maps points-to sets to their corresponding ID.

Definition at line 431 of file PersistentPointsToCache.h.

◆ totalComplements

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::totalComplements
private

Definition at line 449 of file PersistentPointsToCache.h.

◆ totalIntersections

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::totalIntersections
private

Definition at line 454 of file PersistentPointsToCache.h.

◆ totalUnions

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::totalUnions
private

Definition at line 444 of file PersistentPointsToCache.h.

◆ unionCache

template<typename Data >
OpCache SVF::PersistentPointsToCache< Data >::unionCache
private

Maps two IDs to their union. Keys must be sorted.

Definition at line 434 of file PersistentPointsToCache.h.

◆ uniqueComplements

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::uniqueComplements
private

Definition at line 450 of file PersistentPointsToCache.h.

◆ uniqueIntersections

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::uniqueIntersections
private

Definition at line 455 of file PersistentPointsToCache.h.

◆ uniqueUnions

template<typename Data >
u64_t SVF::PersistentPointsToCache< Data >::uniqueUnions
private

Definition at line 445 of file PersistentPointsToCache.h.


The documentation for this class was generated from the following file: