Static Value-Flow Analysis
Loading...
Searching...
No Matches
LockAnalysis.h
Go to the documentation of this file.
1//===- LockAnalysis.h -- Analysis of locksets-------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <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 * LockAnalysis.h
25 *
26 * Created on: 26 Aug 2015
27 * Author: pengd
28 */
29
30#ifndef INCLUDE_MTA_LockAnalysis_H_
31#define INCLUDE_MTA_LockAnalysis_H_
32
36#include "MTA/TCT.h"
37
38#include <memory>
39#include <vector>
40
41namespace SVF
42{
43
44// Forward declaration for the sliced-graph handle analyze() can run on.
45class SlicedSVFIRView;
46
51{
52
53public:
56 {
57 Empty, // initial(dummy) state
58 TDLocked, // stmt is locked
59 TDUnlocked, // stmt is unlocked
60 };
61
64
65 typedef NodeBS LockSet;
68 typedef InstSet CISpan;
80
88
92
93 ~LockAnalysis() = default;
94
99 template<class ICFGGraph, class CGGraph> void analyze(ICFGGraph icfg, CGGraph cg);
100 template<class ICFGGraph>
102 template<class ICFGGraph>
105 template<class ICFGGraph>
108
109 template<class ICFGGraph, class CGGraph> void collectCxtLock(ICFGGraph icfg, CGGraph cg);
110 template<class ICFGGraph, class CGGraph> void analyzeLockSpanCxtStmt(ICFGGraph icfg, CGGraph cg);
111
112 template<class ICFGGraph, class CGGraph> void collectLockUnlockSites(ICFGGraph icfg, CGGraph cg);
113 template<class CGGraph>
115
117
118
119 inline bool isIntraLock(const ICFGNode* lock) const
120 {
121 assert(lockSites.find(lock)!=lockSites.end() && "not a lock site?");
122 return ciLockToSpan.find(lock)!=ciLockToSpan.end();
123 }
124
126 inline void addIntraLock(const ICFGNode* lockSite, const InstSet& stmts)
127 {
128 for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it)
129 {
130 instCILocksMap[*it].insert(lockSite);
131 ciLockToSpan[lockSite].insert(*it);
132 }
133 }
134
136 inline void addCondIntraLock(const ICFGNode* lockSite, const InstSet& stmts)
137 {
138 for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it)
139 {
140 instToCondCILocksMap[*it].insert(lockSite);
141 }
142 }
143
145 inline bool isInsideIntraLock(const ICFGNode* stmt) const
146 {
147 return instCILocksMap.find(stmt)!=instCILocksMap.end() || isInsideCondIntraLock(stmt);
148 }
149
151 inline bool isInsideCondIntraLock(const ICFGNode* stmt) const
152 {
153 return instToCondCILocksMap.find(stmt)!=instToCondCILocksMap.end();
154 }
155
159 inline bool hasIntraLockSet(const ICFGNode* stmt) const
160 {
161 return instCILocksMap.find(stmt)!=instCILocksMap.end();
162 }
163
164 inline const InstSet& getIntraLockSet(const ICFGNode* stmt) const
165 {
166 InstToInstSetMap::const_iterator it = instCILocksMap.find(stmt);
167 assert(it!=instCILocksMap.end() && "intralock not found!");
168 return it->second;
169 }
170
174 inline const InstSet& getCondIntraLockSet(const ICFGNode* stmt) const
175 {
176 InstToInstSetMap::const_iterator it = instToCondCILocksMap.find(stmt);
177 assert(it!=instToCondCILocksMap.end() && "conditional intralock not found!");
178 return it->second;
179 }
181
183
184
185 inline void addCxtLock(const CallStrCxt& cxt,const ICFGNode* inst)
186 {
187 CxtLock cxtlock(cxt,inst);
188 cxtLockSet.insert(cxtlock);
189 DBOUT(DMTA, SVFUtil::outs() << "LockAnalysis Process new lock "; cxtlock.dump());
190 }
191
193 inline bool hasCxtLock(const CxtLock& cxtLock) const
194 {
195 return cxtLockSet.find(cxtLock)!=cxtLockSet.end();
196 }
197
199 inline bool intersects(const CxtLockSet& lockset1,const CxtLockSet& lockset2) const
200 {
201 for(CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it!=eit; ++it)
202 {
203 const CxtLock& lock = *it;
204 for(CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit!=elit; ++lit)
205 {
206 if(lock==*lit)
207 return true;
208 }
209 }
210 return false;
211 }
213 inline bool alias(const CxtLockSet& lockset1,const CxtLockSet& lockset2)
214 {
215 for(CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it!=eit; ++it)
216 {
217 const CxtLock& lock = *it;
218 for(CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit!=elit; ++lit)
219 {
221 return true;
222 }
223 }
224 return false;
225 }
227
229 inline bool isLockCandidateFun(const FunObjVar* fun) const
230 {
231 return lockCandidateFuncSet.find(fun)!=lockCandidateFuncSet.end();
232 }
233
235
236
237 inline bool hasCxtStmtFromInst(const ICFGNode* inst) const
238 {
239 InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
240 return (it != instToCxtStmtSet.end());
241 }
242 inline const CxtStmtSet& getCxtStmtsFromInst(const ICFGNode* inst) const
243 {
244 InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
245 assert(it != instToCxtStmtSet.end());
246 return it->second;
247 }
251 inline void indexCallsiteContext(const ICFGNode* inst, const CallStrCxt& cxt)
252 {
254 for (size_t begin = 0; begin <= cxt.size(); ++begin)
255 {
256 CallStrCxt suffix(cxt.begin() + begin, cxt.end());
257 suffixIndex[suffix].insert(cxt);
258 }
259 }
261 const ICFGNode* inst, const CallStrCxt& suffix) const
262 {
263 InstToContextSuffixMap::const_iterator instIt = callsiteContextSuffixIndex.find(inst);
265 return nullptr;
266 ContextSuffixToContexts::const_iterator suffixIt = instIt->second.find(suffix);
267 return suffixIt == instIt->second.end() ? nullptr : &suffixIt->second;
268 }
269 inline bool hasCxtLockFromCxtStmt(const CxtStmt& cts) const
270 {
271 CxtStmtToCxtLockSet::const_iterator it = cxtStmtToCxtLockSet.find(cts);
272 return (it != cxtStmtToCxtLockSet.end());
273 }
274 inline const CxtLockSet& getCxtLockFromCxtStmt(const CxtStmt& cts) const
275 {
276 CxtStmtToCxtLockSet::const_iterator it = cxtStmtToCxtLockSet.find(cts);
277 assert(it != cxtStmtToCxtLockSet.end());
278 return it->second;
279 }
281 {
282 CxtStmtToCxtLockSet::iterator it = cxtStmtToCxtLockSet.find(cts);
283 assert(it != cxtStmtToCxtLockSet.end());
284 return it->second;
285 }
287 inline bool addCxtStmtToSpan(const CxtStmt& cts, const CxtLock& cl)
288 {
289 cxtLockToSpan[cl].insert(cts);
290 return cxtStmtToCxtLockSet[cts].insert(cl).second;
291 }
294 {
295 bool find = cxtStmtToCxtLockSet[cts].find(cl)!=cxtStmtToCxtLockSet[cts].end();
296 if(find)
297 {
298 cxtStmtToCxtLockSet[cts].erase(cl);
299 cxtLockToSpan[cl].erase(cts);
300 }
301 return find;
302 }
303
306 {
308 }
309 inline bool hasSpanFromCxtLock(const CxtLock& cl)
310 {
311 return cxtLockToSpan.find(cl) != cxtLockToSpan.end();
312 }
314 {
315 assert(cxtLockToSpan.find(cl) != cxtLockToSpan.end());
316 return cxtLockToSpan[cl];
317 }
319
321 inline bool hasOneCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
322 {
323 if(!hasCxtStmtFromInst(I))
324 return false;
326 for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++)
327 {
328 if(lspan.find(*cts) != lspan.end())
329 {
330 return true;
331 }
332 }
333 return false;
334 }
335
336 inline bool hasAllCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
337 {
338 if(!hasCxtStmtFromInst(I))
339 return false;
341 for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++)
342 {
343 if (lspan.find(*cts) == lspan.end())
344 {
345 return false;
346 }
347 }
348 return true;
349 }
350
354 bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2);
355 bool isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2);
357 bool isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode *i2);
358
359 bool isInSameSpan(const ICFGNode *I1, const ICFGNode *I2);
360 bool isInSameCSSpan(const ICFGNode *i1, const ICFGNode *i2) const;
361 bool isInSameCSSpan(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2) const;
362 bool isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const;
363
365 {
366 return cxtLockSet.size();
367 }
369 void printLocks(const CxtStmt& cts);
370
373 {
374 return tct;
375 }
376protected:
378 template<class ICFGGraph, class CGGraph> void handleFork(ICFGGraph icfg, CGGraph cg, const CxtStmt& cts);
379
381 template<class ICFGGraph, class CGGraph> void handleCall(ICFGGraph icfg, CGGraph cg, const CxtStmt& cts);
382
384 template<class ICFGGraph, class CGGraph> void handleRet(ICFGGraph icfg, CGGraph cg, const CxtStmt& cts);
385
388 const FunObjVar* callee, const ICFGNode* callsite,
389 const std::vector<const ICFGNode*>& successors);
390
392 template<class ICFGGraph, class CGGraph> void handleIntra(ICFGGraph icfg, CGGraph cg, const CxtStmt& cts);
393
395 template<class ICFGGraph, class CGGraph> void handleCallRelation(ICFGGraph icfg, CGGraph cg, CxtLockProc& clp, const CallGraphEdge* cgEdge, const CallICFGNode* call);
396
398 bool isAliasedLocks(const CxtLock& cl1, const CxtLock& cl2)
399 {
400 return isAliasedLocks(cl1.getStmt(), cl2.getStmt());
401 }
402 bool isAliasedLocks(const ICFGNode* i1, const ICFGNode* i2);
403
405
406
407 void markCxtStmtFlag(const CxtStmt& tgr, const CxtStmt& src)
408 {
410 if(hasCxtLockFromCxtStmt(tgr)== false)
411 {
412 for(CxtLockSet::const_iterator it = srclockset.begin(), eit = srclockset.end(); it!=eit; ++it)
413 {
415 }
417 }
418 else
419 {
421 {
423 }
424 }
425 }
427 {
428 bool changed = false;
429 for (CxtLockSet::iterator it = tgrlockset.begin(); it != tgrlockset.end(); )
430 {
431 if (srclockset.find(*it) == srclockset.end())
432 {
433 it = tgrlockset.erase(it);
434 changed = true;
435 }
436 else
437 ++it;
438 }
439 return changed;
440 }
441
443 inline void clearFlagMap()
444 {
446 }
448
450
452 {
453 if (isVisitedCTPs(clp) == false)
454 {
455 visitedCTPs.insert(clp);
456 return clpList.push(clp);
457 }
458 return false;
459 }
461 {
463 return clp;
464 }
465 inline bool isVisitedCTPs(const CxtLockProc& clp) const
466 {
467 return visitedCTPs.find(clp) != visitedCTPs.end();
468 }
470
472
473 inline bool pushToCTSWorkList(const CxtStmt& cs)
474 {
475 return cxtStmtList.push(cs);
476 }
478 {
480 return clp;
481 }
483
485
486
487 void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
489 bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
491 bool isContextSuffix(const CallStrCxt& lhs, const CallStrCxt& call);
493
495 inline bool isTDFork(const ICFGNode* call)
496 {
497 if(SVFUtil::isa<CallICFGNode>(call) == false)
498 return false;
499 return getTCG()->getThreadAPI()->isTDFork(SVFUtil::cast<CallICFGNode>(call));
500 }
502 inline bool isTDAcquire(const ICFGNode* call)
503 {
504 if(SVFUtil::isa<CallICFGNode>(call) == false)
505 return false;
506 return getTCG()->getThreadAPI()->isTDAcquire(SVFUtil::cast<CallICFGNode>(call));
507 }
509 inline bool isTDRelease(const ICFGNode* call)
510 {
511 if(SVFUtil::isa<CallICFGNode>(call) == false)
512 return false;
513 return getTCG()->getThreadAPI()->isTDRelease(SVFUtil::cast<CallICFGNode>(call));
514 }
516 inline bool isCallSite(const ICFGNode* inst)
517 {
518 return tct->isCallSite(inst);
519 }
521 inline bool isExtCall(const ICFGNode* inst)
522 {
523 return tct->isExtCall(inst);
524 }
526 inline const SVFVar* getLockVal(const ICFGNode* call)
527 {
528 return getTCG()->getThreadAPI()->getLockVal(call);
529 }
531 inline ThreadCallGraph* getTCG() const
532 {
533 return tct->getThreadCallGraph();
534 }
535
538
541
544
547
550
553
557
559
563
565
569
571
574
576
581
582public:
583 double lockTime;
587};
588
589} // End namespace SVF
590
591#endif /* INCLUDE_MTA_LockAnalysis_H_ */
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DMTA
Definition SVFType.h:597
bool push(const Data &data)
Definition WorkList.h:180
FIFOWorkList< CxtLockProc > CxtLockProcVec
Set< CxtLock > CxtLockSet
void analyze(ICFGGraph icfg, CGGraph cg)
Set< CxtStmt > LockSpan
bool hasIntraLockSet(const ICFGNode *stmt) const
bool removeCxtStmtToSpan(CxtStmt &cts, const CxtLock &cl)
Add context-sensitive statement.
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
bool isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode *i2)
void handleIntra(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle intra.
bool isInSameCSSpan(const ICFGNode *i1, const ICFGNode *i2) const
bool intraBackwardTraverse(ICFGGraph icfg, const InstSet &unlockSet, InstSet &backwardInsts)
bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2)
bool isInSameSpan(const ICFGNode *I1, const ICFGNode *I2)
InstToInstSetMap instCILocksMap
bool hasOneCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
Check if one instruction's context stmt is in a lock span.
void markCxtStmtFlag(const CxtStmt &tgr, const CxtStmt &src)
Mark thread flags for cxtStmt.
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
bool isIntraLock(const ICFGNode *lock) const
Intraprocedural locks.
InstToInstSetMap instToCondCILocksMap
TCT * getTCT()
Get tct.
Set< CxtStmt > CxtStmtSet
void handleReturnAtCallsite(const CxtStmt &exitCxtStmt, const FunObjVar *callee, const ICFGNode *callsite, const std::vector< const ICFGNode * > &successors)
Propagate a callee-exit lock state to one matching callsite context.
bool alias(const CxtLockSet &lockset1, const CxtLockSet &lockset2)
Return true if two locksets has at least one alias lock.
Map< CxtStmt, ValDomain > CxtStmtToLockFlagMap
void handleFork(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle fork.
CxtStmt popFromCTSWorkList()
bool isInsideIntraLock(const ICFGNode *stmt) const
Return true if a statement is inside an intra-procedural lock.
Map< const ICFGNode *, ContextSuffixToContexts > InstToContextSuffixMap
const SVFVar * getLockVal(const ICFGNode *call)
Get lock value.
void analyzeLockSpanCxtStmt(ICFGGraph icfg, CGGraph cg)
FunSet lockCandidateFuncSet
Candidate functions which relevant to locks/unlocks.
ThreadCallGraph * getTCG() const
ThreadCallGraph.
bool hasSpanFromCxtLock(const CxtLock &cl)
bool isInsideCondIntraLock(const ICFGNode *stmt) const
Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional ...
Set< CallStrCxt > CallStrCxtSet
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
bool intraForwardTraverse(ICFGGraph icfg, const ICFGNode *lock, InstSet &unlockSet, InstSet &forwardInsts)
void addCondIntraLock(const ICFGNode *lockSite, const InstSet &stmts)
Add intra-procedural lock.
bool hasCxtLock(const CxtLock &cxtLock) const
Get context-sensitive lock.
Map< CxtStmt, CxtLockSet > CxtStmtToCxtLockSet
bool isTDRelease(const ICFGNode *call)
Whether it is a unlock site.
bool addCxtStmtToSpan(const CxtStmt &cts, const CxtLock &cl)
Add context-sensitive statement.
Map< CxtLock, LockSpan > CxtLockToSpan
Set< CxtLockProc > CxtLockProcSet
InstSet lockSites
Record all visited clps.
bool isTDFork(const ICFGNode *call)
Whether it is a lock site.
void handleRet(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle return.
bool isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2)
bool pushToCTPWorkList(const CxtLockProc &clp)
WorkList helper functions.
CILockToSpan ciLockToSpan
Used for context-insensitive intra-procedural locks.
const InstSet & getIntraLockSet(const ICFGNode *stmt) const
void handleCall(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle call.
Map< const ICFGNode *, CxtStmtSet > InstToCxtStmtSet
const CxtLockSet & getCxtLockFromCxtStmt(const CxtStmt &cts) const
bool hasCxtStmtFromInst(const ICFGNode *inst) const
Context-sensitive statement and lock spans.
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
InstToContextSuffixMap callsiteContextSuffixIndex
Incremental exact suffix index for contexts observed at callsites.
LockSpan & getSpanFromCxtLock(const CxtLock &cl)
void addIntraLock(const ICFGNode *lockSite, const InstSet &stmts)
Add intra-procedural lock.
CxtLockProcSet visitedCTPs
CxtLockProc List.
void touchCxtStmt(CxtStmt &cts)
Touch this context statement.
Set< const ICFGNode * > InstSet
const CallStrCxtSet * getCallsiteContextsWithSuffix(const ICFGNode *inst, const CallStrCxt &suffix) const
bool hasAllCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
bool isLockCandidateFun(const FunObjVar *fun) const
Return true if it is a candidate function.
Map< CxtLock, NodeBS > CxtLockToLockSet
void analyzeIntraProceduralLock(ICFGGraph icfg)
~LockAnalysis()=default
void buildCandidateFuncSetForLock(CGGraph cg)
void printLocks(const CxtStmt &cts)
Print locks and spans.
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
ValDomain
semilattice Empty==>TDUnlocked==>TDLocked
CxtLockProc popFromCTPWorkList()
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
Map< const ICFGNode *, InstSet > InstToInstSetMap
void collectLockUnlockSites(ICFGGraph icfg, CGGraph cg)
Set< const FunObjVar * > FunSet
void handleCallRelation(ICFGGraph icfg, CGGraph cg, CxtLockProc &clp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
CxtLockSet cxtLockSet
Context-sensitive locks.
CxtLockSet & getCxtLockFromCxtStmt(const CxtStmt &cts)
Map< const ICFGNode *, NodeBS > LockSiteToLockSet
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
Map< const ICFGNode *, CISpan > CILockToSpan
bool isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const
bool isVisitedCTPs(const CxtLockProc &clp) const
void collectCxtLock(ICFGGraph icfg, CGGraph cg)
bool isAliasedLocks(const CxtLock &cl1, const CxtLock &cl2)
Return true it a lock matches an unlock.
void clearFlagMap()
Clear flags.
FIFOWorkList< CxtStmt > CxtStmtWorkList
CxtStmtToCxtLockSet cxtStmtToCxtLockSet
bool hasCxtLockFromCxtStmt(const CxtStmt &cts) const
InstToCxtStmtSet instToCxtStmtSet
Map a statement to all its context-sensitive statements.
Map< CallStrCxt, CallStrCxtSet > ContextSuffixToContexts
bool intersect(CxtLockSet &tgrlockset, const CxtLockSet &srclockset)
TCT::InstVec InstVec
void addCxtLock(const CallStrCxt &cxt, const ICFGNode *inst)
Context-sensitive locks.
bool intersects(const CxtLockSet &lockset1, const CxtLockSet &lockset2) const
Return true if the intersection of two locksets is not empty.
void indexCallsiteContext(const ICFGNode *inst, const CallStrCxt &cxt)
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
const InstSet & getCondIntraLockSet(const ICFGNode *stmt) const
CxtLockToSpan cxtLockToSpan
CxtLockProcVec clpList
Following data structures are used for collecting context-sensitive locks.
bool isTDAcquire(const ICFGNode *call)
Whether it is a lock site.
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:274
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:199
std::vector< const ICFGNode * > InstVec
Definition TCT.h:174
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:267
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
bool isTDRelease(const CallICFGNode *inst) const
Return true if this call release a lock.
const SVFVar * getLockVal(const ICFGNode *inst) const
Return lock value.
bool isTDAcquire(const CallICFGNode *inst) const
Return true if this call acquire a lock.
ThreadAPI * getThreadAPI() const
Thread API.
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
std::vector< u32_t > CallStrCxt
Definition GeneralType.h:96
unsigned u32_t
Definition GeneralType.h:67