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
84protected:
85 void buildSVFG() override;
86
88
89 inline void connectAParamAndFParam(const PAGNode* cs_arg, const PAGNode* fun_arg, const CallICFGNode*, CallSiteID csId, SVFGEdgeSetTy& edges) override
90 {
93 if (edge != nullptr)
94 {
95 PHISVFGNode* phi = SVFUtil::cast<PHISVFGNode>(getSVFGNode(phiId));
97 edges.insert(edge);
98 }
99 }
101 inline void connectFRetAndARet(const PAGNode* fun_ret, const PAGNode* cs_ret, CallSiteID csId, SVFGEdgeSetTy& edges) override
102 {
108 if (pag->isPhiNode(fun_ret)==false)
109 return;
110
112 if (edge != nullptr)
113 {
114 PHISVFGNode* phi = SVFUtil::cast<PHISVFGNode>(getSVFGNode(phiId));
116 edges.insert(edge);
117 }
118 }
121 {
122 NodeBS intersection = actualIn->getPointsTo();
123 intersection &= formalIn->getPointsTo();
124 if (intersection.empty() == false)
125 {
128 if (edge != nullptr)
129 edges.insert(edge);
130 }
131 }
134 {
135 NodeBS intersection = formalOut->getPointsTo();
136 intersection &= actualOut->getPointsTo();
137 if (intersection.empty() == false)
138 {
141 if (edge != nullptr)
142 edges.insert(edge);
143 }
144 }
146
148
150 {
151 NodeIDToNodeIDMap::const_iterator it = actualInToDefMap.find(ai);
152 assert(it != actualInToDefMap.end() && "can not find actual-in's def");
153 return it->second;
154 }
156 {
157 NodeIDToNodeIDMap::const_iterator it = formalOutToDefMap.find(fo);
158 assert(it != formalOutToDefMap.end() && "can not find formal-out's def");
159 return it->second;
160 }
162
163private:
165
167
168
173
183
185
188
190
191
197
200
202 inline void initialWorkList()
203 {
204 for (SVFG::const_iterator it = begin(), eit = end(); it != eit; ++it)
205 addIntoWorklist(it->second);
206 }
207
211 inline bool addIntoWorklist(const SVFGNode* node)
212 {
213 if (const MSSAPHISVFGNode* phi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
214 {
215 if (isConnectingTwoCallSites(phi) == false && isDefOfAInFOut(phi) == false)
216 return worklist.push(phi);
217 }
218 return false;
219 }
220
222 void bypassMSSAPHINode(const MSSAPHISVFGNode* node);
223
225 bool checkSelfCycleEdges(const MSSAPHISVFGNode* node);
226
229
231 inline bool bothInterEdges(const SVFGEdge* edge1, const SVFGEdge* edge2) const
232 {
233 bool inter1 = SVFUtil::isa<CallIndSVFGEdge, RetIndSVFGEdge>(edge1);
234 bool inter2 = SVFUtil::isa<CallIndSVFGEdge, RetIndSVFGEdge>(edge2);
235 return (inter1 && inter2);
236 }
237
239 {
240 phi->setOpVer(phi->getOpVerNum(), operand);
241 }
242
253 {
255 addSVFGNode(sNode, const_cast<RetICFGNode*>(
256 ar->getCallSite()->getRetICFGNode()));
257 resetDef(ar->getRev(),sNode);
258 return sNode;
259 }
260
261 inline void resetDef(const PAGNode* pagNode, const SVFGNode* node)
262 {
263 PAGNodeToDefMapTy::iterator it = PAGNodeToDefMap.find(pagNode);
264 assert(it != PAGNodeToDefMap.end() && "a SVFIR node doesn't have definition before");
265 it->second = node->getId();
266 }
267
270 inline void setActualINDef(NodeID ai, NodeID def)
271 {
272 bool inserted = actualInToDefMap.emplace(ai, def).second;
273 (void)inserted; // Suppress warning of unused variable under release build
274 assert(inserted && "can not set actual-in's def twice");
275 defNodes.set(def);
276 }
277 inline void setFormalOUTDef(NodeID fo, NodeID def)
278 {
279 bool inserted = formalOutToDefMap.emplace(fo, def).second;
280 (void) inserted;
281 assert(inserted && "can not set formal-out's def twice");
282 defNodes.set(def);
283 }
285
286 inline bool isDefOfAInFOut(const SVFGNode* node)
287 {
288 return defNodes.test(node->getId());
289 }
290
292
293 inline bool actualInOfIndCS(const ActualINSVFGNode* ai) const
294 {
295 return (SVFIR::getPAG()->isIndirectCallSites(ai->getCallSite()));
296 }
297 inline bool actualOutOfIndCS(const ActualOUTSVFGNode* ao) const
298 {
299 return (SVFIR::getPAG()->isIndirectCallSites(ao->getCallSite()));
300 }
302
304
306 {
307 return (fi->getFun()->hasAddressTaken());
308 }
310 {
311 return (fo->getFun()->hasAddressTaken());
312 }
314
316 bool isConnectingTwoCallSites(const SVFGNode* node) const;
317
327 bool canBeRemoved(const SVFGNode * node);
328
330
331 inline void removeAllEdges(const SVFGNode* node)
332 {
333 removeInEdges(node);
334 removeOutEdges(node);
335 }
336 inline void removeInEdges(const SVFGNode* node)
337 {
339 while (node->hasIncomingEdge())
340 removeSVFGEdge(*(node->InEdgeBegin()));
341 }
342 inline void removeOutEdges(const SVFGNode* node)
343 {
344 while (node->hasOutgoingEdge())
345 removeSVFGEdge(*(node->OutEdgeBegin()));
346 }
348
349
353
355
359};
360
361} // End namespace SVF
362
363#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 SVFFunction *fun)
Add a function entry node.
Definition ICFG.cpp:234
NodeID getId() const
Get ID.
Set< SVFGNode * > SVFGNodeSet
Definition SVFGOPT.h:58
bool isDefOfAInFOut(const SVFGNode *node)
Definition SVFGOPT.h:286
SVFGEdge * addCallIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS &cpts)
Add inter-procedural value flow edge.
Definition SVFGOPT.cpp:68
void replaceFParamARetWithPHI(PHISVFGNode *phi, SVFGNode *svfgNode)
Replace FormalParam/ActualRet node with PHI node.
Definition SVFGOPT.cpp:151
void handleIntraValueFlow()
Remove MSSAPHI SVFG nodes.
Definition SVFGOPT.cpp:391
void retargetEdgesOfAOutFIn(SVFGNode *node)
Connect actual-out/formal-in's predecessors to their successors directly.
Definition SVFGOPT.cpp:250
void addInterPHIOperands(PHISVFGNode *phi, const PAGNode *operand)
Definition SVFGOPT.h:238
void setFormalOUTDef(NodeID fo, NodeID def)
Definition SVFGOPT.h:277
FIFOWorkList< const MSSAPHISVFGNode * > WorkList
Definition SVFGOPT.h:60
void setActualINDef(NodeID ai, NodeID def)
Definition SVFGOPT.h:270
void handleInterValueFlow()
Definition SVFGOPT.cpp:90
void bypassMSSAPHINode(const MSSAPHISVFGNode *node)
Remove MSSAPHI node if possible.
Definition SVFGOPT.cpp:480
NodeID getActualINDef(NodeID ai) const
Get def-site of actual-in/formal-out.
Definition SVFGOPT.h:149
Map< NodeID, NodeID > NodeIDToNodeIDMap
Definition SVFGOPT.h:59
void removeInEdges(const SVFGNode *node)
Definition SVFGOPT.h:336
void connectAInAndFIn(const ActualINSVFGNode *actualIn, const FormalINSVFGNode *formalIn, CallSiteID csId, SVFGEdgeSetTy &edges) override
Connect actual-in and formal-in.
Definition SVFGOPT.h:120
SVFGOPT(std::unique_ptr< MemSSA > mssa, VFGK kind)
Constructor.
Definition SVFGOPT.h:64
bool keepAllSelfCycle
Definition SVFGOPT.h:357
bool addNewSVFGEdge(NodeID srcId, NodeID dstId, const SVFGEdge *preEdge, const SVFGEdge *succEdge)
Add new SVFG edge from src to dst.
Definition SVFGOPT.cpp:523
bool bothInterEdges(const SVFGEdge *edge1, const SVFGEdge *edge2) const
Return TRUE if both edges are indirect call/ret edges.
Definition SVFGOPT.h:231
bool formalInOfAddressTakenFunc(const FormalINSVFGNode *fi) const
Check if formal-in/formal-out reside in address-taken function.
Definition SVFGOPT.h:305
bool addIntoWorklist(const SVFGNode *node)
Definition SVFGOPT.h:211
void buildSVFG() override
Start building SVFG.
Definition SVFGOPT.cpp:47
bool actualOutOfIndCS(const ActualOUTSVFGNode *ao) const
Definition SVFGOPT.h:297
bool keepActualOutFormalIn
Definition SVFGOPT.h:356
InterPHISVFGNode * addInterPHIForAR(const ActualRetSVFGNode *ar)
Add inter PHI SVFG node for actual return.
Definition SVFGOPT.h:252
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:89
bool formalOutOfAddressTakenFunc(const FormalOUTSVFGNode *fo) const
Definition SVFGOPT.h:309
NodeID getFormalOUTDef(NodeID fo) const
Definition SVFGOPT.h:155
WorkList worklist
storing MSSAPHI nodes which may be removed.
Definition SVFGOPT.h:354
NodeIDToNodeIDMap actualInToDefMap
map actual-in to its def-site node
Definition SVFGOPT.h:350
void setTokeepAllSelfCycle()
Definition SVFGOPT.h:75
InterPHISVFGNode * addInterPHIForFP(const FormalParmSVFGNode *fp)
Add inter PHI SVFG node for formal parameter.
Definition SVFGOPT.h:244
bool isConnectingTwoCallSites(const SVFGNode *node) const
Return TRUE if this node has both incoming call/ret and outgoing call/ret edges.
Definition SVFGOPT.cpp:292
bool canBeRemoved(const SVFGNode *node)
Definition SVFGOPT.cpp:334
NodeIDToNodeIDMap formalOutToDefMap
map formal-out to its def-site node
Definition SVFGOPT.h:351
NodeBS defNodes
preserved def nodes of formal-in/actual-out
Definition SVFGOPT.h:352
void setTokeepContextSelfCycle()
Definition SVFGOPT.h:79
void retargetEdgesOfAInFOut(SVFGNode *node)
Retarget edges related to actual-in/-out and formal-in/-out.
Definition SVFGOPT.cpp:204
void removeAllEdges(const SVFGNode *node)
Remove edges of a SVFG node.
Definition SVFGOPT.h:331
void parseSelfCycleHandleOption()
Definition SVFGOPT.cpp:372
bool keepContextSelfCycle
Definition SVFGOPT.h:358
~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:133
void connectFRetAndARet(const PAGNode *fun_ret, const PAGNode *cs_ret, CallSiteID csId, SVFGEdgeSetTy &edges) override
Connect formal-ret and actual ret.
Definition SVFGOPT.h:101
void initialWorkList()
Initial work list with MSSAPHI nodes which may be removed.
Definition SVFGOPT.h:202
void removeOutEdges(const SVFGNode *node)
Definition SVFGOPT.h:342
void setTokeepActualOutFormalIn()
Definition SVFGOPT.h:71
void resetDef(const PAGNode *pagNode, const SVFGNode *node)
Definition SVFGOPT.h:261
bool actualInOfIndCS(const ActualINSVFGNode *ai) const
Check if actual-in/actual-out exist at indirect call site.
Definition SVFGOPT.h:293
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:79
bool checkSelfCycleEdges(const MSSAPHISVFGNode *node)
Remove self cycle edges if needed. Return TRUE if some self cycle edges remained.
Definition SVFGOPT.cpp:442
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:260
ICFG * getICFG() const
Definition SVFIR.h:172
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:116
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:721
VFGK kind
Definition VFG.h:105
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:701
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:55
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74