Static Value-Flow Analysis
Andersen.h
Go to the documentation of this file.
1 //===- Andersen.h -- Field-sensitive Andersen's pointer analysis-------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2017> <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  * Andersen.h
25  *
26  * Created on: Nov 12, 2013
27  * Author: Yulei Sui
28  *
29  * The field-sensitive implementation is improved based on
30  *
31  * Yuxiang Lei and Yulei Sui. "Fast and Precise Handling of Positive Weight Cycles for Field-sensitive Pointer Analysis".
32  * 26th International Static Analysis Symposium (SAS'19)
33  */
34 
35 #ifndef INCLUDE_WPA_ANDERSEN_H_
36 #define INCLUDE_WPA_ANDERSEN_H_
37 
39 #include "WPA/WPAStat.h"
40 #include "WPA/WPASolver.h"
41 #include "SVFIR/SVFIR.h"
42 #include "Graphs/ConsG.h"
43 #include "Util/Options.h"
44 
45 namespace SVF
46 {
47 
48 class SVFModule;
49 
50 class ThreadCallGraph;
51 
56 
58 {
59 public:
61 
62 public:
63 
65  AndersenBase(SVFIR* _pag, PTATY type = Andersen_BASE, bool alias_check = true)
66  : BVDataPTAImpl(_pag, type, alias_check), consCG(nullptr)
67  {
69  }
70 
72  ~AndersenBase() override;
73 
75  virtual void analyze() override;
76 
77  virtual void solveAndwritePtsToFile(const std::string& filename);
78 
79  virtual void readPtsFromFile(const std::string& filename);
80 
81  virtual void solveConstraints();
82 
84  virtual void initialize() override;
85 
87  virtual void finalize() override;
88 
90  virtual bool updateCallGraph(const CallSiteToFunPtrMap&) override;
91 
94 
96  virtual void connectCaller2ForkedFunParams(const CallICFGNode* cs, const SVFFunction* F,
97  NodePairSet& cpySrcNodes);
98 
100  virtual void connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F,
101  NodePairSet& cpySrcNodes);
102 
104 
105  static inline bool classof(const AndersenBase *)
106  {
107  return true;
108  }
109  static inline bool classof(const PointerAnalysis *pta)
110  {
111  return ( pta->getAnalysisTy() == Andersen_BASE
112  || pta->getAnalysisTy() == Andersen_WPA
114  || pta->getAnalysisTy() == AndersenSCD_WPA
115  || pta->getAnalysisTy() == AndersenSFR_WPA
116  || pta->getAnalysisTy() == TypeCPP_WPA
117  || pta->getAnalysisTy() == Steensgaard_WPA);
118  }
120 
123  {
124  return consCG;
125  }
126 
128 
129  inline NodeID sccRepNode(NodeID id) const override
130  {
131  return consCG->sccRepNode(id);
132  }
133  inline NodeBS& sccSubNodes(NodeID repId)
134  {
135  return consCG->sccSubNodes(repId);
136  }
138 
140  virtual bool addCopyEdge(NodeID src, NodeID dst) = 0;
141 
143  inline void printStat()
144  {
146  }
147 
148  virtual void normalizePointsTo() override;
149 
151  void cleanConsCG(NodeID id);
152 
154 
156 
162  static u32_t numOfSfrs;
164 
166  static double timeOfSCCDetection;
167  static double timeOfSCCMerges;
168  static double timeOfCollapse;
171  static double timeOfProcessCopyGep;
172  static double timeOfProcessLoadStore;
173  static double timeOfUpdateCallGraph;
175 
176 protected:
183  void heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet& cpySrcNodes);
184 };
185 
189 class Andersen: public AndersenBase
190 {
191 
192 
193 public:
195 
197  Andersen(SVFIR* _pag, PTATY type = Andersen_WPA, bool alias_check = true)
198  : AndersenBase(_pag, type, alias_check)
199  {
200  }
201 
203  virtual ~Andersen()
204  {
205 
206  }
207 
209  virtual void initialize();
210 
212  virtual void finalize();
213 
215  inline void resetData()
216  {
218  MaxPointsToSetSize = 0;
221  }
222 
224 
225  static inline bool classof(const Andersen *)
226  {
227  return true;
228  }
229  static inline bool classof(const PointerAnalysis *pta)
230  {
231  return (pta->getAnalysisTy() == Andersen_WPA
233  || pta->getAnalysisTy() == AndersenSCD_WPA
234  || pta->getAnalysisTy() == AndersenSFR_WPA);
235  }
237 
239  virtual inline const PointsTo& getPts(NodeID id)
240  {
241  return getPTDataTy()->getPts(sccRepNode(id));
242  }
243  virtual inline bool unionPts(NodeID id, const PointsTo& target)
244  {
245  id = sccRepNode(id);
246  return getPTDataTy()->unionPts(id, target);
247  }
248  virtual inline bool unionPts(NodeID id, NodeID ptd)
249  {
250  id = sccRepNode(id);
251  ptd = sccRepNode(ptd);
252  return getPTDataTy()->unionPts(id,ptd);
253  }
254 
255 
256  void dumpTopLevelPtsTo();
257 
258  void setDetectPWC(bool flag)
259  {
261  }
262 
263 protected:
264 
266 
268  virtual inline void computeDiffPts(NodeID id)
269  {
270  if (Options::DiffPts())
271  {
272  NodeID rep = sccRepNode(id);
274  }
275  }
276  virtual inline const PointsTo& getDiffPts(NodeID id)
277  {
278  NodeID rep = sccRepNode(id);
279  if (Options::DiffPts())
280  return getDiffPTDataTy()->getDiffPts(rep);
281  else
282  return getPTDataTy()->getPts(rep);
283  }
284 
286  inline void updatePropaPts(NodeID dstId, NodeID srcId)
287  {
288  if (!Options::DiffPts())
289  return;
290  NodeID srcRep = sccRepNode(srcId);
291  NodeID dstRep = sccRepNode(dstId);
292  getDiffPTDataTy()->updatePropaPtsMap(srcRep, dstRep);
293  }
294  inline void clearPropaPts(NodeID src)
295  {
296  if (Options::DiffPts())
297  {
298  NodeID rep = sccRepNode(src);
300  }
301  }
302 
303  virtual void initWorklist() {}
304 
306  virtual void processNode(NodeID nodeId);
307 
309 
310  void processAllAddr();
311 
312  virtual bool processLoad(NodeID node, const ConstraintEdge* load);
313  virtual bool processStore(NodeID node, const ConstraintEdge* load);
314  virtual bool processCopy(NodeID node, const ConstraintEdge* edge);
315  virtual bool processGep(NodeID node, const GepCGEdge* edge);
316  virtual void handleCopyGep(ConstraintNode* node);
317  virtual void handleLoadStore(ConstraintNode* node);
318  virtual void processAddr(const AddrCGEdge* addr);
319  virtual bool processGepPts(const PointsTo& pts, const GepCGEdge* edge);
321 
323  virtual inline bool addCopyEdge(NodeID src, NodeID dst)
324  {
325  if (consCG->addCopyCGEdge(src, dst))
326  {
327  updatePropaPts(src, dst);
328  return true;
329  }
330  return false;
331  }
332 
334  virtual void mergeNodeToRep(NodeID nodeId,NodeID newRepId);
335 
336  virtual bool mergeSrcToTgt(NodeID srcId,NodeID tgtId);
337 
339 
340  void mergeSccNodes(NodeID repNodeId, const NodeBS& subNodes);
341  void mergeSccCycle();
343 
345  virtual void collapsePWCNode(NodeID nodeId);
346  void collapseFields();
347  bool collapseNodePts(NodeID nodeId);
348  bool collapseField(NodeID nodeId);
350 
352  void updateNodeRepAndSubs(NodeID nodeId,NodeID newRepId);
353 
355  virtual NodeStack& SCCDetect();
356 
357 
358 
360  void sanitizePts()
361  {
362  for(ConstraintGraph::iterator it = consCG->begin(), eit = consCG->end(); it!=eit; ++it)
363  {
364  const PointsTo& pts = getPts(it->first);
365  NodeBS fldInsenObjs;
366 
367  for (NodeID o : pts)
368  {
369  if(isFieldInsensitive(o))
370  fldInsenObjs.set(o);
371  }
372 
373  for (NodeID o : fldInsenObjs)
374  {
375  const NodeBS &allFields = consCG->getAllFieldsObjVars(o);
376  for (NodeID f : allFields) addPts(it->first, f);
377  }
378  }
379  }
380 
382  virtual const std::string PTAName() const
383  {
384  return "AndersenWPA";
385  }
386 
389  virtual void cluster(void) const;
390 };
391 
392 
393 
398 {
399 
400 private:
401 
402  static AndersenWaveDiff* diffWave; // static instance
403 
404 public:
405  AndersenWaveDiff(SVFIR* _pag, PTATY type = AndersenWaveDiff_WPA, bool alias_check = true): Andersen(_pag, type, alias_check) {}
406 
409  {
410  if(diffWave==nullptr)
411  {
412  diffWave = new AndersenWaveDiff(_pag, AndersenWaveDiff_WPA, false);
413  diffWave->analyze();
414  return diffWave;
415  }
416  return diffWave;
417  }
419  {
420  if (diffWave)
421  delete diffWave;
422  diffWave = nullptr;
423  }
424 
425  virtual void initialize();
426  virtual void solveWorklist();
427  virtual void processNode(NodeID nodeId);
428  virtual void postProcessNode(NodeID nodeId);
429  virtual bool handleLoad(NodeID id, const ConstraintEdge* load);
430  virtual bool handleStore(NodeID id, const ConstraintEdge* store);
431 };
432 
433 } // End namespace SVF
434 
435 #endif /* INCLUDE_WPA_ANDERSEN_H_ */
#define F(f)
newitem type
Definition: cJSON.cpp:2739
const char *const string
Definition: cJSON.h:172
void setValue(T v)
Definition: CommandLine.h:351
static bool classof(const PointerAnalysis *pta)
Definition: Andersen.h:109
static double timeOfSCCMerges
Definition: Andersen.h:167
static u32_t numOfProcessedCopy
Number of processed Addr edge.
Definition: Andersen.h:158
static u32_t numOfSCCDetection
Definition: Andersen.h:165
virtual void normalizePointsTo() override
static u32_t numOfSfrs
Number of processed Store edge.
Definition: Andersen.h:162
virtual void finalize() override
Finalize analysis.
Definition: Andersen.cpp:89
static double timeOfUpdateCallGraph
Definition: Andersen.h:173
static u32_t numOfProcessedStore
Number of processed Load edge.
Definition: Andersen.h:161
virtual void connectCaller2CalleeParams(const CallICFGNode *cs, const SVFFunction *F, NodePairSet &cpySrcNodes)
Connect formal and actual parameters for indirect callsites.
static u32_t numOfProcessedAddr
Statistics.
Definition: Andersen.h:157
virtual bool updateCallGraph(const CallSiteToFunPtrMap &) override
Update call graph.
Definition: Andersen.cpp:190
void printStat()
dump statistics
Definition: Andersen.h:143
void heapAllocatorViaIndCall(const CallICFGNode *cs, NodePairSet &cpySrcNodes)
CallSite2DummyValPN callsite2DummyValPN
Definition: Andersen.h:180
NodeBS & sccSubNodes(NodeID repId)
Definition: Andersen.h:133
virtual void readPtsFromFile(const std::string &filename)
Definition: Andersen.cpp:157
static u32_t numOfProcessedLoad
Number of processed Gep edge.
Definition: Andersen.h:160
static double timeOfSCCDetection
Definition: Andersen.h:166
NodeBS redundantGepNodes
Definition: Andersen.h:153
virtual bool addCopyEdge(NodeID src, NodeID dst)=0
Add copy edge on constraint graph.
virtual void initialize() override
Initialize analysis.
Definition: Andersen.cpp:73
~AndersenBase() override
Destructor.
Definition: Andersen.cpp:64
virtual void analyze() override
Andersen analysis.
Definition: Andersen.cpp:133
static u32_t numOfFieldExpand
Definition: Andersen.h:163
static double timeOfProcessLoadStore
Definition: Andersen.h:172
static u32_t numOfProcessedGep
Number of processed Copy edge.
Definition: Andersen.h:159
static double timeOfProcessCopyGep
Definition: Andersen.h:171
ConstraintGraph * getConstraintGraph()
Get constraint graph.
Definition: Andersen.h:122
OrderedMap< const CallICFGNode *, NodeID > CallSite2DummyValPN
Definition: Andersen.h:60
static u32_t MaxPointsToSetSize
Definition: Andersen.h:170
virtual void solveConstraints()
Definition: Andersen.cpp:100
virtual bool updateThreadCallGraph(const CallSiteToFunPtrMap &, NodePairSet &)
Update thread call graph.
Definition: Andersen.cpp:224
static double timeOfCollapse
Definition: Andersen.h:168
static u32_t AveragePointsToSetSize
Definition: Andersen.h:169
virtual void solveAndwritePtsToFile(const std::string &filename)
Definition: Andersen.cpp:168
ConstraintGraph * consCG
Constraint Graph.
Definition: Andersen.h:178
void cleanConsCG(NodeID id)
remove redundant gepnodes in constraint graph
Definition: Andersen.cpp:180
AndersenBase(SVFIR *_pag, PTATY type=Andersen_BASE, bool alias_check=true)
Constructor.
Definition: Andersen.h:65
static bool classof(const AndersenBase *)
Methods for support type inquiry through isa, cast, and dyn_cast:
Definition: Andersen.h:105
virtual void connectCaller2ForkedFunParams(const CallICFGNode *cs, const SVFFunction *F, NodePairSet &cpySrcNodes)
Connect formal and actual parameters for indirect forksites.
Definition: Andersen.cpp:244
NodeID sccRepNode(NodeID id) const override
SCC methods.
Definition: Andersen.h:129
virtual void solveWorklist()
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition: Andersen.h:408
static void releaseAndersenWaveDiff()
Definition: Andersen.h:418
AndersenWaveDiff(SVFIR *_pag, PTATY type=AndersenWaveDiff_WPA, bool alias_check=true)
Definition: Andersen.h:405
virtual bool handleStore(NodeID id, const ConstraintEdge *store)
virtual bool handleLoad(NodeID id, const ConstraintEdge *load)
virtual void postProcessNode(NodeID nodeId)
static AndersenWaveDiff * diffWave
Definition: Andersen.h:402
virtual void processNode(NodeID nodeId)
virtual void handleLoadStore(ConstraintNode *node)
Definition: Andersen.cpp:496
virtual const PointsTo & getDiffPts(NodeID id)
Definition: Andersen.h:276
void setDetectPWC(bool flag)
Definition: Andersen.h:258
virtual ~Andersen()
Destructor.
Definition: Andersen.h:203
virtual const PointsTo & getPts(NodeID id)
Operation of points-to set.
Definition: Andersen.h:239
void mergeSccNodes(NodeID repNodeId, const NodeBS &subNodes)
Merge sub node in a SCC cycle to their rep node.
Definition: Andersen.cpp:738
virtual void processNode(NodeID nodeId)
Override WPASolver function in order to use the default solver.
Definition: Andersen.cpp:455
virtual void initialize()
Initialize analysis.
Definition: Andersen.cpp:418
CallSite2DummyValPN callsite2DummyValPN
Map an instruction to a dummy obj which created at an indirect callsite, which invokes a heap allocat...
Definition: Andersen.h:265
void sanitizePts()
Sanitize pts for field insensitive objects.
Definition: Andersen.h:360
virtual NodeStack & SCCDetect()
SCC detection.
Definition: Andersen.cpp:834
virtual void mergeNodeToRep(NodeID nodeId, NodeID newRepId)
Merge sub node to its rep.
Definition: Andersen.cpp:889
bool collapseNodePts(NodeID nodeId)
Definition: Andersen.cpp:753
void dumpTopLevelPtsTo()
Definition: Andersen.cpp:939
void updatePropaPts(NodeID dstId, NodeID srcId)
Handle propagated points-to set.
Definition: Andersen.h:286
static bool classof(const PointerAnalysis *pta)
Definition: Andersen.h:229
Andersen(SVFIR *_pag, PTATY type=Andersen_WPA, bool alias_check=true)
Constructor.
Definition: Andersen.h:197
SCCDetection< ConstraintGraph * > CGSCC
Definition: Andersen.h:194
virtual void computeDiffPts(NodeID id)
Handle diff points-to set.
Definition: Andersen.h:268
void clearPropaPts(NodeID src)
Definition: Andersen.h:294
virtual bool addCopyEdge(NodeID src, NodeID dst)
Add copy edge on constraint graph.
Definition: Andersen.h:323
virtual bool unionPts(NodeID id, NodeID ptd)
Definition: Andersen.h:248
virtual void initWorklist()
Definition: Andersen.h:303
void resetData()
Reset data.
Definition: Andersen.h:215
virtual bool processGep(NodeID node, const GepCGEdge *edge)
Definition: Andersen.cpp:613
static bool classof(const Andersen *)
Methods for support type inquiry through isa, cast, and dyn_cast:
Definition: Andersen.h:225
virtual void handleCopyGep(ConstraintNode *node)
Definition: Andersen.cpp:476
virtual bool unionPts(NodeID id, const PointsTo &target)
Definition: Andersen.h:243
virtual bool processLoad(NodeID node, const ConstraintEdge *load)
Definition: Andersen.cpp:553
void collapseFields()
collapse positive weight cycles of a graph
Definition: Andersen.cpp:695
virtual bool processStore(NodeID node, const ConstraintEdge *load)
Definition: Andersen.cpp:573
virtual bool processCopy(NodeID node, const ConstraintEdge *edge)
Definition: Andersen.cpp:593
virtual bool processGepPts(const PointsTo &pts, const GepCGEdge *edge)
Definition: Andersen.cpp:622
void mergeSccCycle()
Definition: Andersen.cpp:710
virtual void processAddr(const AddrCGEdge *addr)
Definition: Andersen.cpp:538
void updateNodeRepAndSubs(NodeID nodeId, NodeID newRepId)
Updates subnodes of its rep, and rep node of its subs.
Definition: Andersen.cpp:899
virtual void finalize()
Finalize analysis.
Definition: Andersen.cpp:432
virtual const std::string PTAName() const
Get PTA name.
Definition: Andersen.h:382
void processAllAddr()
handling various constraints
Definition: Andersen.cpp:524
virtual void cluster(void) const
Definition: Andersen.cpp:917
virtual bool mergeSrcToTgt(NodeID srcId, NodeID tgtId)
Definition: Andersen.cpp:858
virtual void collapsePWCNode(NodeID nodeId)
Collapse a field object into its base for field insensitive analysis.
Definition: Andersen.cpp:686
bool collapseField(NodeID nodeId)
Definition: Andersen.cpp:773
DiffPTDataTy * getDiffPTDataTy() const
PTDataTy * getPTDataTy() const
Get points-to data structure.
virtual bool addPts(NodeID id, NodeID ptd)
NodeID sccRepNode(NodeID id) const
SCC rep/sub nodes methods.
Definition: ConsG.h:235
CopyCGEdge * addCopyCGEdge(NodeID src, NodeID dst)
Add Copy edge.
Definition: ConsG.cpp:222
NodeBS & sccSubNodes(NodeID id)
Definition: ConsG.h:243
NodeBS & getAllFieldsObjVars(NodeID id)
Definition: ConsG.h:316
virtual void updatePropaPtsMap(Key &src, Key &dst)=0
virtual bool computeDiffPts(Key &var, const DataSet &all)=0
virtual void clearPropaPts(Key &var)=0
Clear propagated points-to set of var.
virtual const DataSet & getDiffPts(Key &var)=0
Get diff points to.
iterator begin()
Iterators.
Definition: GenericGraph.h:627
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
static Option< bool > DetectPWC
Definition: Options.h:216
static const Option< bool > DiffPts
Definition: Options.h:215
virtual const DataSet & getPts(const Key &var)=0
Get points-to set of var.
virtual bool unionPts(const Key &dstVar, const Key &srcVar)=0
Performs pts(dstVar) = pts(dstVar) U pts(srcVar).
PTATY
Pointer analysis type list.
@ AndersenSCD_WPA
Selective cycle detection andersen-style WPA.
@ Andersen_BASE
Base Andersen PTA.
@ Andersen_WPA
Andersen PTA.
@ AndersenWaveDiff_WPA
Diff wave propagation andersen-style WPA.
@ TypeCPP_WPA
Type-based analysis for C++.
@ AndersenSFR_WPA
Stride-based field representation.
@ Steensgaard_WPA
Steensgaard PTA.
bool isFieldInsensitive(NodeID id) const
void dumpStat()
Dump the statistics.
PTATY getAnalysisTy() const
Type of pointer analysis.
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
u32_t OnTheFlyIterBudgetForStat
Flag for iteration budget for on-the-fly statistics.
void set(unsigned Idx)
u32_t iterationForPrintStat
print out statistics for i-th iteration
Definition: WPASolver.h:173
for isBitcode
Definition: BasicTypes.h:68
std::stack< NodeID > NodeStack
Definition: GeneralType.h:118
u32_t NodeID
Definition: GeneralType.h:55
Set< NodePair > NodePairSet
Definition: GeneralType.h:114
unsigned u32_t
Definition: GeneralType.h:46
WPASolver< ConstraintGraph * > WPAConstraintSolver
Definition: Andersen.h:50
std::map< Key, Value, Compare, Allocator > OrderedMap
Definition: GeneralType.h:109