Static Value-Flow Analysis
VersionedFlowSensitiveStat.cpp
Go to the documentation of this file.
1 //===- VersionedFlowSensitiveStat.cpp -- Statistics for VFSPTA -//
2 
3 /*
4  * VersionedFlowSensitiveStat.cpp
5  *
6  * Created on: 25/07/2020
7  * Author: mbarbar
8  */
9 
10 #include "Util/SVFUtil.h"
11 #include "WPA/WPAStat.h"
13 #include "MemoryModel/PointsTo.h"
14 
15 using namespace SVF;
16 using namespace SVFUtil;
17 
19 {
20  _NumVersions = 0;
21  _MaxVersions = 0;
22  _NumNonEmptyVersions = 0;
23  _NumSingleVersion = 0;
24  _NumUsedVersions = 0;
25  _NumEmptyVersions = 0;
26  _MaxPtsSize = 0;
27  _MaxTopLvlPtsSize = 0;
28  _MaxVersionPtsSize = 0;
29  _TotalPtsSize = 0;
30  _AvgPtsSize = 0.0;
31  _AvgTopLvlPtsSize = 0.0;
32  _AvgVersionPtsSize = 0.0;
33 }
34 
36 {
37  // Largely based on that in FlowSensitiveStat. Would be better to split the FSStat version
38  // and reuse code rather than copy.
39  assert(SVFUtil::isa<VersionedFlowSensitive>(vfspta) && "VFSStat::performStat: not given VFSPTA.");
40  endClk();
41 
42  clearStat();
43 
44  SVFIR *pag = vfspta->getPAG();
45 
46  versionStat();
47  ptsSizeStat();
48 
49  u32_t fiObjNumber = 0;
50  u32_t fsObjNumber = 0;
51  Set<SymID> nodeSet;
52  for (SVFIR::const_iterator it = pag->begin(); it != pag->end(); ++it)
53  {
54  NodeID nodeId = it->first;
55  PAGNode* pagNode = it->second;
56  if (SVFUtil::isa<ObjVar>(pagNode))
57  {
58  const MemObj *memObj = pag->getBaseObj(nodeId);
59  SymID baseId = memObj->getId();
60  if (nodeSet.insert(baseId).second)
61  {
62  if (memObj->isFieldInsensitive()) fiObjNumber++;
63  else fsObjNumber++;
64  }
65  }
66  }
67 
68  PTNumStatMap["FIObjNum"] = fiObjNumber;
69  PTNumStatMap["FSObjNum"] = fsObjNumber;
70 
71  unsigned numOfCopy = 0;
72  unsigned numOfStore = 0;
73  for (SVFG::iterator it = vfspta->svfg->begin(); it != vfspta->svfg->end(); ++it)
74  {
75  SVFGNode* svfgNode = it->second;
76  if (SVFUtil::isa<CopySVFGNode>(svfgNode)) numOfCopy++;
77  else if (SVFUtil::isa<StoreSVFGNode>(svfgNode)) numOfStore++;
78  }
79 
81 
82  timeStatMap["TotalTime"] = (endTime - startTime)/TIMEINTERVAL;
83  timeStatMap["SolveTime"] = vfspta->solveTime;
84  timeStatMap["SCCTime"] = vfspta->sccTime;
85  timeStatMap["ProcessTime"] = vfspta->processTime;
86  timeStatMap["PropagationTime"] = vfspta->propagationTime;
87  timeStatMap["DirectPropaTime"] = vfspta->directPropaTime;
88  timeStatMap["IndirectPropaTime"] = vfspta->indirectPropaTime;
89  timeStatMap["Strong/WeakUpdTime"] = vfspta->updateTime;
90  timeStatMap["AddrTime"] = vfspta->addrTime;
91  timeStatMap["CopyTime"] = vfspta->copyTime;
92  timeStatMap["GepTime"] = vfspta->gepTime;
93  timeStatMap["LoadTime"] = vfspta->loadTime;
94  timeStatMap["StoreTime"] = vfspta->storeTime;
95  timeStatMap["UpdateCGTime"] = vfspta->updateCallGraphTime;
96  timeStatMap["PhiTime"] = vfspta->phiTime;
97  timeStatMap["meldLabelingTime"] = vfspta->meldLabelingTime;
98  timeStatMap["PrelabelingTime"] = vfspta->prelabelingTime;
99  timeStatMap["VersionPropTime"] = vfspta->versionPropTime;
100 
101  PTNumStatMap["TotalPointers"] = pag->getValueNodeNum() + pag->getFieldValNodeNum();
102  PTNumStatMap["TotalObjects"] = pag->getObjectNodeNum() + pag->getFieldObjNodeNum();
103 
104  PTNumStatMap["Pointers"] = pag->getValueNodeNum();
105  PTNumStatMap["MemObjects"] = pag->getObjectNodeNum();
106  PTNumStatMap["DummyFieldPtrs"] = pag->getFieldValNodeNum();
107  PTNumStatMap["FieldObjs"] = pag->getFieldObjNodeNum();
108 
109  PTNumStatMap["TotalVersions"] = _NumVersions;
110  PTNumStatMap["MaxVersionsForObj"] = _MaxVersions;
111  PTNumStatMap["TotalNonEmptyVPts"] = _NumNonEmptyVersions;
112  PTNumStatMap["TotalEmptyVPts"] = _NumEmptyVersions;
113  PTNumStatMap["TotalExistingVPts"] = _NumUsedVersions;
114  PTNumStatMap["TotalSingleVObjs"] = _NumSingleVersion;
115 
116  PTNumStatMap["CopysNum"] = numOfCopy;
117  PTNumStatMap["StoresNum"] = numOfStore;
118 
119  PTNumStatMap["SolveIterations"] = vfspta->numOfIteration;
120 
121  PTNumStatMap["IndEdgeSolved"] = vfspta->getNumOfResolvedIndCallEdge();
122 
123  PTNumStatMap["StrongUpdates"] = vfspta->svfgHasSU.count();
124 
125  PTNumStatMap["MaxPtsSize"] = _MaxPtsSize;
126  PTNumStatMap["MaxTopLvlPtsSize"] = _MaxTopLvlPtsSize;
127  PTNumStatMap["MaxVersionPtsSize"] = _MaxVersionPtsSize;
128 
129  timeStatMap["AvgPtsSize"] = _AvgPtsSize;
130  timeStatMap["AvgTopLvlPtsSize"] = _AvgTopLvlPtsSize;
131  timeStatMap["AvgVersionPtsSize"] = _AvgVersionPtsSize;
132 
133  PTNumStatMap["ProcessedAddr"] = vfspta->numOfProcessedAddr;
134  PTNumStatMap["ProcessedCopy"] = vfspta->numOfProcessedCopy;
135  PTNumStatMap["ProcessedGep"] = vfspta->numOfProcessedGep;
136  PTNumStatMap["ProcessedLoad"] = vfspta->numOfProcessedLoad;
137  PTNumStatMap["ProcessedStore"] = vfspta->numOfProcessedStore;
138  PTNumStatMap["ProcessedPhi"] = vfspta->numOfProcessedPhi;
139  PTNumStatMap["ProcessedAParam"] = vfspta->numOfProcessedActualParam;
140  PTNumStatMap["ProcessedFRet"] = vfspta->numOfProcessedFormalRet;
141  PTNumStatMap["ProcessedMSSANode"] = vfspta->numOfProcessedMSSANode;
142 
143  PTNumStatMap["NumOfNodesInSCC"] = vfspta->numOfNodesInSCC;
144  PTNumStatMap["MaxSCCSize"] = vfspta->maxSCCSize;
145  PTNumStatMap["NumOfSCC"] = vfspta->numOfSCC;
146  timeStatMap["AverageSCCSize"] = (vfspta->numOfSCC == 0) ? 0 :
147  ((double)vfspta->numOfNodesInSCC / vfspta->numOfSCC);
148 
149  PTAStat::printStat("Versioned Flow-Sensitive Pointer Analysis Statistics");
150 }
151 
153 {
154  // TODO! Need to merge yield/consume.
155  _NumSingleVersion = 0;
156  _MaxVersions = 0;
157 
158  u32_t totalVersionPtsSize = 0;
159  for (const VersionedFlowSensitive::LocVersionMap *lvm :
160  {
161  &vfspta->consume, &vfspta->yield
162  })
163  {
164  for (const VersionedFlowSensitive::ObjToVersionMap &lov : *lvm)
165  {
166  for (const VersionedFlowSensitive::ObjToVersionMap::value_type &ov : lov)
167  {
168  const NodeID o = ov.first;
169  const Version v = ov.second;
170 
171  ++_NumVersions;
172 
173  // If the version was just over-approximate and never accessed, ignore.
174  // TODO: with vPtD changed there is no interface to check if the PTS
175  // exists; an emptiness check is *not* an existence check.
176  if (vfspta->vPtD->getPts(vfspta->atKey(o, v)).empty()) continue;
177 
178  const PointsTo &ovPts = vfspta->vPtD->getPts(vfspta->atKey(o, v));
179  if (!ovPts.empty()) ++_NumNonEmptyVersions;
180  else ++_NumEmptyVersions;
181 
182  _TotalPtsSize += ovPts.count();
183  totalVersionPtsSize += ovPts.count();
184  if (ovPts.count() > _MaxVersionPtsSize) _MaxVersionPtsSize = ovPts.count();
185  }
186  }
187  }
188 
189  _NumUsedVersions = _NumNonEmptyVersions + _NumEmptyVersions;
190 
191  if (_NumNonEmptyVersions != 0) _AvgVersionPtsSize = (double)totalVersionPtsSize / (double)_NumUsedVersions;
192 
193  _TotalPtsSize += totalVersionPtsSize;
194 }
195 
197 {
198  u32_t totalValidTopLvlPointers = 0;
199  u32_t totalTopLvlPtsSize = 0;
200  for (SVFIR::iterator it = vfspta->getPAG()->begin(); it != vfspta->getPAG()->end(); ++it)
201  {
202  if (!vfspta->getPAG()->isValidTopLevelPtr(it->second)) continue;
203 
204  NodeID p = it->first;
205 
206  totalValidTopLvlPointers++;
207 
208  u32_t size = vfspta->getPts(p).count();
209  totalTopLvlPtsSize += size;
210  if (size > _MaxTopLvlPtsSize) _MaxTopLvlPtsSize = size;
211  }
212 
213  if (totalValidTopLvlPointers != 0) _AvgTopLvlPtsSize = (double)totalTopLvlPtsSize / (double)totalValidTopLvlPointers;
214 
215  _TotalPtsSize += totalTopLvlPtsSize;
216 
217  if (_NumNonEmptyVersions + totalValidTopLvlPointers != 0)
218  {
219  _AvgPtsSize = (double)_TotalPtsSize / (double)(_NumNonEmptyVersions + totalValidTopLvlPointers);
220  }
221 
222  _MaxPtsSize = _MaxVersionPtsSize > _MaxTopLvlPtsSize ? _MaxVersionPtsSize : _MaxTopLvlPtsSize;
223 }
#define TIMEINTERVAL
Definition: SVFType.h:512
cJSON * p
Definition: cJSON.cpp:2559
iterator begin()
Iterators.
Definition: GenericGraph.h:627
IDToNodeMapTy::const_iterator const_iterator
Definition: GenericGraph.h:607
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
u32_t getValueNodeNum() const
Definition: IRGraph.h:186
u32_t getObjectNodeNum() const
Definition: IRGraph.h:190
SymID getId() const
Get the memory object id.
bool isFieldInsensitive() const
Return true if its field limit is 0.
void performStat() override
Definition: PTAStat.cpp:52
bool empty() const
Returns true if set is empty.
Definition: PointsTo.cpp:98
u32_t count() const
Returns number of elements.
Definition: PointsTo.cpp:111
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
u32_t getFieldObjNodeNum() const
Definition: SVFIR.h:338
u32_t getFieldValNodeNum() const
Node and edge statistics.
Definition: SVFIR.h:334
const MemObj * getBaseObj(NodeID id) const
Definition: SVFIR.h:459
virtual void printStat(std::string str="")
Definition: SVFStat.cpp:66
void ptsSizeStat(void)
For all PTS size related statistics not handled by versionStat.
void versionStat(void)
For all version-related statistics.
std::vector< ObjToVersionMap > LocVersionMap
Map< NodeID, Version > ObjToVersionMap
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
unsigned Version
Definition: GeneralType.h:123
unsigned SymID
Definition: GeneralType.h:57
unsigned u32_t
Definition: GeneralType.h:46
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96