Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVFGOPT.h
Go to the documentation of this file.
1//===- SVFGOPT.h -- SVFG optimizer--------------------------------------------//
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 * @file: SVFGOPT.h
25 * @author: yesen
26 * @date: 20/03/2014
27 * @version: 1.0
28 *
29 * @section LICENSE
30 *
31 * @section DESCRIPTION
32 *
33 */
34
35
36#ifndef SVFGOPT_H_
37#define SVFGOPT_H_
38
39
40#include "Graphs/SVFG.h"
41#include "Util/WorkList.h"
42
43namespace SVF
44{
45
56class SVFGOPT : public SVFG
57{
61
62public:
64 SVFGOPT(std::unique_ptr<MemSSA> mssa, VFGK kind) : SVFG(std::move(mssa), kind)
65 {
67 }
68
69 ~SVFGOPT() override = default;
70
72 {
74 }
76 {
77 keepAllSelfCycle = true;
78 }
80 {
82 }
83
85 void readAndOptSVFG(const std::string &filename);
86
88 void buildAndWriteSVFG(const std::string &filename);
89
90protected:
91 void buildSVFG() override;
92
94 void optimiseSVFG();
95
97
98 inline void connectAParamAndFParam(const ValVar* cs_arg, const ValVar* fun_arg, const CallICFGNode*, CallSiteID csId, SVFGEdgeSetTy& edges) override
99 {
100 NodeID phiId = getDef(fun_arg);
101 SVFGEdge* edge = addCallEdge(getDef(cs_arg), phiId, csId);
102 if (edge != nullptr)
103 {
105 addInterPHIOperands(phi, cs_arg);
106 edges.insert(edge);
107 }
108 }
109
110 inline void connectFRetAndARet(const ValVar* fun_ret, const ValVar* cs_ret, CallSiteID csId, SVFGEdgeSetTy& edges) override
111 {
112 NodeID phiId = getDef(cs_ret);
113 NodeID retdef = getDef(fun_ret);
117 if (pag->isPhiNode(fun_ret)==false)
118 return;
119
120 SVFGEdge* edge = addRetEdge(retdef, phiId, csId);
121 if (edge != nullptr)
122 {
124 addInterPHIOperands(phi, fun_ret);
125 edges.insert(edge);
126 }
127 }
128
129 inline void connectAInAndFIn(const ActualINSVFGNode* actualIn, const FormalINSVFGNode* formalIn, CallSiteID csId, SVFGEdgeSetTy& edges) override
130 {
131 NodeBS intersection = actualIn->getPointsTo();
132 intersection &= formalIn->getPointsTo();
133 if (intersection.empty() == false)
134 {
135 NodeID aiDef = getActualINDef(actualIn->getId());
136 SVFGEdge* edge = addCallIndirectSVFGEdge(aiDef,formalIn->getId(),csId,intersection);
137 if (edge != nullptr)
138 edges.insert(edge);
139 }
140 }
141
142 inline void connectFOutAndAOut(const FormalOUTSVFGNode* formalOut, const ActualOUTSVFGNode* actualOut, CallSiteID csId, SVFGEdgeSetTy& edges) override
143 {
144 NodeBS intersection = formalOut->getPointsTo();
145 intersection &= actualOut->getPointsTo();
146 if (intersection.empty() == false)
147 {
148 NodeID foDef = getFormalOUTDef(formalOut->getId());
149 SVFGEdge* edge = addRetIndirectSVFGEdge(foDef,actualOut->getId(),csId,intersection);
150 if (edge != nullptr)
151 edges.insert(edge);
152 }
153 }
154
155
157
158 inline NodeID getActualINDef(NodeID ai) const
159 {
160 NodeIDToNodeIDMap::const_iterator it = actualInToDefMap.find(ai);
161 assert(it != actualInToDefMap.end() && "can not find actual-in's def");
162 return it->second;
163 }
165 {
166 NodeIDToNodeIDMap::const_iterator it = formalOutToDefMap.find(fo);
167 assert(it != formalOutToDefMap.end() && "can not find formal-out's def");
168 return it->second;
169 }
170
171
172private:
174
176
177
178 SVFGEdge* addCallIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS& cpts);
180 SVFGEdge* addRetIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS& cpts);
182
192
194
195 void replaceFParamARetWithPHI(PHISVFGNode* phi, SVFGNode* svfgNode);
197
199
200
206
209
211 inline void initialWorkList()
212 {
213 for (SVFG::const_iterator it = begin(), eit = end(); it != eit; ++it)
214 addIntoWorklist(it->second);
215 }
216
220 inline bool addIntoWorklist(const SVFGNode* node)
221 {
223 {
224 if (isConnectingTwoCallSites(phi) == false && isDefOfAInFOut(phi) == false)
225 return worklist.push(phi);
226 }
227 return false;
228 }
229
231 void bypassMSSAPHINode(const MSSAPHISVFGNode* node);
232
234 bool checkSelfCycleEdges(const MSSAPHISVFGNode* node);
235
237 bool addNewSVFGEdge(NodeID srcId, NodeID dstId, const SVFGEdge* preEdge, const SVFGEdge* succEdge);
238
240 inline bool bothInterEdges(const SVFGEdge* edge1, const SVFGEdge* edge2) const
241 {
244 return (inter1 && inter2);
245 }
246
247 inline void addInterPHIOperands(PHISVFGNode* phi, const ValVar* operand)
248 {
249 phi->setOpVer(phi->getOpVerNum(), operand);
250 }
251
254 {
256 addSVFGNode(sNode, pag->getICFG()->getFunEntryICFGNode(fp->getFun()));
257 resetDef(fp->getParam(),sNode);
258 return sNode;
259 }
260
262 {
264 addSVFGNode(sNode, const_cast<RetICFGNode*>(
265 ar->getCallSite()->getRetICFGNode()));
266 resetDef(ar->getRev(),sNode);
267 return sNode;
268 }
269
270 inline void resetDef(const ValVar* valVar, const SVFGNode* node)
271 {
272 ValVarToDefMapTy::iterator it = ValVarToDefMap.find(valVar);
273 assert(it != ValVarToDefMap.end() && "a SVFIR node doesn't have definition before");
274 it->second = node->getId();
275 }
276
279 inline void setActualINDef(NodeID ai, NodeID def)
280 {
281 bool inserted = actualInToDefMap.emplace(ai, def).second;
282 (void)inserted; // Suppress warning of unused variable under release build
283 assert(inserted && "can not set actual-in's def twice");
284 defNodes.set(def);
285 }
286 inline void setFormalOUTDef(NodeID fo, NodeID def)
287 {
288 bool inserted = formalOutToDefMap.emplace(fo, def).second;
289 (void) inserted;
290 assert(inserted && "can not set formal-out's def twice");
291 defNodes.set(def);
292 }
293
294
295 inline bool isDefOfAInFOut(const SVFGNode* node)
296 {
297 return defNodes.test(node->getId());
298 }
299
301
302 inline bool actualInOfIndCS(const ActualINSVFGNode* ai) const
303 {
304 return (SVFIR::getPAG()->isIndirectCallSites(ai->getCallSite()));
305 }
306 inline bool actualOutOfIndCS(const ActualOUTSVFGNode* ao) const
307 {
308 return (SVFIR::getPAG()->isIndirectCallSites(ao->getCallSite()));
309 }
310
311
313
314 inline bool formalInOfAddressTakenFunc(const FormalINSVFGNode* fi) const
315 {
316 return (fi->getFun()->hasAddressTaken());
317 }
319 {
320 return (fo->getFun()->hasAddressTaken());
321 }
322
323
325 bool isConnectingTwoCallSites(const SVFGNode* node) const;
326
336 bool canBeRemoved(const SVFGNode * node);
337
339
340 inline void removeAllEdges(const SVFGNode* node)
341 {
342 removeInEdges(node);
343 removeOutEdges(node);
344 }
345 inline void removeInEdges(const SVFGNode* node)
346 {
348 while (node->hasIncomingEdge())
349 removeSVFGEdge(*(node->InEdgeBegin()));
350 }
351 inline void removeOutEdges(const SVFGNode* node)
352 {
353 while (node->hasOutgoingEdge())
354 removeSVFGEdge(*(node->OutEdgeBegin()));
355 }
356
357
358
362
364
368};
369
370} // End namespace SVF
371
372#endif /* SVFGOPT_H_ */
const CallICFGNode * getCallSite() const
Callsite.
Definition SVFGNode.h:182
const CallICFGNode * getCallSite() const
Callsite.
Definition SVFGNode.h:232
const CallICFGNode * getCallSite() const
Return callsite.
Definition VFGNode.h:1111
const ValVar * getRev() const
Receive parameter at callsite.
Definition VFGNode.h:1121
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:440
const ValVar * getParam() const
Return parameter.
Definition VFGNode.h:1041
const FunObjVar * getFun() const override
Return function.
Definition VFGNode.h:1047
bool hasAddressTaken() const
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
iterator OutEdgeBegin()
iterators
iterator InEdgeBegin()
const NodeBS & getPointsTo() const
Return points-to of the MR.
Definition SVFGNode.h:52
u32_t getOpVerNum() const
Definition VFGNode.h:769
void setOpVer(u32_t pos, const ValVar *node)
Definition VFGNode.h:761
Set< SVFGNode * > SVFGNodeSet
Definition SVFGOPT.h:58
bool isDefOfAInFOut(const SVFGNode *node)
Definition SVFGOPT.h:295
SVFGEdge * addCallIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS &cpts)
Add inter-procedural value flow edge.
Definition SVFGOPT.cpp:88
void buildAndWriteSVFG(const std::string &filename)
Optimised SVFG's shouldn't be written in their optimised form; writes the full SVFG to file before op...
Definition SVFGOPT.cpp:54
void replaceFParamARetWithPHI(PHISVFGNode *phi, SVFGNode *svfgNode)
Replace FormalParam/ActualRet node with PHI node.
Definition SVFGOPT.cpp:171
void handleIntraValueFlow()
Remove MSSAPHI SVFG nodes.
Definition SVFGOPT.cpp:411
void retargetEdgesOfAOutFIn(SVFGNode *node)
Connect actual-out/formal-in's predecessors to their successors directly.
Definition SVFGOPT.cpp:270
void setFormalOUTDef(NodeID fo, NodeID def)
Definition SVFGOPT.h:286
FIFOWorkList< const MSSAPHISVFGNode * > WorkList
Definition SVFGOPT.h:60
void setActualINDef(NodeID ai, NodeID def)
Definition SVFGOPT.h:279
void handleInterValueFlow()
Definition SVFGOPT.cpp:110
void bypassMSSAPHINode(const MSSAPHISVFGNode *node)
Remove MSSAPHI node if possible.
Definition SVFGOPT.cpp:500
void resetDef(const ValVar *valVar, const SVFGNode *node)
Definition SVFGOPT.h:270
NodeID getActualINDef(NodeID ai) const
Get def-site of actual-in/formal-out.
Definition SVFGOPT.h:158
Map< NodeID, NodeID > NodeIDToNodeIDMap
Definition SVFGOPT.h:59
void removeInEdges(const SVFGNode *node)
Definition SVFGOPT.h:345
void connectAInAndFIn(const ActualINSVFGNode *actualIn, const FormalINSVFGNode *formalIn, CallSiteID csId, SVFGEdgeSetTy &edges) override
Connect actual-in and formal-in.
Definition SVFGOPT.h:129
SVFGOPT(std::unique_ptr< MemSSA > mssa, VFGK kind)
Constructor.
Definition SVFGOPT.h:64
bool keepAllSelfCycle
Definition SVFGOPT.h:366
bool addNewSVFGEdge(NodeID srcId, NodeID dstId, const SVFGEdge *preEdge, const SVFGEdge *succEdge)
Add new SVFG edge from src to dst.
Definition SVFGOPT.cpp:543
bool bothInterEdges(const SVFGEdge *edge1, const SVFGEdge *edge2) const
Return TRUE if both edges are indirect call/ret edges.
Definition SVFGOPT.h:240
bool formalInOfAddressTakenFunc(const FormalINSVFGNode *fi) const
Check if formal-in/formal-out reside in address-taken function.
Definition SVFGOPT.h:314
bool addIntoWorklist(const SVFGNode *node)
Definition SVFGOPT.h:220
void buildSVFG() override
Start building SVFG.
Definition SVFGOPT.cpp:61
bool actualOutOfIndCS(const ActualOUTSVFGNode *ao) const
Definition SVFGOPT.h:306
bool keepActualOutFormalIn
Definition SVFGOPT.h:365
InterPHISVFGNode * addInterPHIForAR(const ActualRetSVFGNode *ar)
Add inter PHI SVFG node for actual return.
Definition SVFGOPT.h:261
void connectAParamAndFParam(const ValVar *cs_arg, const ValVar *fun_arg, const CallICFGNode *, CallSiteID csId, SVFGEdgeSetTy &edges) override
Connect SVFG nodes between caller and callee for indirect call sites.
Definition SVFGOPT.h:98
bool formalOutOfAddressTakenFunc(const FormalOUTSVFGNode *fo) const
Definition SVFGOPT.h:318
NodeID getFormalOUTDef(NodeID fo) const
Definition SVFGOPT.h:164
WorkList worklist
storing MSSAPHI nodes which may be removed.
Definition SVFGOPT.h:363
NodeIDToNodeIDMap actualInToDefMap
map actual-in to its def-site node
Definition SVFGOPT.h:359
void setTokeepAllSelfCycle()
Definition SVFGOPT.h:75
InterPHISVFGNode * addInterPHIForFP(const FormalParmSVFGNode *fp)
Add inter PHI SVFG node for formal parameter.
Definition SVFGOPT.h:253
bool isConnectingTwoCallSites(const SVFGNode *node) const
Return TRUE if this node has both incoming call/ret and outgoing call/ret edges.
Definition SVFGOPT.cpp:312
void readAndOptSVFG(const std::string &filename)
Optimised SVFG's aren't written in their optimised form; read full SVFG and optimise it.
Definition SVFGOPT.cpp:47
void connectFRetAndARet(const ValVar *fun_ret, const ValVar *cs_ret, CallSiteID csId, SVFGEdgeSetTy &edges) override
Connect formal-ret and actual ret.
Definition SVFGOPT.h:110
bool canBeRemoved(const SVFGNode *node)
Definition SVFGOPT.cpp:354
NodeIDToNodeIDMap formalOutToDefMap
map formal-out to its def-site node
Definition SVFGOPT.h:360
NodeBS defNodes
preserved def nodes of formal-in/actual-out
Definition SVFGOPT.h:361
void setTokeepContextSelfCycle()
Definition SVFGOPT.h:79
void retargetEdgesOfAInFOut(SVFGNode *node)
Retarget edges related to actual-in/-out and formal-in/-out.
Definition SVFGOPT.cpp:224
void removeAllEdges(const SVFGNode *node)
Remove edges of a SVFG node.
Definition SVFGOPT.h:340
void addInterPHIOperands(PHISVFGNode *phi, const ValVar *operand)
Definition SVFGOPT.h:247
void parseSelfCycleHandleOption()
Definition SVFGOPT.cpp:392
bool keepContextSelfCycle
Definition SVFGOPT.h:367
~SVFGOPT() override=default
Destructor.
void connectFOutAndAOut(const FormalOUTSVFGNode *formalOut, const ActualOUTSVFGNode *actualOut, CallSiteID csId, SVFGEdgeSetTy &edges) override
Connect formal-out and actual-out.
Definition SVFGOPT.h:142
void optimiseSVFG()
Separate optimisation function to avoid duplicate code.
Definition SVFGOPT.cpp:68
void initialWorkList()
Initial work list with MSSAPHI nodes which may be removed.
Definition SVFGOPT.h:211
void removeOutEdges(const SVFGNode *node)
Definition SVFGOPT.h:351
void setTokeepActualOutFormalIn()
Definition SVFGOPT.h:71
bool actualInOfIndCS(const ActualINSVFGNode *ai) const
Check if actual-in/actual-out exist at indirect call site.
Definition SVFGOPT.h:302
SVFGEdge * addRetIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS &cpts)
Add indirect ret edge from src to dst with one call site ID.
Definition SVFGOPT.cpp:99
bool checkSelfCycleEdges(const MSSAPHISVFGNode *node)
Remove self cycle edges if needed. Return TRUE if some self cycle edges remained.
Definition SVFGOPT.cpp:462
SVFG(std::unique_ptr< MemSSA > mssa, VFGK k)
Constructor.
Definition SVFG.cpp:204
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition SVFG.h:150
virtual void addSVFGNode(SVFGNode *node, ICFGNode *icfgNode)
Add SVFG node.
Definition SVFG.h:413
void removeSVFGEdge(SVFGEdge *edge)
Remove a SVFG edge.
Definition SVFG.h:254
NodeID getDef(const ValVar *valVar) const
Definition SVFG.h:372
std::unique_ptr< MemSSA > mssa
Definition SVFG.h:106
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:121
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual const FunObjVar * getFun() const
Get the function of this SVFGNode.
Definition VFGNode.h:79
VFGNodeIDToNodeMapTy::const_iterator const_iterator
Definition VFG.h:81
SVFIR * pag
Definition VFG.h:104
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:689
VFGK kind
Definition VFG.h:105
ValVarToDefMapTy ValVarToDefMap
map a pag node to its definition SVG node
Definition VFG.h:89
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:669
VFGK
VFG kind.
Definition VFG.h:56
VFGEdge::SVFGEdgeSetTy SVFGEdgeSetTy
Definition VFG.h:78
NodeID totalVFGNode
Definition VFG.h:88
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
Definition Casting.h:360
LLVM_NODISCARD bool isa(const Y &Val)
Definition Casting.h:241
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition Casting.h:405
for isBitcode
Definition BasicTypes.h:70
unsigned CallSiteID
Definition GeneralType.h:78
InterPHIVFGNode InterPHISVFGNode
Definition SVFG.h:58
u32_t NodeID
Definition GeneralType.h:76
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition GeneralType.h:51
VFGNode SVFGNode
Definition SVFG.h:43
PHIVFGNode PHISVFGNode
Definition SVFG.h:56
ActualRetVFGNode ActualRetSVFGNode
Definition SVFG.h:45
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition GeneralType.h:56
VFGEdge SVFGEdge
Definition SVFG.h:42
SparseBitVector NodeBS
Definition GeneralType.h:82
FormalParmVFGNode FormalParmSVFGNode
Definition SVFG.h:46