Static Value-Flow Analysis
DDAStat.cpp
Go to the documentation of this file.
1 //===- DDAStat.cpp -- Statistics for demand-driven pass-------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * DDAStat.cpp
25  *
26  * Created on: Sep 15, 2014
27  * Author: Yulei Sui
28  */
29 
30 #include "DDA/DDAStat.h"
31 #include "DDA/FlowDDA.h"
32 #include "DDA/ContextDDA.h"
33 #include "Graphs/SVFGStat.h"
34 #include "MemoryModel/PointsTo.h"
35 
36 #include <iomanip>
37 
38 using namespace SVF;
39 using namespace SVFUtil;
40 using namespace std;
41 
42 DDAStat::DDAStat(FlowDDA* pta) : PTAStat(pta), flowDDA(pta), contextDDA(nullptr)
43 {
44  initDefault();
45 }
46 DDAStat::DDAStat(ContextDDA* pta) : PTAStat(pta), flowDDA(nullptr), contextDDA(pta)
47 {
48  initDefault();
49 }
50 
52 {
53  _TotalNumOfQuery = 0;
55  _TotalNumOfDPM = 0;
59  _TotalNumOfStep = 0;
61 
65  _NumOfNullPtr = 0;
71  _AnaTimePerQuery = 0;
73 
74 
75  _NumOfDPM = 0;
79 
80  _NumOfStep = 0;
82  _AnaTimePerQuery = 0;
85 }
86 
88 {
89  if(flowDDA)
90  return flowDDA->getSVFG();
91  else
92  return contextDDA->getSVFG();
93 
94 }
95 
97 {
98  if(flowDDA)
99  return flowDDA;
100  else
101  return contextDDA;
102 }
103 
105 {
106 
107  u32_t NumOfDPM = 0;
108  u32_t NumOfLoc = 0;
109  u32_t maxNumOfDPMPerLoc = 0;
110  u32_t cptsSize = 0;
111  PointsTo pts;
112  if(flowDDA)
113  {
114  for(FlowDDA::LocToDPMVecMap::const_iterator it = flowDDA->getLocToDPMVecMap().begin(),
115  eit = flowDDA->getLocToDPMVecMap().end(); it!=eit; ++it)
116  {
117  NumOfLoc++;
118  u32_t num = it->second.size();
119  NumOfDPM += num;
120  if(num > maxNumOfDPMPerLoc)
121  maxNumOfDPMPerLoc = num;
122  }
123  cptsSize = flowDDA->getPts(ptr).count();
124  pts = flowDDA->getPts(ptr);
125  }
126  else if(contextDDA)
127  {
128  for(ContextDDA::LocToDPMVecMap::const_iterator it = contextDDA->getLocToDPMVecMap().begin(),
129  eit = contextDDA->getLocToDPMVecMap().end(); it!=eit; ++it)
130  {
131  NumOfLoc++;
132  u32_t num = it->second.size();
133  NumOfDPM += num;
134  if(num > maxNumOfDPMPerLoc)
135  maxNumOfDPMPerLoc = num;
136  }
137  ContextCond cxt;
138  CxtVar var(cxt,ptr);
139  cptsSize = contextDDA->getPts(var).count();
141  }
142  u32_t ptsSize = pts.count();
143 
144  double avgDPMAtLoc = NumOfLoc!=0 ? (double)NumOfDPM/NumOfLoc : 0;
145  _AvgNumOfDPMAtSVFGNode += avgDPMAtLoc;
146  if(maxNumOfDPMPerLoc > _MaxNumOfDPMAtSVFGNode)
147  _MaxNumOfDPMAtSVFGNode = maxNumOfDPMPerLoc;
148 
149  _TotalCPtsSize += cptsSize;
150  if (_MaxCPtsSize < cptsSize)
151  _MaxCPtsSize = cptsSize;
152 
153  _TotalPtsSize += ptsSize;
154  if(_MaxPtsSize < ptsSize)
155  _MaxPtsSize = ptsSize;
156 
157  if(cptsSize == 0)
158  _NumOfNullPtr++;
159 
160  if(getPTA()->containBlackHoleNode(pts))
161  {
163  }
164  if(getPTA()->containConstantNode(pts))
165  {
167  }
168 
174 
177 
178  timeStatMap.clear();
179  NumPerQueryStatMap.clear();
180 
181  timeStatMap["TimePerQuery"] = _AnaTimePerQuery/TIMEINTERVAL;
182  timeStatMap["CyleTimePerQuery"] = _AnaTimeCyclePerQuery/TIMEINTERVAL;
183 
184  NumPerQueryStatMap["CPtsSize"] = cptsSize;
185  NumPerQueryStatMap["PtsSize"] = ptsSize;
186  NumPerQueryStatMap["NumOfStep"] = _NumOfStep;
187  NumPerQueryStatMap["NumOfStepInCycle"] = _NumOfStepInCycle;
188  NumPerQueryStatMap["NumOfDPM"] = _NumOfDPM;
191  NumPerQueryStatMap["AvgDPMAtLoc"] = avgDPMAtLoc;
192  NumPerQueryStatMap["MaxDPMAtLoc"] = maxNumOfDPMPerLoc;
193  NumPerQueryStatMap["MaxPathPerQuery"] = ContextCond::maximumPath;
194  NumPerQueryStatMap["MaxCxtPerQuery"] = ContextCond::maximumCxt;
195  NumPerQueryStatMap["NumOfMustAA"] = _NumOfMustAliases;
196  NumPerQueryStatMap["NumOfInfePath"] = _NumOfInfeasiblePath;
197 
199  _NumOfStep = 0;
200  _NumOfStepInCycle = 0;
201  _NumOfDPM = 0;
203  _NumOfMustAliases = 0;
207 }
208 
210 {
211  if (flowDDA)
213  else if (contextDDA)
215 }
216 
218 {
219 
220  generalNumMap.clear();
221  PTNumStatMap.clear();
222  timeStatMap.clear();
223 
224  callgraphStat();
225 
227 
228  for (SVFIR::const_iterator nodeIt = SVFIR::getPAG()->begin(), nodeEit = SVFIR::getPAG()->end(); nodeIt != nodeEit; nodeIt++)
229  {
230  PAGNode* pagNode = nodeIt->second;
231  if(SVFUtil::isa<ObjVar>(pagNode))
232  {
233  if(getPTA()->isLocalVarInRecursiveFun(nodeIt->first))
234  {
235  localVarInRecursion.set(nodeIt->first);
236  }
237  }
238  }
239 
240  timeStatMap["TotalQueryTime"] = _TotalTimeOfQueries/TIMEINTERVAL;
242  timeStatMap["TotalBKCondTime"] = (_TotalTimeOfBKCondition/TIMEINTERVAL);
243 
244  PTNumStatMap["NumOfQuery"] = _TotalNumOfQuery;
245  PTNumStatMap["NumOfOOBQuery"] = _TotalNumOfOutOfBudgetQuery;
246  PTNumStatMap["NumOfDPM"] = _TotalNumOfDPM;
248  PTNumStatMap["NumOfStoreSU"] = _StrongUpdateStores.count();
249  PTNumStatMap["NumOfStep"] = _TotalNumOfStep;
250  PTNumStatMap["NumOfStepInCycle"] = _TotalNumOfStepInCycle;
251  timeStatMap["AvgDPMAtLoc"] = (double)_AvgNumOfDPMAtSVFGNode/_TotalNumOfQuery;
252  PTNumStatMap["MaxDPMAtLoc"] = _MaxNumOfDPMAtSVFGNode;
253  PTNumStatMap["MaxPathPerQuery"] = ContextCond::maximumPath;
254  PTNumStatMap["MaxCxtPerQuery"] = ContextCond::maximumCxt;
255  PTNumStatMap["MaxCPtsSize"] = _MaxCPtsSize;
256  PTNumStatMap["MaxPtsSize"] = _MaxPtsSize;
257  timeStatMap["AvgCPtsSize"] = (double)_TotalCPtsSize/_TotalNumOfQuery;
258  timeStatMap["AvgPtsSize"] = (double)_TotalPtsSize/_TotalNumOfQuery;
259  PTNumStatMap["IndEdgeSolved"] = getPTA()->getNumOfResolvedIndCallEdge();
260  PTNumStatMap["NumOfNullPtr"] = _NumOfNullPtr;
261  PTNumStatMap["PointsToConstPtr"] = _NumOfConstantPtr;
262  PTNumStatMap["PointsToBlkPtr"] = _NumOfBlackholePtr;
263  PTNumStatMap["NumOfMustAA"] = _TotalNumOfMustAliases;
264  PTNumStatMap["NumOfInfePath"] = _TotalNumOfInfeasiblePath;
265  PTNumStatMap["NumOfStore"] = SVFIR::getPAG()->getPTASVFStmtSet(SVFStmt::Store).size();
266  timeStatMap["MemoryUsageVmrss"] = _vmrssUsageAfter - _vmrssUsageBefore;
267  timeStatMap["MemoryUsageVmsize"] = _vmsizeUsageAfter - _vmsizeUsageBefore;
268 
269  printStat();
270 }
271 
273 {
274 
275  if (timeStatMap.empty() == false && NumPerQueryStatMap.empty() == false)
276  {
277  SVFUtil::outs().flags(std::ios::left);
278  unsigned field_width = 20;
279  SVFUtil::outs() << "---------------------Stat Per Query--------------------------------\n";
280  for (TIMEStatMap::iterator it = timeStatMap.begin(), eit = timeStatMap.end(); it != eit; ++it)
281  {
282  // format out put with width 20 space
283  SVFUtil::outs() << std::setw(field_width) << it->first << it->second << "\n";
284  }
285  for (NUMStatMap::iterator it = NumPerQueryStatMap.begin(), eit = NumPerQueryStatMap.end(); it != eit; ++it)
286  {
287  // format out put with width 20 space
288  SVFUtil::outs() << std::setw(field_width) << it->first << it->second << "\n";
289  }
290  }
291  getPTA()->dumpPts(ptr, pts);
292 }
293 
294 
295 void DDAStat::printStat(string str)
296 {
297 
298  if(flowDDA)
299  {
301  flowDDA->getSVFG()->getStat()->performSCCStat(edgeSet);
302  }
303  else if(contextDDA)
304  {
306  }
307 
308  SVFUtil::outs() << "\n****Demand-Driven Pointer Analysis Statistics****\n";
309  PTAStat::printStat(str);
310 }
#define TIMEINTERVAL
Definition: SVFType.h:512
const PointsTo & getPts(NodeID id) override
virtual const CPtSet & getPts(CVar id)
virtual PointsTo getBVPointsTo(const CPtSet &cpts) const
Given a conditional pts return its bit vector points-to.
unsigned count() const
static u32_t maximumCxt
Definition: DPItem.h:378
static u32_t maximumPath
Definition: DPItem.h:379
ConstSVFGEdgeSet & getInsensitiveEdgeSet()
Return insensitive edge set.
Definition: ContextDDA.h:207
u32_t _TotalNumOfStep
Definition: DDAStat.h:89
u32_t _NumOfMustAliases
Definition: DDAStat.h:56
void performStatPerQuery(NodeID ptr) override
Definition: DDAStat.cpp:104
u32_t _TotalNumOfInfeasiblePath
Definition: DDAStat.h:87
u32_t _TotalPtsSize
Definition: DDAStat.h:96
u32_t _TotalNumOfOutOfBudgetQuery
Definition: DDAStat.h:83
u32_t _MaxPtsSize
Definition: DDAStat.h:94
double _AnaTimePerQuery
Definition: DDAStat.h:61
double _AvgNumOfDPMAtSVFGNode
Definition: DDAStat.h:101
u32_t _TotalNumOfMustAliases
Definition: DDAStat.h:86
u32_t _TotalNumOfDPM
Definition: DDAStat.h:84
SVFG * getSVFG() const
Definition: DDAStat.cpp:87
u32_t _TotalCPtsSize
Definition: DDAStat.h:95
PointerAnalysis * getPTA() const
Definition: DDAStat.cpp:96
u32_t _NumOfDPM
Definition: DDAStat.h:54
u32_t _NumOfStrongUpdates
Definition: DDAStat.h:55
u32_t _NumOfInfeasiblePath
Definition: DDAStat.h:57
void performStat() override
Definition: DDAStat.cpp:217
u32_t _TotalNumOfStrongUpdates
Definition: DDAStat.h:85
u64_t _NumOfStep
Definition: DDAStat.h:59
u32_t _MaxNumOfDPMAtSVFGNode
Definition: DDAStat.h:102
NUMStatMap NumPerQueryStatMap
Definition: DDAStat.h:104
FlowDDA * flowDDA
Definition: DDAStat.h:79
u32_t _TotalNumOfQuery
Definition: DDAStat.h:82
double _TotalTimeOfBKCondition
Definition: DDAStat.h:64
u32_t _NumOfConstantPtr
Definition: DDAStat.h:98
u64_t _NumOfStepInCycle
Definition: DDAStat.h:60
u32_t _NumOfNullPtr
Definition: DDAStat.h:97
double _AnaTimeCyclePerQuery
Definition: DDAStat.h:62
void getNumOfOOBQuery()
Definition: DDAStat.cpp:209
double _TotalTimeOfQueries
Definition: DDAStat.h:63
ContextDDA * contextDDA
Definition: DDAStat.h:80
void initDefault()
Definition: DDAStat.cpp:51
u32_t _TotalNumOfStepInCycle
Definition: DDAStat.h:90
u32_t _MaxCPtsSize
Definition: DDAStat.h:93
NodeBS _StrongUpdateStores
Definition: DDAStat.h:66
u32_t _NumOfIndCallEdgeSolved
Definition: DDAStat.h:92
void printStatPerQuery(NodeID ptr, const PointsTo &pts) override
Definition: DDAStat.cpp:272
void printStat(std::string str="") override
Definition: DDAStat.cpp:295
DDAStat(FlowDDA *pta)
Definition: DDAStat.cpp:42
u32_t _NumOfBlackholePtr
Definition: DDAStat.h:99
DPTItemSet outOfBudgetDpms
out of budget dpm set
Definition: DDAVFSolver.h:787
SVFG * getSVFG() const
Return SVFG.
Definition: DDAVFSolver.h:118
const LocToDPMVecMap & getLocToDPMVecMap() const
Map a SVFGNode to its dpms for handling value-flow cycles.
Definition: DDAVFSolver.h:660
OrderedSet< const SVFGEdge * > ConstSVFGEdgeSet
Definition: DDAVFSolver.h:60
IDToNodeMapTy::const_iterator const_iterator
Definition: GenericGraph.h:607
u32_t _vmsizeUsageBefore
Definition: PTAStat.h:77
NodeBS localVarInRecursion
Definition: PTAStat.h:54
u32_t _vmsizeUsageAfter
Definition: PTAStat.h:78
u32_t _vmrssUsageAfter
Definition: PTAStat.h:76
u32_t _vmrssUsageBefore
Definition: PTAStat.h:75
void callgraphStat() override
Definition: PTAStat.cpp:81
virtual void dumpPts(NodeID ptr, const PointsTo &pts)
bool containBlackHoleNode(const PointsTo &pts)
Determine whether a points-to contains a black hole or constant node.
u32_t getNumOfResolvedIndCallEdge() const
Return number of resolved indirect call edges.
bool containConstantNode(const PointsTo &pts)
u32_t count() const
Returns number of elements.
Definition: PointsTo.cpp:111
virtual void performSCCStat(SVFGEdgeSet insensitiveCalRetEdges)
Definition: SVFGStat.cpp:369
Definition: SVFG.h:66
SVFGStat * getStat() const
Return statistics.
Definition: SVFG.h:126
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
SVFStmt::SVFStmtSetTy & getPTASVFStmtSet(SVFStmt::PEDGEK kind)
Get PTA edges set according to its kind.
Definition: SVFIR.h:206
NUMStatMap generalNumMap
Definition: SVFStat.h:76
NUMStatMap PTNumStatMap
Definition: SVFStat.h:77
virtual void printStat(std::string str="")
Definition: SVFStat.cpp:66
TIMEStatMap timeStatMap
Definition: SVFStat.h:78
void set(unsigned Idx)
unsigned count() const
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
unsigned u32_t
Definition: GeneralType.h:46