Static Value-Flow Analysis
FlowSensitive.h
Go to the documentation of this file.
1 //===- FlowSensitive.h -- Flow-sensitive 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  * FlowSensitiveAnalysis.h
25  *
26  * Created on: Oct 28, 2013
27  * Author: Yulei Sui
28  */
29 
30 #ifndef FLOWSENSITIVEANALYSIS_H_
31 #define FLOWSENSITIVEANALYSIS_H_
32 
34 #include "Graphs/SVFGOPT.h"
36 #include "MSSA/SVFGBuilder.h"
37 #include "WPA/WPAFSSolver.h"
38 
39 namespace SVF
40 {
41 
42 class AndersenWaveDiff;
43 class SVFModule;
44 
50 {
51  friend class FlowSensitiveStat;
52 protected:
54 
55 public:
59 
62  {
63  svfg = nullptr;
73  }
74 
76  ~FlowSensitive() override = default;
77 
80  {
81  if (fspta == nullptr)
82  {
83  fspta = std::unique_ptr<FlowSensitive>(new FlowSensitive(_pag));
84  fspta->analyze();
85  }
86  return fspta.get();
87  }
88 
90  static void releaseFSWPA()
91  {
92  fspta = nullptr;
93  }
94 
96  virtual bool runOnModule(SVFModule*)
97  {
98  return false;
99  }
100 
102  void analyze() override;
103 
104  virtual void solveAndwritePtsToFile(const std::string& filename);
105 
106  virtual void readPtsFromFile(const std::string& filename);
107 
108  virtual void solveConstraints();
109 
111  void initialize() override;
112 
114  void finalize() override;
115 
117  const std::string PTAName() const override
118  {
119  return "FlowSensitive";
120  }
121 
123 
124  static inline bool classof(const FlowSensitive *)
125  {
126  return true;
127  }
128  static inline bool classof(const PointerAnalysis *pta)
129  {
130  return pta->getAnalysisTy() == FSSPARSE_WPA;
131  }
133 
135  inline SVFG* getSVFG() const
136  {
137  return svfg;
138  }
139 
140 protected:
142  NodeStack& SCCDetect() override;
143 
145 
146  bool propFromSrcToDst(SVFGEdge* edge) override;
149  virtual bool propAlongDirectEdge(const DirectSVFGEdge* edge);
151  virtual bool propAlongIndirectEdge(const IndirectSVFGEdge* edge);
153  virtual bool propVarPtsFromSrcToDst(NodeID var, const SVFGNode* src, const SVFGNode* dst);
156  virtual bool propagateFromAPToFP(const ActualParmSVFGNode* ap, const SVFGNode* dst);
159  virtual bool propagateFromFRToAR(const FormalRetSVFGNode* fr, const SVFGNode* dst);
161  virtual bool weakUpdateOutFromIn(const SVFGNode* node)
162  {
163  return getDFPTDataTy()->updateAllDFOutFromIn(node->getId(),0,false);
164  }
166  virtual bool strongUpdateOutFromIn(const SVFGNode* node, NodeID singleton)
167  {
168  return getDFPTDataTy()->updateAllDFOutFromIn(node->getId(),singleton,true);
169  }
171 
174 
175  bool propVarPtsAfterCGUpdated(NodeID var, const SVFGNode* src, const SVFGNode* dst);
176 
177  virtual inline bool propDFOutToIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar)
178  {
179  return getDFPTDataTy()->updateAllDFInFromOut(srcStmt->getId(), srcVar, dstStmt->getId(),dstVar);
180  }
181  virtual inline bool propDFInToIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar)
182  {
183  return getDFPTDataTy()->updateAllDFInFromIn(srcStmt->getId(), srcVar, dstStmt->getId(),dstVar);
184  }
186 
188 
189  inline bool updateOutFromIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar)
190  {
191  return getDFPTDataTy()->updateDFOutFromIn(srcStmt->getId(),srcVar, dstStmt->getId(),dstVar);
192  }
193  virtual inline bool updateInFromIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar)
194  {
195  return getDFPTDataTy()->updateDFInFromIn(srcStmt->getId(),srcVar, dstStmt->getId(),dstVar);
196  }
197  virtual inline bool updateInFromOut(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar)
198  {
199  return getDFPTDataTy()->updateDFInFromOut(srcStmt->getId(),srcVar, dstStmt->getId(),dstVar);
200  }
201 
202  virtual inline bool unionPtsFromIn(const SVFGNode* stmt, NodeID srcVar, NodeID dstVar)
203  {
204  return getDFPTDataTy()->updateTLVPts(stmt->getId(),srcVar,dstVar);
205  }
206  virtual inline bool unionPtsFromTop(const SVFGNode* stmt, NodeID srcVar, NodeID dstVar)
207  {
208  return getDFPTDataTy()->updateATVPts(srcVar,stmt->getId(),dstVar);
209  }
210 
211  inline void clearAllDFOutVarFlag(const SVFGNode* stmt)
212  {
214  }
216 
218 
219  void processNode(NodeID nodeId) override;
220  bool processSVFGNode(SVFGNode* node);
221  virtual bool processAddr(const AddrSVFGNode* addr);
222  virtual bool processCopy(const CopySVFGNode* copy);
223  virtual bool processPhi(const PHISVFGNode* phi);
224  virtual bool processGep(const GepSVFGNode* edge);
225  virtual bool processLoad(const LoadSVFGNode* load);
226  virtual bool processStore(const StoreSVFGNode* store);
228 
230 
231  bool updateCallGraph(const CallSiteToFunPtrMap& callsites) override;
234  void connectCallerAndCallee(const CallEdgeMap& newEdges, SVFGEdgeSetTy& edges);
236  virtual void updateConnectedNodes(const SVFGEdgeSetTy& edges);
238 
240  bool isStrongUpdate(const SVFGNode* node, NodeID& singleton);
241 
243  virtual void countAliases(Set<std::pair<NodeID, NodeID>> cmp, unsigned *mayAliases, unsigned *noAliases);
244 
247 
248  inline const PointsTo& getDFInPtsSet(const SVFGNode* stmt, const NodeID node)
249  {
250  return getDFPTDataTy()->getDFInPtsSet(stmt->getId(),node);
251  }
252  inline const PointsTo& getDFOutPtsSet(const SVFGNode* stmt, const NodeID node)
253  {
254  return getDFPTDataTy()->getDFOutPtsSet(stmt->getId(),node);
255  }
257 
261  inline const DFInOutMap& getDFInputMap() const
262  {
263  return getMutDFPTDataTy()->getDFIn();
264  }
265  inline const DFInOutMap& getDFOutputMap() const
266  {
267  return getMutDFPTDataTy()->getDFOut();
268  }
270 
273  virtual void cluster(void);
275  virtual void plainMap(void) const;
276 
277  static std::unique_ptr<FlowSensitive> fspta;
280 
282  std::vector<std::pair<hclust_fast_methods, std::vector<NodeID>>> candidateMappings;
283 
285 
295 
299 
300  double solveTime;
301  double sccTime;
302  double processTime;
306  double updateTime;
307  double addrTime;
308  double copyTime;
309  double gepTime;
310  double loadTime;
311  double storeTime;
312  double phiTime;
314 
317 
318  void svfgStat();
319 };
320 
321 } // End namespace SVF
322 
323 #endif /* FLOWSENSITIVEANALYSIS_H_ */
newitem type
Definition: cJSON.cpp:2739
copy
Definition: cJSON.cpp:414
const char *const string
Definition: cJSON.h:172
DFPTDataTy * getDFPTDataTy() const
MutDFPTDataTy * getMutDFPTDataTy() const
virtual bool updateATVPts(const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Update address-taken variables OUT[dstLoc:dstVar] with points-to of top-level pointers.
virtual const DataSet & getDFInPtsSet(LocID loc, const Key &var)=0
virtual bool updateDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Union (IN[dstLoc:dstVar], OUT[srcLoc:srcVar]).
virtual bool updateAllDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Union (IN[dstLoc::dstVar], IN[srcLoc:srcVar]. There is no flag check, unlike the above.
virtual bool updateAllDFOutFromIn(LocID loc, const Key &singleton, bool strongUpdates)=0
For each variable var in IN at loc, do updateDFOutFromIn(loc, var, loc, var).
virtual bool updateDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
virtual bool updateAllDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Union (IN[dstLoc::dstVar], OUT[srcLoc:srcVar]. There is no flag check, unlike the above.
virtual bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar)=0
Update points-to set of top-level pointers with IN[srcLoc:srcVar].
virtual void clearAllDFOutUpdatedVar(LocID)=0
virtual bool updateDFOutFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Union (OUT[dstLoc:dstVar], IN[srcLoc:srcVar]).
virtual const DataSet & getDFOutPtsSet(LocID loc, const Key &var)=0
BVDataPTAImpl::MutDFPTDataTy MutDFPTDataTy
Definition: FlowSensitive.h:56
bool updateOutFromIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
Update data-flow points-to data.
~FlowSensitive() override=default
Destructor.
void processNode(NodeID nodeId) override
Handle various constraints.
u32_t numOfProcessedLoad
Number of processed Phi node.
static bool classof(const PointerAnalysis *pta)
virtual void solveConstraints()
virtual bool unionPtsFromIn(const SVFGNode *stmt, NodeID srcVar, NodeID dstVar)
virtual void updateConnectedNodes(const SVFGEdgeSetTy &edges)
Update nodes connected during updating call graph.
u32_t numOfProcessedCopy
Number of processed Addr node.
double gepTime
time of handling gep edges
static std::unique_ptr< FlowSensitive > fspta
double indirectPropaTime
time of points-to propagation of top-level pointers
virtual bool propagateFromAPToFP(const ActualParmSVFGNode *ap, const SVFGNode *dst)
double addrTime
time of handling address edges
virtual bool propagateFromFRToAR(const FormalRetSVFGNode *fr, const SVFGNode *dst)
virtual bool propDFInToIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
NodeStack & SCCDetect() override
SCC detection.
double solveTime
time of solve.
bool isStrongUpdate(const SVFGNode *node, NodeID &singleton)
Return TRUE if this is a strong update STORE statement.
virtual void readPtsFromFile(const std::string &filename)
virtual bool unionPtsFromTop(const SVFGNode *stmt, NodeID srcVar, NodeID dstVar)
virtual void plainMap(void) const
Sets the global best mapping as a plain mapping, i.e. n -> n.
AndersenWaveDiff * ander
virtual bool propDFOutToIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
virtual bool runOnModule(SVFModule *)
We start from here.
Definition: FlowSensitive.h:96
const DFInOutMap & getDFOutputMap() const
u32_t numOfProcessedStore
Number of processed Load node.
SVFG::SVFGEdgeSetTy SVFGEdgeSetTy
Definition: FlowSensitive.h:53
SVFG * getSVFG() const
Return SVFG.
SVFGBuilder memSSA
void analyze() override
Flow sensitive analysis.
BVDataPTAImpl::MutDFPTDataTy::PtsMap PtsMap
Definition: FlowSensitive.h:58
const PointsTo & getDFOutPtsSet(const SVFGNode *stmt, const NodeID node)
double storeTime
time of store edges
virtual bool updateInFromIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
double copyTime
time of handling copy edges
bool propFromSrcToDst(SVFGEdge *edge) override
Propagation.
u32_t numOfProcessedGep
Number of processed Copy node.
virtual void cluster(void)
virtual bool strongUpdateOutFromIn(const SVFGNode *node, NodeID singleton)
Handle strong updates.
void finalize() override
Finalize analysis.
const PointsTo & getDFInPtsSet(const SVFGNode *stmt, const NodeID node)
Get points-to set for a node from data flow IN/OUT set at a statement.
virtual void countAliases(Set< std::pair< NodeID, NodeID >> cmp, unsigned *mayAliases, unsigned *noAliases)
Fills may/noAliases for the location/pointer pairs in cmp.
void clearAllDFOutVarFlag(const SVFGNode *stmt)
const DFInOutMap & getDFInputMap() const
bool processSVFGNode(SVFGNode *node)
virtual bool processLoad(const LoadSVFGNode *load)
bool propVarPtsAfterCGUpdated(NodeID var, const SVFGNode *src, const SVFGNode *dst)
virtual bool processPhi(const PHISVFGNode *phi)
virtual bool processStore(const StoreSVFGNode *store)
u32_t maxSCCSize
Number of processed mssa node.
virtual bool processCopy(const CopySVFGNode *copy)
double loadTime
time of load edges
FlowSensitive(SVFIR *_pag, PTATY type=FSSPARSE_WPA)
Constructor.
Definition: FlowSensitive.h:61
bool updateCallGraph(const CallSiteToFunPtrMap &callsites) override
Update call graph.
virtual bool weakUpdateOutFromIn(const SVFGNode *node)
Handle weak updates.
virtual bool processAddr(const AddrSVFGNode *addr)
u32_t numOfProcessedActualParam
Number of processed Store node.
u32_t numOfProcessedPhi
Number of processed Gep node.
double propagationTime
time of points-to propagation.
const std::string PTAName() const override
Get PTA name.
static bool classof(const FlowSensitive *)
Methods for support type inquiry through isa, cast, and dyn_cast.
virtual bool propAlongDirectEdge(const DirectSVFGEdge *edge)
Propagate points-to information along a DIRECT SVFG edge.
void initialize() override
Initialize analysis.
void connectCallerAndCallee(const CallEdgeMap &newEdges, SVFGEdgeSetTy &edges)
Connect nodes in SVFG.
std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > candidateMappings
Save candidate mappings for evaluation's sake.
virtual bool processGep(const GepSVFGNode *edge)
u32_t numOfProcessedFormalRet
Number of processed actual param node.
double directPropaTime
time of points-to propagation of address-taken objects
double processTime
time of processNode.
u32_t numOfProcessedAddr
Statistics.
virtual bool propVarPtsFromSrcToDst(NodeID var, const SVFGNode *src, const SVFGNode *dst)
Propagate points-to information of a certain variable from src to dst.
static void releaseFSWPA()
Release flow-sensitive pointer analysis.
Definition: FlowSensitive.h:90
virtual bool propAlongIndirectEdge(const IndirectSVFGEdge *edge)
Propagate points-to information along an INDIRECT SVFG edge.
double phiTime
time of phi nodes.
static FlowSensitive * createFSWPA(SVFIR *_pag)
Create single instance of flow-sensitive pointer analysis.
Definition: FlowSensitive.h:79
double sccTime
time of SCC detection.
double updateTime
time of strong/weak updates.
virtual bool updateInFromOut(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
u32_t numOfProcessedMSSANode
Number of processed formal ret node.
BVDataPTAImpl::MutDFPTDataTy::DFPtsMap DFInOutMap
Definition: FlowSensitive.h:57
virtual void solveAndwritePtsToFile(const std::string &filename)
double updateCallGraphTime
time of updating call graph
Map< LocID, PtsMap > DFPtsMap
Data-flow point-to map.
const DFPtsMap & getDFOut()
BaseMutPTData::PtsMap PtsMap
const DFPtsMap & getDFIn()
PTATY
Pointer analysis type list.
@ FSSPARSE_WPA
Sparse flow sensitive WPA.
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
PTATY getAnalysisTy() const
Type of pointer analysis.
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
u32_t OnTheFlyIterBudgetForStat
Flag for iteration budget for on-the-fly statistics.
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
Definition: SVFG.h:66
VFGEdge::SVFGEdgeSetTy SVFGEdgeSetTy
Definition: VFG.h:78
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
WPAFSSolver< SVFG * > WPASVFGFSSolver
Definition: FlowSensitive.h:43
u32_t NodeID
Definition: GeneralType.h:55
unsigned u32_t
Definition: GeneralType.h:46
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96