Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVFGOPT.cpp
Go to the documentation of this file.
1//===- SVFGOPT.cpp -- 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.cpp
25 * @author: yesen
26 * @date: 31/03/2014
27 * @version: 1.0
28 *
29 * @section LICENSE
30 *
31 * @section DESCRIPTION
32 *
33 */
34
35#include "Util/Options.h"
36#include "Graphs/SVFGOPT.h"
37#include "Graphs/SVFGStat.h"
38
39using namespace SVF;
40using namespace SVFUtil;
41
42static std::string KeepAllSelfCycle = "all";
43static std::string KeepContextSelfCycle = "context";
44static std::string KeepNoneSelfCycle = "none";
45
47void SVFGOPT::readAndOptSVFG(const std::string &filename)
48{
49 SVFG::readFile(filename);
51}
52
54void SVFGOPT::buildAndWriteSVFG(const std::string &filename)
55{
57 SVFG::writeToFile(filename);
59}
60
66
69{
71 dump("SVFG_before_opt");
72
73 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("\tSVFG Optimisation\n"));
74
76
77 stat->sfvgOptStart();
79
81 stat->sfvgOptEnd();
82
83}
84
89{
91 return addIntraIndirectVFEdge(srcId, dstId, cpts);
92 else
93 return addCallIndirectVFEdge(srcId, dstId, cpts, csid);
94}
95
100{
102 return addIntraIndirectVFEdge(srcId, dstId, cpts);
103 else
104 return addRetIndirectVFEdge(srcId, dstId, cpts, csid);
105}
106
111{
112 SVFGNodeSet candidates;
113 for (SVFGNodeIDToNodeMapTy::iterator it = SVFG::begin(), eit = SVFG::end();
114 it!=eit; ++it)
115 {
116 SVFGNode* node = it->second;
120 candidates.insert(node);
121 }
122
123 SVFGNodeSet nodesToBeDeleted;
124 for (SVFGNodeSet::const_iterator it = candidates.begin(), eit = candidates.end();
125 it!=eit; ++it)
126 {
127 SVFGNode* node = *it;
129 {
131 nodesToBeDeleted.insert(fp);
132 }
134 {
136 nodesToBeDeleted.insert(ar);
137 }
139 {
140 nodesToBeDeleted.insert(node);
141 }
143 {
145 nodesToBeDeleted.insert(node);
146 }
148 {
149 if(keepActualOutFormalIn == false)
150 nodesToBeDeleted.insert(node);
151 }
152 }
153
154 for (SVFGNodeSet::iterator it = nodesToBeDeleted.begin(), eit = nodesToBeDeleted.end(); it != eit; ++it)
155 {
156 SVFGNode* node = *it;
157 if (canBeRemoved(node))
158 {
161
162 removeAllEdges(node);
163 removeSVFGNode(node);
164 }
165 }
166}
167
172{
174 && "expecting a formal param or actual ret svfg node");
175
177 NodeID phiId = phi->getId();
179 for (SVFGNode::const_iterator it = svfgNode->OutEdgeBegin(), eit = svfgNode->OutEdgeEnd();
180 it != eit; ++it)
181 {
182 const SVFGEdge* outEdge = *it;
183 SVFGNode* dstNode = outEdge->getDstNode();
184 NodeID dstId = dstNode->getId();
185 if (const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast<CallDirSVFGEdge>(outEdge))
186 addCallEdge(phiId, dstId, callEdge->getCallSiteId());
187 else if (const RetDirSVFGEdge* retEdge = SVFUtil::dyn_cast<RetDirSVFGEdge>(outEdge))
188 addRetEdge(phiId, dstId, retEdge->getCallSiteId());
189 else
190 addIntraDirectVFEdge(phiId, dstId);
191 }
192
195 {
196 for (SVFGNode::iterator it = svfgNode->InEdgeBegin(), eit = svfgNode->InEdgeEnd();
197 it != eit; ++it)
198 {
199 ActualParmSVFGNode* ap = SVFUtil::cast<ActualParmSVFGNode>((*it)->getSrcNode());
200 addInterPHIOperands(phi, ap->getParam());
201 // connect actual param's def node to phi node
202 addCallEdge(getDef(ap->getParam()), phiId, getCallSiteID(ap->getCallSite(), fp->getFun()));
203 }
204 }
206 {
207 for (SVFGNode::iterator it = svfgNode->InEdgeBegin(), eit = svfgNode->InEdgeEnd();
208 it != eit; ++it)
209 {
210 FormalRetSVFGNode* fr = SVFUtil::cast<FormalRetSVFGNode>((*it)->getSrcNode());
211 addInterPHIOperands(phi, fr->getRet());
212 // connect formal return's def node to phi node
213 addRetEdge(getDef(fr->getRet()), phiId, getCallSiteID(ar->getCallSite(), fr->getFun()));
214 }
215 }
216
217 removeAllEdges(svfgNode);
218}
219
225{
226 assert(node->getInEdges().size() == 1 && "actual-in/formal-out can only have one incoming edge as its def size");
227
228 SVFGNode* def = nullptr;
229 NodeBS inPointsTo;
230
233 for (; it != eit; ++it)
234 {
236 inPointsTo = inEdge->getPointsTo();
237
238 def = inEdge->getSrcNode();
240 setActualINDef(node->getId(), def->getId());
241 else if (SVFUtil::isa<FormalOUTSVFGNode>(node))
242 setFormalOUTDef(node->getId(), def->getId());
243 }
244
245 it = node->OutEdgeBegin(), eit = node->OutEdgeEnd();
246 for (; it != eit; ++it)
247 {
249 NodeBS intersection = inPointsTo;
250 intersection &= outEdge->getPointsTo();
251
252 if (intersection.empty())
253 continue;
254
255 SVFGNode* dstNode = outEdge->getDstNode();
256 if (const CallIndSVFGEdge* callEdge = SVFUtil::dyn_cast<CallIndSVFGEdge>(outEdge))
257 addCallIndirectSVFGEdge(def->getId(), dstNode->getId(), callEdge->getCallSiteId(), intersection);
258 else if (const RetIndSVFGEdge* retEdge = SVFUtil::dyn_cast<RetIndSVFGEdge>(outEdge))
259 addRetIndirectSVFGEdge(def->getId(), dstNode->getId(), retEdge->getCallSiteId(), intersection);
260 else
261 assert(false && "expecting an inter-procedural SVFG edge");
262 }
263
264 removeAllEdges(node);
265}
266
271{
273 SVFGNode::const_iterator inEit = node->InEdgeEnd();
274 for (; inIt != inEit; ++inIt)
275 {
277 NodeID srcId = inEdge->getSrcID();
278
280 SVFGNode::const_iterator outEit = node->OutEdgeEnd();
281 for (; outIt != outEit; ++outIt)
282 {
283 const IndirectSVFGEdge* outEdge = SVFUtil::cast<IndirectSVFGEdge>(*outIt);
284
285 NodeBS intersection = inEdge->getPointsTo();
286 intersection &= outEdge->getPointsTo();
287 if (intersection.empty())
288 continue;
289
290 NodeID dstId = outEdge->getDstID();
291 if (const RetIndSVFGEdge* retEdge = SVFUtil::dyn_cast<RetIndSVFGEdge>(inEdge))
292 {
293 addRetIndirectSVFGEdge(srcId, dstId, retEdge->getCallSiteId(), intersection);
294 }
295 else if (const CallIndSVFGEdge* callEdge = SVFUtil::dyn_cast<CallIndSVFGEdge>(inEdge))
296 {
297 addCallIndirectSVFGEdge(srcId, dstId, callEdge->getCallSiteId(), intersection);
298 }
299 else
300 {
301 addIntraIndirectVFEdge(srcId, dstId, intersection);
302 }
303 }
304 }
305
306 removeAllEdges(node);
307}
308
313{
314 bool hasInCallRet = false;
315 bool hasOutCallRet = false;
316
317 SVFGNode::const_iterator edgeIt = node->InEdgeBegin();
318 SVFGNode::const_iterator edgeEit = node->InEdgeEnd();
319 for (; edgeIt != edgeEit; ++edgeIt)
320 {
322 {
323 hasInCallRet = true;
324 break;
325 }
326 }
327
328 edgeIt = node->OutEdgeBegin();
329 edgeEit = node->OutEdgeEnd();
330 for (; edgeIt != edgeEit; ++edgeIt)
331 {
333 {
334 hasOutCallRet = true;
335 break;
336 }
337 }
338
339 if (hasInCallRet && hasOutCallRet)
340 return true;
341 else
342 return false;
343}
344
355{
358 return true;
361 {
365 if (isConnectingTwoCallSites(node))
366 return false;
367
369 {
370 return (actualInOfIndCS(ai) == false);
371 }
373 {
374 return (actualOutOfIndCS(ao) == false && isDefOfAInFOut(node) == false);
375 }
376 else if (const FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
377 {
378 return (formalInOfAddressTakenFunc(fi) == false && isDefOfAInFOut(node) == false);
379 }
381 {
382 return (formalOutOfAddressTakenFunc(fo) == false);
383 }
384 }
385
386 return false;
387}
388
393{
394 std::string choice = (Options::SelfCycle().empty()) ? "" : Options::SelfCycle();
395 if (choice.empty() || choice == KeepAllSelfCycle)
396 keepAllSelfCycle = true;
397 else if (choice == KeepContextSelfCycle)
399 else if (choice == KeepNoneSelfCycle)
401 else
402 {
403 SVFUtil::writeWrnMsg("Unrecognised option. All self cycle edges will be kept.");
404 keepAllSelfCycle = true;
405 }
406}
407
412{
414
416
417 while (!worklist.empty())
418 {
419 const MSSAPHISVFGNode* node = worklist.pop();
420
422 if (checkSelfCycleEdges(node))
423 continue;
424
425 if (node->hasOutgoingEdge() && node->hasIncomingEdge())
426 bypassMSSAPHINode(node);
427
429 if (node->hasIncomingEdge() && node->hasOutgoingEdge() == false)
430 {
432 SVFGNode::const_iterator edgeIt = node->InEdgeBegin();
433 SVFGNode::const_iterator edgeEit = node->InEdgeEnd();
434 for (; edgeIt != edgeEit; ++edgeIt)
435 addIntoWorklist((*edgeIt)->getSrcNode());
436
437 removeInEdges(node);
438 }
439 else if (node->hasOutgoingEdge() && node->hasIncomingEdge() == false)
440 {
442 SVFGNode::const_iterator edgeIt = node->OutEdgeBegin();
443 SVFGNode::const_iterator edgeEit = node->OutEdgeEnd();
444 for (; edgeIt != edgeEit; ++edgeIt)
445 addIntoWorklist((*edgeIt)->getDstNode());
446
447 removeOutEdges(node);
448 }
449
451 if (node->hasIncomingEdge() == false && node->hasOutgoingEdge() == false)
452 removeSVFGNode(const_cast<MSSAPHISVFGNode*>(node));
453 }
454}
455
456
463{
464 bool hasSelfCycle = false;
465
466 SVFGEdge::SVFGEdgeSetTy inEdges = node->getInEdges();
467 SVFGNode::const_iterator inEdgeIt = inEdges.begin();
468 SVFGNode::const_iterator inEdgeEit = inEdges.end();
469 for (; inEdgeIt != inEdgeEit; ++inEdgeIt)
470 {
471 SVFGEdge* preEdge = *inEdgeIt;
472
473 if (preEdge->getSrcID() == preEdge->getDstID())
474 {
476 {
477 hasSelfCycle = true;
478 break;
479 }
480 else if (keepContextSelfCycle &&
482 {
483 hasSelfCycle = true;
484 continue;
485 }
486 else
487 {
488 assert(SVFUtil::isa<IndirectSVFGEdge>(preEdge) && "can only remove indirect SVFG edge");
489 removeSVFGEdge(preEdge);
490 }
491 }
492 }
493
494 return hasSelfCycle;
495}
496
501{
502 SVFGNode::const_iterator inEdgeIt = node->InEdgeBegin();
503 SVFGNode::const_iterator inEdgeEit = node->InEdgeEnd();
504 for (; inEdgeIt != inEdgeEit; ++inEdgeIt)
505 {
506 const SVFGEdge* preEdge = *inEdgeIt;
507 const SVFGNode* srcNode = preEdge->getSrcNode();
508
509 bool added = false;
511 SVFGNode::const_iterator outEdgeIt = node->OutEdgeBegin();
512 SVFGNode::const_iterator outEdgeEit = node->OutEdgeEnd();
513 for (; outEdgeIt != outEdgeEit; ++outEdgeIt)
514 {
515 const SVFGEdge* succEdge = *outEdgeIt;
516 const SVFGNode* dstNode = (*outEdgeIt)->getDstNode();
517 if (srcNode->getId() != dstNode->getId()
518 && addNewSVFGEdge(srcNode->getId(), dstNode->getId(), preEdge, succEdge))
519 added = true;
520 else
521 {
524 addIntoWorklist(dstNode);
525 }
526 }
527
528 if (added == false)
529 {
532 addIntoWorklist(srcNode);
533 }
534 }
535
536 removeAllEdges(node);
537}
538
543bool SVFGOPT::addNewSVFGEdge(NodeID srcId, NodeID dstId, const SVFGEdge* preEdge, const SVFGEdge* succEdge)
544{
546 && "either pre or succ edge is not indirect SVFG edge");
547
548 const IndirectSVFGEdge* preIndEdge = SVFUtil::cast<IndirectSVFGEdge>(preEdge);
549 const IndirectSVFGEdge* succIndEdge = SVFUtil::cast<IndirectSVFGEdge>(succEdge);
550
551 NodeBS intersection = preIndEdge->getPointsTo();
552 intersection &= succIndEdge->getPointsTo();
553
554 if (intersection.empty())
555 return false;
556
557 assert(bothInterEdges(preEdge, succEdge) == false && "both edges are inter edges");
558
559 if (const CallIndSVFGEdge* preCallEdge = SVFUtil::dyn_cast<CallIndSVFGEdge>(preEdge))
560 {
561 return addCallIndirectSVFGEdge(srcId, dstId, preCallEdge->getCallSiteId(), intersection);
562 }
563 else if (const CallIndSVFGEdge* succCallEdge = SVFUtil::dyn_cast<CallIndSVFGEdge>(succEdge))
564 {
565 return addCallIndirectSVFGEdge(srcId, dstId, succCallEdge->getCallSiteId(), intersection);
566 }
567 else if (const RetIndSVFGEdge* preRetEdge = SVFUtil::dyn_cast<RetIndSVFGEdge>(preEdge))
568 {
569 return addRetIndirectSVFGEdge(srcId, dstId, preRetEdge->getCallSiteId(), intersection);
570 }
571 else if (const RetIndSVFGEdge* succRetEdge = SVFUtil::dyn_cast<RetIndSVFGEdge>(succEdge))
572 {
573 return addRetIndirectSVFGEdge(srcId, dstId, succRetEdge->getCallSiteId(), intersection);
574 }
575 else
576 {
577 return addIntraIndirectVFEdge(srcId, dstId, intersection);
578 }
579
580 return false;
581}
static std::string KeepNoneSelfCycle
Definition SVFGOPT.cpp:44
static std::string KeepContextSelfCycle
Definition SVFGOPT.cpp:43
static std::string KeepAllSelfCycle
Definition SVFGOPT.cpp:42
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DGENERAL
Definition SVFType.h:582
const ValVar * getParam() const
Return parameter.
Definition VFGNode.h:989
const CallICFGNode * getCallSite() const
Return callsite.
Definition VFGNode.h:983
const FunObjVar * getFun() const override
Function.
Definition VFGNode.h:1177
const ValVar * getRet() const
Return value at callee.
Definition VFGNode.h:1172
NodeType * getSrcNode() const
NodeType * getDstNode() const
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
iterator OutEdgeEnd()
const GEdgeSetTy & getInEdges() const
iterator OutEdgeBegin()
iterators
iterator InEdgeBegin()
iterator InEdgeEnd()
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:75
const NodeBS & getPointsTo() const
Definition SVFGEdge.h:60
static const Option< bool > KeepAOFI
Definition Options.h:104
static const Option< std::string > SelfCycle
Definition Options.h:105
static const Option< bool > DumpVFG
Definition Options.h:108
static const Option< bool > ContextInsensitive
Definition Options.h:103
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
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 removeInEdges(const SVFGNode *node)
Definition SVFGOPT.h:345
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
bool formalOutOfAddressTakenFunc(const FormalOUTSVFGNode *fo) const
Definition SVFGOPT.h:318
WorkList worklist
storing MSSAPHI nodes which may be removed.
Definition SVFGOPT.h:363
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
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
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
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
virtual void buildSVFG()
Start building SVFG.
Definition SVFG.cpp:228
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition SVFG.cpp:576
void removeSVFGNode(SVFGNode *node)
Remove a SVFGNode.
Definition SVFG.h:259
virtual void writeToFile(const std::string &filename)
SVFGEdge * addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition SVFG.cpp:525
void removeSVFGEdge(SVFGEdge *edge)
Remove a SVFG edge.
Definition SVFG.h:254
NodeID getDef(const ValVar *valVar) const
Definition SVFG.h:372
virtual void readFile(const std::string &filename)
SVFGEdge * addIntraIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts)
Add indirect def-use edges of a memory region between two statements,.
Definition SVFG.cpp:463
SVFGStat * stat
Definition SVFG.h:105
SVFGEdge * addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition SVFG.cpp:505
NodeID getId() const
Get ID.
Definition SVFValue.h:158
VFGEdgeSetTy SVFGEdgeSetTy
Definition VFGEdge.h:118
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
Definition VFGNode.h:55
VFGEdge::VFGEdgeSetTy::iterator iterator
Definition VFGNode.h:54
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:689
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *func) const
Get callsite given a callsiteID.
Definition VFG.h:178
VFGEdge * addIntraDirectVFEdge(NodeID srcId, NodeID dstId)
Definition VFG.cpp:643
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:669
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:121
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
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:88
std::ostream & outs()
Overwrite llvm::outs().
Definition SVFUtil.h:58
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
ActualParmVFGNode ActualParmSVFGNode
Definition SVFG.h:44
u32_t NodeID
Definition GeneralType.h:76
VFGNode SVFGNode
Definition SVFG.h:43
PHIVFGNode PHISVFGNode
Definition SVFG.h:56
ActualRetVFGNode ActualRetSVFGNode
Definition SVFG.h:45
VFGEdge SVFGEdge
Definition SVFG.h:42
SparseBitVector NodeBS
Definition GeneralType.h:82
FormalParmVFGNode FormalParmSVFGNode
Definition SVFG.h:46
FormalRetVFGNode FormalRetSVFGNode
Definition SVFG.h:47