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 }
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 PAGNode* cs_arg, const PAGNode* fun_arg, const CallICFGNode*, CallSiteID csId, SVFGEdgeSetTy& edges) override
99 {
102 if (edge != nullptr)
103 {
104 PHISVFGNode* phi = SVFUtil::cast<PHISVFGNode>(getSVFGNode(phiId));
106 edges.insert(edge);
107 }
108 }
110 inline void connectFRetAndARet(const PAGNode* fun_ret, const PAGNode* cs_ret, CallSiteID csId, SVFGEdgeSetTy& edges) override
111 {
117 if (pag->isPhiNode(fun_ret)==false)
118 return;
119
121 if (edge != nullptr)
122 {
123 PHISVFGNode* phi = SVFUtil::cast<PHISVFGNode>(getSVFGNode(phiId));
125 edges.insert(edge);
126 }
127 }
130 {
131 NodeBS intersection = actualIn->getPointsTo();
132 intersection &= formalIn->getPointsTo();
133 if (intersection.empty() == false)
134 {
137 if (edge != nullptr)
138 edges.insert(edge);
139 }
140 }
143 {
144 NodeBS intersection = formalOut->getPointsTo();
145 intersection &= actualOut->getPointsTo();
146 if (intersection.empty() == false)
147 {
150 if (edge != nullptr)
151 edges.insert(edge);
152 }
153 }
155
157
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 }
171
172private:
174
176
177
182
192
194
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 {
222 if (const MSSAPHISVFGNode* phi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
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
238
240 inline bool bothInterEdges(const SVFGEdge* edge1, const SVFGEdge* edge2) const
241 {
242 bool inter1 = SVFUtil::isa<CallIndSVFGEdge, RetIndSVFGEdge>(edge1);
243 bool inter2 = SVFUtil::isa<CallIndSVFGEdge, RetIndSVFGEdge>(edge2);
244 return (inter1 && inter2);
245 }
246
248 {
249 phi->setOpVer(phi->getOpVerNum(), operand);
250 }
251
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 PAGNode* pagNode, const SVFGNode* node)
271 {
272 PAGNodeToDefMapTy::iterator it = PAGNodeToDefMap.find(pagNode);
273 assert(it != PAGNodeToDefMap.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 }
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 }
311
313
315 {
316 return (fi->getFun()->hasAddressTaken());
317 }
319 {
320 return (fo->getFun()->hasAddressTaken());
321 }
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 }
357
358
362
364
368};
369
370} // End namespace SVF
371
372#endif /* SVFGOPT_H_ */
bool push(const Data &data)
Definition WorkList.h:165
iterator begin()
Iterators.
IDToNodeMapTy::const_iterator const_iterator
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
iterator OutEdgeBegin()
iterators
iterator InEdgeBegin()
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Definition ICFG.cpp:242
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 addInterPHIOperands(PHISVFGNode *phi, const PAGNode *operand)
Definition SVFGOPT.h:247
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
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 PAGNode *cs_arg, const PAGNode *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
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 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 connectFRetAndARet(const PAGNode *fun_ret, const PAGNode *cs_ret, CallSiteID csId, SVFGEdgeSetTy &edges) override
Connect formal-ret and actual ret.
Definition SVFGOPT.h:110
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
void resetDef(const PAGNode *pagNode, const SVFGNode *node)
Definition SVFGOPT.h:270
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
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:397
void removeSVFGEdge(SVFGEdge *edge)
Remove a SVFG edge.
Definition SVFG.h:238
std::unique_ptr< MemSSA > mssa
Definition SVFG.h:106
NodeID getDef(const PAGNode *pagNode) const
Definition SVFG.h:356
bool isPhiNode(const SVFVar *node) const
Whether this SVFVar is a result operand a of phi node.
Definition SVFIR.h:287
ICFG * getICFG() const
Definition SVFIR.h:163
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:116
NodeID getId() const
Get ID.
Definition SVFValue.h:158
bool test(unsigned Idx) const
void set(unsigned Idx)
SVFIR * pag
Definition VFG.h:104
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:705
VFGK kind
Definition VFG.h:105
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:685
VFGK
VFG kind.
Definition VFG.h:56
PAGNodeToDefMapTy PAGNodeToDefMap
map a pag node to its definition SVG node
Definition VFG.h:89
VFGEdge::SVFGEdgeSetTy SVFGEdgeSetTy
Definition VFG.h:78
NodeID totalVFGNode
Definition VFG.h:88
for isBitcode
Definition BasicTypes.h:68
unsigned CallSiteID
Definition GeneralType.h:58
InterPHIVFGNode InterPHISVFGNode
Definition SVFG.h:58
u32_t NodeID
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74