Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | List of all members
SVF::LockAnalysis Class Reference

#include <LockAnalysis.h>

Public Types

enum  ValDomain { Empty , TDLocked , TDUnlocked }
 semilattice Empty==>TDUnlocked==>TDLocked More...
 
typedef CxtStmt CxtLock
 
typedef CxtProc CxtLockProc
 
typedef NodeBS LockSet
 
typedef TCT::InstVec InstVec
 
typedef Set< const ICFGNode * > InstSet
 
typedef InstSet CISpan
 
typedef Map< const ICFGNode *, CISpanCILockToSpan
 
typedef Set< const FunObjVar * > FunSet
 
typedef Map< const ICFGNode *, InstSetInstToInstSetMap
 
typedef Map< CxtStmt, ValDomainCxtStmtToLockFlagMap
 
typedef FIFOWorkList< CxtStmtCxtStmtWorkList
 
typedef Set< CxtStmtLockSpan
 
typedef Set< CxtStmtCxtStmtSet
 
typedef Set< CxtLockCxtLockSet
 
typedef Set< CallStrCxtCallStrCxtSet
 
typedef Map< CallStrCxt, CallStrCxtSetContextSuffixToContexts
 
typedef Map< const ICFGNode *, ContextSuffixToContextsInstToContextSuffixMap
 
typedef Map< CxtLock, LockSpanCxtLockToSpan
 
typedef Map< CxtLock, NodeBSCxtLockToLockSet
 
typedef Map< const ICFGNode *, NodeBSLockSiteToLockSet
 
typedef Map< const ICFGNode *, CxtStmtSetInstToCxtStmtSet
 
typedef Map< CxtStmt, CxtLockSetCxtStmtToCxtLockSet
 
typedef FIFOWorkList< CxtLockProcCxtLockProcVec
 
typedef Set< CxtLockProcCxtLockProcSet
 

Public Member Functions

 LockAnalysis (TCT *t)
 
 ~LockAnalysis ()=default
 
template<class ICFGGraph , class CGGraph >
void analyze (ICFGGraph icfg, CGGraph cg)
 
template<class ICFGGraph >
void analyzeIntraProceduralLock (ICFGGraph icfg)
 
template<class ICFGGraph >
bool intraForwardTraverse (ICFGGraph icfg, const ICFGNode *lock, InstSet &unlockSet, InstSet &forwardInsts)
 
template<class ICFGGraph >
bool intraBackwardTraverse (ICFGGraph icfg, const InstSet &unlockSet, InstSet &backwardInsts)
 
template<class ICFGGraph , class CGGraph >
void collectCxtLock (ICFGGraph icfg, CGGraph cg)
 
template<class ICFGGraph , class CGGraph >
void analyzeLockSpanCxtStmt (ICFGGraph icfg, CGGraph cg)
 
template<class ICFGGraph , class CGGraph >
void collectLockUnlockSites (ICFGGraph icfg, CGGraph cg)
 
template<class CGGraph >
void buildCandidateFuncSetForLock (CGGraph cg)
 
bool isIntraLock (const ICFGNode *lock) const
 Intraprocedural locks.
 
void addIntraLock (const ICFGNode *lockSite, const InstSet &stmts)
 Add intra-procedural lock.
 
void addCondIntraLock (const ICFGNode *lockSite, const InstSet &stmts)
 Add intra-procedural lock.
 
bool isInsideIntraLock (const ICFGNode *stmt) const
 Return true if a statement is inside an intra-procedural lock.
 
bool isInsideCondIntraLock (const ICFGNode *stmt) const
 Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional unlock)
 
bool hasIntraLockSet (const ICFGNode *stmt) const
 
const InstSetgetIntraLockSet (const ICFGNode *stmt) const
 
const InstSetgetCondIntraLockSet (const ICFGNode *stmt) const
 
void addCxtLock (const CallStrCxt &cxt, const ICFGNode *inst)
 Context-sensitive locks.
 
bool hasCxtLock (const CxtLock &cxtLock) const
 Get context-sensitive lock.
 
bool intersects (const CxtLockSet &lockset1, const CxtLockSet &lockset2) const
 Return true if the intersection of two locksets is not empty.
 
bool alias (const CxtLockSet &lockset1, const CxtLockSet &lockset2)
 Return true if two locksets has at least one alias lock.
 
bool isLockCandidateFun (const FunObjVar *fun) const
 Return true if it is a candidate function.
 
bool hasCxtStmtFromInst (const ICFGNode *inst) const
 Context-sensitive statement and lock spans.
 
const CxtStmtSetgetCxtStmtsFromInst (const ICFGNode *inst) const
 
void indexCallsiteContext (const ICFGNode *inst, const CallStrCxt &cxt)
 
const CallStrCxtSetgetCallsiteContextsWithSuffix (const ICFGNode *inst, const CallStrCxt &suffix) const
 
bool hasCxtLockFromCxtStmt (const CxtStmt &cts) const
 
const CxtLockSetgetCxtLockFromCxtStmt (const CxtStmt &cts) const
 
CxtLockSetgetCxtLockFromCxtStmt (const CxtStmt &cts)
 
bool addCxtStmtToSpan (const CxtStmt &cts, const CxtLock &cl)
 Add context-sensitive statement.
 
bool removeCxtStmtToSpan (CxtStmt &cts, const CxtLock &cl)
 Add context-sensitive statement.
 
void touchCxtStmt (CxtStmt &cts)
 Touch this context statement.
 
bool hasSpanFromCxtLock (const CxtLock &cl)
 
LockSpangetSpanFromCxtLock (const CxtLock &cl)
 
bool hasOneCxtInLockSpan (const ICFGNode *I, LockSpan lspan) const
 Check if one instruction's context stmt is in a lock span.
 
bool hasAllCxtInLockSpan (const ICFGNode *I, LockSpan lspan) const
 
bool isProtectedByCommonLock (const ICFGNode *i1, const ICFGNode *i2)
 
bool isProtectedByCommonCxtLock (const ICFGNode *i1, const ICFGNode *i2)
 
bool isProtectedByCommonCxtLock (const CxtStmt &cxtStmt1, const CxtStmt &cxtStmt2)
 
bool isProtectedByCommonCILock (const ICFGNode *i1, const ICFGNode *i2)
 
bool isInSameSpan (const ICFGNode *I1, const ICFGNode *I2)
 
bool isInSameCSSpan (const ICFGNode *i1, const ICFGNode *i2) const
 
bool isInSameCSSpan (const CxtStmt &cxtStmt1, const CxtStmt &cxtStmt2) const
 
bool isInSameCISpan (const ICFGNode *i1, const ICFGNode *i2) const
 
u32_t getNumOfCxtLocks ()
 
void printLocks (const CxtStmt &cts)
 Print locks and spans.
 
TCTgetTCT ()
 Get tct.
 

Public Attributes

double lockTime
 
u32_t numOfTotalQueries
 
u32_t numOfLockedQueries
 
double lockQueriesTime
 

Protected Member Functions

template<class ICFGGraph , class CGGraph >
void handleFork (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
 Handle fork.
 
template<class ICFGGraph , class CGGraph >
void handleCall (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
 Handle call.
 
template<class ICFGGraph , class CGGraph >
void handleRet (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
 Handle return.
 
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.
 
template<class ICFGGraph , class CGGraph >
void handleIntra (ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
 Handle intra.
 
template<class ICFGGraph , class CGGraph >
void handleCallRelation (ICFGGraph icfg, CGGraph cg, CxtLockProc &clp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
 Handle call relations.
 
bool isAliasedLocks (const CxtLock &cl1, const CxtLock &cl2)
 Return true it a lock matches an unlock.
 
bool isAliasedLocks (const ICFGNode *i1, const ICFGNode *i2)
 
void markCxtStmtFlag (const CxtStmt &tgr, const CxtStmt &src)
 Mark thread flags for cxtStmt.
 
bool intersect (CxtLockSet &tgrlockset, const CxtLockSet &srclockset)
 
void clearFlagMap ()
 Clear flags.
 
bool pushToCTPWorkList (const CxtLockProc &clp)
 WorkList helper functions.
 
CxtLockProc popFromCTPWorkList ()
 
bool isVisitedCTPs (const CxtLockProc &clp) const
 
bool pushToCTSWorkList (const CxtStmt &cs)
 Worklist operations.
 
CxtStmt popFromCTSWorkList ()
 
void pushCxt (CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
 Context helper functions.
 
bool matchCxt (CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
 Match context.
 
bool isContextSuffix (const CallStrCxt &lhs, const CallStrCxt &call)
 If lhs is a suffix of rhs, including equal.
 
bool isTDFork (const ICFGNode *call)
 Whether it is a lock site.
 
bool isTDAcquire (const ICFGNode *call)
 Whether it is a lock site.
 
bool isTDRelease (const ICFGNode *call)
 Whether it is a unlock site.
 
bool isCallSite (const ICFGNode *inst)
 Whether it is a callsite.
 
bool isExtCall (const ICFGNode *inst)
 Whether it is calling an external function.
 
const SVFVargetLockVal (const ICFGNode *call)
 Get lock value.
 
ThreadCallGraphgetTCG () const
 ThreadCallGraph.
 

Protected Attributes

TCTtct
 TCT.
 
CxtStmtWorkList cxtStmtList
 context-sensitive statement worklist
 
InstToCxtStmtSet instToCxtStmtSet
 Map a statement to all its context-sensitive statements.
 
InstToContextSuffixMap callsiteContextSuffixIndex
 Incremental exact suffix index for contexts observed at callsites.
 
CxtLockSet cxtLockSet
 Context-sensitive locks.
 
CxtLockToSpan cxtLockToSpan
 
CxtStmtToCxtLockSet cxtStmtToCxtLockSet
 
CxtLockProcVec clpList
 Following data structures are used for collecting context-sensitive locks.
 
CxtLockProcSet visitedCTPs
 CxtLockProc List.
 
InstSet lockSites
 Record all visited clps.
 
InstSet unlockSites
 
FunSet lockCandidateFuncSet
 Candidate functions which relevant to locks/unlocks.
 
CILockToSpan ciLockToSpan
 Used for context-insensitive intra-procedural locks.
 
InstToInstSetMap instCILocksMap
 
InstToInstSetMap instToCondCILocksMap
 

Detailed Description

Lock analysis

Definition at line 50 of file LockAnalysis.h.

Member Typedef Documentation

◆ CallStrCxtSet

Definition at line 77 of file LockAnalysis.h.

◆ CILockToSpan

Definition at line 69 of file LockAnalysis.h.

◆ CISpan

Definition at line 68 of file LockAnalysis.h.

◆ ContextSuffixToContexts

Definition at line 78 of file LockAnalysis.h.

◆ CxtLock

Definition at line 62 of file LockAnalysis.h.

◆ CxtLockProc

Definition at line 63 of file LockAnalysis.h.

◆ CxtLockProcSet

Definition at line 87 of file LockAnalysis.h.

◆ CxtLockProcVec

Definition at line 86 of file LockAnalysis.h.

◆ CxtLockSet

Definition at line 76 of file LockAnalysis.h.

◆ CxtLockToLockSet

Definition at line 82 of file LockAnalysis.h.

◆ CxtLockToSpan

Definition at line 81 of file LockAnalysis.h.

◆ CxtStmtSet

Definition at line 75 of file LockAnalysis.h.

◆ CxtStmtToCxtLockSet

Definition at line 85 of file LockAnalysis.h.

◆ CxtStmtToLockFlagMap

Definition at line 72 of file LockAnalysis.h.

◆ CxtStmtWorkList

Definition at line 73 of file LockAnalysis.h.

◆ FunSet

Definition at line 70 of file LockAnalysis.h.

◆ InstSet

Definition at line 67 of file LockAnalysis.h.

◆ InstToContextSuffixMap

Definition at line 79 of file LockAnalysis.h.

◆ InstToCxtStmtSet

Definition at line 84 of file LockAnalysis.h.

◆ InstToInstSetMap

Definition at line 71 of file LockAnalysis.h.

◆ InstVec

Definition at line 66 of file LockAnalysis.h.

◆ LockSet

Definition at line 65 of file LockAnalysis.h.

◆ LockSiteToLockSet

Definition at line 83 of file LockAnalysis.h.

◆ LockSpan

Definition at line 74 of file LockAnalysis.h.

Member Enumeration Documentation

◆ ValDomain

semilattice Empty==>TDUnlocked==>TDLocked

Enumerator
Empty 
TDLocked 
TDUnlocked 

Definition at line 55 of file LockAnalysis.h.

56 {
57 Empty, // initial(dummy) state
58 TDLocked, // stmt is locked
59 TDUnlocked, // stmt is unlocked
60 };

Constructor & Destructor Documentation

◆ LockAnalysis()

SVF::LockAnalysis::LockAnalysis ( TCT t)
inline

Definition at line 89 of file LockAnalysis.h.

◆ ~LockAnalysis()

SVF::LockAnalysis::~LockAnalysis ( )
default

Member Function Documentation

◆ addCondIntraLock()

void SVF::LockAnalysis::addCondIntraLock ( const ICFGNode lockSite,
const InstSet stmts 
)
inline

Add intra-procedural lock.

Definition at line 136 of file LockAnalysis.h.

137 {
138 for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it)
139 {
140 instToCondCILocksMap[*it].insert(lockSite);
141 }
142 }
InstToInstSetMap instToCondCILocksMap
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ addCxtLock()

void SVF::LockAnalysis::addCxtLock ( const CallStrCxt cxt,
const ICFGNode inst 
)
inline

Context-sensitive locks.

Add inter-procedural context-sensitive lock

Definition at line 185 of file LockAnalysis.h.

186 {
187 CxtLock cxtlock(cxt,inst);
188 cxtLockSet.insert(cxtlock);
189 DBOUT(DMTA, SVFUtil::outs() << "LockAnalysis Process new lock "; cxtlock.dump());
190 }
#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
CxtLockSet cxtLockSet
Context-sensitive locks.
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52

◆ addCxtStmtToSpan()

bool SVF::LockAnalysis::addCxtStmtToSpan ( const CxtStmt cts,
const CxtLock cl 
)
inline

Add context-sensitive statement.

Definition at line 287 of file LockAnalysis.h.

288 {
289 cxtLockToSpan[cl].insert(cts);
290 return cxtStmtToCxtLockSet[cts].insert(cl).second;
291 }
CxtStmtToCxtLockSet cxtStmtToCxtLockSet
CxtLockToSpan cxtLockToSpan

◆ addIntraLock()

void SVF::LockAnalysis::addIntraLock ( const ICFGNode lockSite,
const InstSet stmts 
)
inline

Add intra-procedural lock.

Definition at line 126 of file LockAnalysis.h.

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 }
InstToInstSetMap instCILocksMap
CILockToSpan ciLockToSpan
Used for context-insensitive intra-procedural locks.

◆ alias()

bool SVF::LockAnalysis::alias ( const CxtLockSet lockset1,
const CxtLockSet lockset2 
)
inline

Return true if two locksets has at least one alias lock.

Definition at line 213 of file LockAnalysis.h.

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 }
bool isAliasedLocks(const CxtLock &cl1, const CxtLock &cl2)
Return true it a lock matches an unlock.

◆ analyze()

template<class ICFGGraph , class CGGraph >
template void LockAnalysis::analyze< const SlicedICFGView *, const SlicedThreadCallGraphView * > ( ICFGGraph  icfg,
CGGraph  cg 
)

context-sensitive forward traversal from each lock site. Generate following results (1) context-sensitive lock site, (2) maps a context-sensitive lock site to its corresponding lock span. The same implementation runs over full and sliced ICFG/CallGraph traits.

Definition at line 46 of file LockAnalysis.cpp.

47{
50
51 DOTIMESTAT(double lockStart = PTAStat::getClk(true));
52
53 DBOUT(DGENERAL, outs() << "\tIntra-procedural LockAnalysis\n");
54 DBOUT(DMTA, outs() << "\tIntra-procedural LockAnalysis\n");
56
57 DBOUT(DGENERAL, outs() << "\tCollect context-sensitive locks\n");
58 DBOUT(DMTA, outs() << "\tCollect context-sensitive locks\n");
59 collectCxtLock(icfg, cg);
60
61 DBOUT(DGENERAL, outs() << "\tInter-procedural LockAnalysis\n");
62 DBOUT(DMTA, outs() << "\tInter-procedural LockAnalysis\n");
64
65 DOTIMESTAT(double lockEnd = PTAStat::getClk(true));
67}
#define TIMEINTERVAL
Definition SVFType.h:604
#define DGENERAL
Definition SVFType.h:582
#define DOTIMESTAT(X)
Definition SVFType.h:578
void analyzeLockSpanCxtStmt(ICFGGraph icfg, CGGraph cg)
void analyzeIntraProceduralLock(ICFGGraph icfg)
void buildCandidateFuncSetForLock(CGGraph cg)
void collectLockUnlockSites(ICFGGraph icfg, CGGraph cg)
void collectCxtLock(ICFGGraph icfg, CGGraph cg)
static double getClk(bool mark=false)
Definition SVFStat.cpp:51

◆ analyzeIntraProceduralLock()

template<class ICFGGraph >
void LockAnalysis::analyzeIntraProceduralLock ( ICFGGraph  icfg)

Analyze intraprocedural locks A lock is intraprocedural if its lock span is within a procedural

FIXME:Should we intersect forwardInsts and backwardInsts?

Definition at line 158 of file LockAnalysis.cpp.

159{
160
161 // Identify the protected Instructions.
162 for (InstSet::const_iterator it = lockSites.begin(), ie = lockSites.end(); it != ie; ++it)
163 {
164 const ICFGNode* lockSite = *it;
165 assert(isCallSite(lockSite) && "Lock acquire instruction must be a CallSite");
166
167 // Perform forward traversal
171
175 icfg, unlockSet, backwardInsts);
176
178 if(forward && backward)
180 else if(forward && !backward)
182 }
183}
bool intraBackwardTraverse(ICFGGraph icfg, const InstSet &unlockSet, InstSet &backwardInsts)
bool intraForwardTraverse(ICFGGraph icfg, const ICFGNode *lock, InstSet &unlockSet, InstSet &forwardInsts)
void addCondIntraLock(const ICFGNode *lockSite, const InstSet &stmts)
Add intra-procedural lock.
InstSet lockSites
Record all visited clps.
void addIntraLock(const ICFGNode *lockSite, const InstSet &stmts)
Add intra-procedural lock.
Set< const ICFGNode * > InstSet
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.

◆ analyzeLockSpanCxtStmt()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::analyzeLockSpanCxtStmt ( ICFGGraph  icfg,
CGGraph  cg 
)

Definition at line 374 of file LockAnalysis.cpp.

375{
376
377 const TCT::FunSet& entryFuncSet = tct->getEntryProcs();
378 for (TCT::FunSet::const_iterator it = entryFuncSet.begin(), eit = entryFuncSet.end(); it != eit; ++it)
379 {
380 if (!isLockCandidateFun(*it))
381 continue;
382 CallStrCxt cxt;
385 continue;
388 }
389
390 while (!cxtStmtList.empty())
391 {
393
395 const ICFGNode* curInst = cts.getStmt();
397 continue;
398 const bool firstContextVisit = instToCxtStmtSet[curInst].insert(cts).second;
400 indexCallsiteContext(curInst, cts.getContext());
401 DBOUT(DMTA, outs() << "\nVisit cxtStmt: ");
402 DBOUT(DMTA, cts.dump());
403
404 DBOUT(DMTA, outs() << "\nIts cxt lock sets: ");
406
407 if (isTDFork(curInst))
408 {
409 handleFork(icfg, cg, cts);
410 }
411 else if (isTDAcquire(curInst))
412 {
413 // Context truncation can merge a path into a lock context that the
414 // call-graph pre-collection did not enumerate. The propagation is
415 // authoritative: register that reachable lock before constructing
416 // its span. Release builds already constructed the same span; this
417 // keeps the canonical lock registry consistent as well.
418 if (!hasCxtLock(cts))
419 addCxtLock(cts.getContext(), curInst);
421 handleIntra(icfg, cg, cts);
422 }
423 else if (isTDRelease(curInst))
424 {
426 handleIntra(icfg, cg, cts);
427 }
428 else if (isCallSite(curInst) && !isExtCall(curInst))
429 {
430 handleCall(icfg, cg, cts);
431 }
432 else if (SVFUtil::dyn_cast<FunExitICFGNode>(curInst))
433 {
434 handleRet(icfg, cg, cts);
435 }
436 else
437 {
438 handleIntra(icfg, cg, cts);
439 }
440
441 }
442
443}
bool empty() const
Definition WorkList.h:161
bool removeCxtStmtToSpan(CxtStmt &cts, const CxtLock &cl)
Add context-sensitive statement.
CxtStmtWorkList cxtStmtList
context-sensitive statement worklist
void handleIntra(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle intra.
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
void handleFork(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle fork.
CxtStmt popFromCTSWorkList()
bool hasCxtLock(const CxtLock &cxtLock) const
Get context-sensitive lock.
bool isTDRelease(const ICFGNode *call)
Whether it is a unlock site.
bool addCxtStmtToSpan(const CxtStmt &cts, const CxtLock &cl)
Add context-sensitive statement.
bool isTDFork(const ICFGNode *call)
Whether it is a lock site.
void handleRet(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle return.
void handleCall(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle call.
bool pushToCTSWorkList(const CxtStmt &cs)
Worklist operations.
void touchCxtStmt(CxtStmt &cts)
Touch this context statement.
bool isLockCandidateFun(const FunObjVar *fun) const
Return true if it is a candidate function.
void printLocks(const CxtStmt &cts)
Print locks and spans.
InstToCxtStmtSet instToCxtStmtSet
Map a statement to all its context-sensitive statements.
void addCxtLock(const CallStrCxt &cxt, const ICFGNode *inst)
Context-sensitive locks.
void indexCallsiteContext(const ICFGNode *inst, const CallStrCxt &cxt)
bool isTDAcquire(const ICFGNode *call)
Whether it is a lock site.
OrderedSet< const FunObjVar *, FunObjVarIdCmp > FunSet
Definition TCT.h:173
const FunSet & getEntryProcs() const
Get marked candidate functions.
Definition TCT.h:245
std::vector< u32_t > CallStrCxt
Definition GeneralType.h:96

◆ buildCandidateFuncSetForLock()

template<class CGGraph >
void LockAnalysis::buildCandidateFuncSetForLock ( CGGraph  cg)

Collect candidate functions for context-sensitive lock analysis

Definition at line 107 of file LockAnalysis.cpp.

108{
109
111
112 TCT::PTACGNodeSet visited;
114
115 for (InstSet::iterator it = lockSites.begin(), eit = lockSites.end(); it != eit; ++it)
116 {
117 const FunObjVar* fun=(*it)->getFun();
119 if (visited.find(cgnode) == visited.end())
120 {
121 worklist.push(cgnode);
122 visited.insert(cgnode);
123 }
124 }
125 for (InstSet::iterator it = unlockSites.begin(), eit = unlockSites.end(); it != eit; ++it)
126 {
127 const FunObjVar* fun = (*it)->getFun();
129 if (visited.find(cgnode) == visited.end())
130 {
131 worklist.push(cgnode);
132 visited.insert(cgnode);
133 }
134 }
135 while (!worklist.empty())
136 {
137 const CallGraphNode* node = worklist.pop();
138 lockCandidateFuncSet.insert(node->getFunction());
139 std::vector<const CallGraphEdge*> inEdges;
141 for (const CallGraphEdge* edge : inEdges)
142 {
143 const CallGraphNode* srcNode = edge->getSrcNode();
144 if (visited.find(srcNode) == visited.end())
145 {
146 visited.insert(srcNode);
147 worklist.push(srcNode);
148 }
149 }
150 }
151}
const FunObjVar * getFunction() const
Get function of this call node.
Definition CallGraph.h:191
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
bool push(const Data &data)
Definition WorkList.h:180
FunSet lockCandidateFuncSet
Candidate functions which relevant to locks/unlocks.
Set< const CallGraphNode * > PTACGNodeSet
Definition TCT.h:176
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
Definition TCT.h:199

◆ clearFlagMap()

void SVF::LockAnalysis::clearFlagMap ( )
inlineprotected

Clear flags.

Definition at line 443 of file LockAnalysis.h.

444 {
446 }

◆ collectCxtLock()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::collectCxtLock ( ICFGGraph  icfg,
CGGraph  cg 
)

Definition at line 289 of file LockAnalysis.cpp.

290{
291 const TCT::FunSet& entryFuncSet = tct->getEntryProcs();
292 for (TCT::FunSet::const_iterator it = entryFuncSet.begin(), eit = entryFuncSet.end(); it != eit; ++it)
293 {
294 if (!isLockCandidateFun(*it))
295 continue;
296 CallStrCxt cxt;
297 CxtLockProc t(cxt, *it);
299 }
300
301 while (!clpList.empty())
302 {
304 CallGraphNode* cgNode = getTCG()->getCallGraphNode(clp.getProc());
305 if (!isLockCandidateFun(cgNode->getFunction()))
306 continue;
307
308 std::vector<const CallGraphEdge*> outEdges;
310 for (const CallGraphEdge* cgEdge : outEdges)
311 {
312 std::vector<const CallICFGNode*> directCalls;
314 cg, cgEdge, directCalls);
315 for (const CallICFGNode* callSite : directCalls)
316 {
317 DBOUT(DMTA,
318 outs() << "\nCollecting CxtLocks: handling direct call:" << *callSite << "\t" << cgEdge->getSrcNode()->getFunction()->getName()
319 << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
321 }
322 std::vector<const CallICFGNode*> indirectCalls;
324 cg, cgEdge, indirectCalls);
325 for (const CallICFGNode* callSite : indirectCalls)
326 {
327 DBOUT(DMTA,
328 outs() << "\nCollecting CxtLocks: handling indirect call:" << *callSite << "\t"
329 << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName()
330 << "\n");
332 }
333 }
334 }
335}
ThreadCallGraph * getTCG() const
ThreadCallGraph.
bool pushToCTPWorkList(const CxtLockProc &clp)
WorkList helper functions.
CxtLockProc popFromCTPWorkList()
void handleCallRelation(ICFGGraph icfg, CGGraph cg, CxtLockProc &clp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
CxtLockProcVec clpList
Following data structures are used for collecting context-sensitive locks.

◆ collectLockUnlockSites()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::collectLockUnlockSites ( ICFGGraph  icfg,
CGGraph  cg 
)

Collect lock/unlock sites

Definition at line 74 of file LockAnalysis.cpp.

75{
77
79 for (auto nodeIt = CGTraits::nodes_begin(cg),
80 nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt)
81 {
82 const FunObjVar* F = CGTraits::getRawNode(*nodeIt)->getFunction();
83 for (auto it : *F)
84 {
85 const SVFBasicBlock* bb = it.second;
86 for (const ICFGNode* icfgNode : bb->getICFGNodeList())
87 {
89 continue;
90 if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDRelease(cast<CallICFGNode>(icfgNode)))
91 {
92 unlockSites.insert(icfgNode);
93 }
94 if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDAcquire(cast<CallICFGNode>(icfgNode)))
95 {
96 lockSites.insert(icfgNode);
97 }
98 }
99 }
100 }
101}
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
bool isTDRelease(const CallICFGNode *inst) const
Return true if this call release a lock.
bool isTDAcquire(const CallICFGNode *inst) const
Return true if this call acquire a lock.
ThreadAPI * getThreadAPI() const
Thread API.

◆ getCallsiteContextsWithSuffix()

const CallStrCxtSet * SVF::LockAnalysis::getCallsiteContextsWithSuffix ( const ICFGNode inst,
const CallStrCxt suffix 
) const
inline

Definition at line 260 of file LockAnalysis.h.

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 }
InstToContextSuffixMap callsiteContextSuffixIndex
Incremental exact suffix index for contexts observed at callsites.

◆ getCondIntraLockSet()

const InstSet & SVF::LockAnalysis::getCondIntraLockSet ( const ICFGNode stmt) const
inline

Return the conditional intra-procedural locks whose may-spans contain stmt. Slicing needs these witnesses even though a conditional lock is not strong enough to prove mutual exclusion at the client query.

Definition at line 174 of file LockAnalysis.h.

175 {
176 InstToInstSetMap::const_iterator it = instToCondCILocksMap.find(stmt);
177 assert(it!=instToCondCILocksMap.end() && "conditional intralock not found!");
178 return it->second;
179 }

◆ getCxtLockFromCxtStmt() [1/2]

CxtLockSet & SVF::LockAnalysis::getCxtLockFromCxtStmt ( const CxtStmt cts)
inline

Definition at line 280 of file LockAnalysis.h.

281 {
282 CxtStmtToCxtLockSet::iterator it = cxtStmtToCxtLockSet.find(cts);
283 assert(it != cxtStmtToCxtLockSet.end());
284 return it->second;
285 }

◆ getCxtLockFromCxtStmt() [2/2]

const CxtLockSet & SVF::LockAnalysis::getCxtLockFromCxtStmt ( const CxtStmt cts) const
inline

Definition at line 274 of file LockAnalysis.h.

275 {
276 CxtStmtToCxtLockSet::const_iterator it = cxtStmtToCxtLockSet.find(cts);
277 assert(it != cxtStmtToCxtLockSet.end());
278 return it->second;
279 }

◆ getCxtStmtsFromInst()

const CxtStmtSet & SVF::LockAnalysis::getCxtStmtsFromInst ( const ICFGNode inst) const
inline

Definition at line 242 of file LockAnalysis.h.

243 {
244 InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
245 assert(it != instToCxtStmtSet.end());
246 return it->second;
247 }

◆ getIntraLockSet()

const InstSet & SVF::LockAnalysis::getIntraLockSet ( const ICFGNode stmt) const
inline

Definition at line 164 of file LockAnalysis.h.

165 {
166 InstToInstSetMap::const_iterator it = instCILocksMap.find(stmt);
167 assert(it!=instCILocksMap.end() && "intralock not found!");
168 return it->second;
169 }

◆ getLockVal()

const SVFVar * SVF::LockAnalysis::getLockVal ( const ICFGNode call)
inlineprotected

Get lock value.

Definition at line 526 of file LockAnalysis.h.

527 {
528 return getTCG()->getThreadAPI()->getLockVal(call);
529 }
const SVFVar * getLockVal(const ICFGNode *inst) const
Return lock value.

◆ getNumOfCxtLocks()

u32_t SVF::LockAnalysis::getNumOfCxtLocks ( )
inline

Definition at line 364 of file LockAnalysis.h.

365 {
366 return cxtLockSet.size();
367 }

◆ getSpanFromCxtLock()

LockSpan & SVF::LockAnalysis::getSpanFromCxtLock ( const CxtLock cl)
inline

Definition at line 313 of file LockAnalysis.h.

314 {
315 assert(cxtLockToSpan.find(cl) != cxtLockToSpan.end());
316 return cxtLockToSpan[cl];
317 }

◆ getTCG()

ThreadCallGraph * SVF::LockAnalysis::getTCG ( ) const
inlineprotected

ThreadCallGraph.

Definition at line 531 of file LockAnalysis.h.

532 {
533 return tct->getThreadCallGraph();
534 }

◆ getTCT()

TCT * SVF::LockAnalysis::getTCT ( )
inline

Get tct.

Definition at line 372 of file LockAnalysis.h.

373 {
374 return tct;
375 }

◆ handleCall()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::handleCall ( ICFGGraph  icfg,
CGGraph  cg,
const CxtStmt cts 
)
protected

Handle call.

Definition at line 490 of file LockAnalysis.cpp.

491{
492
493 const CallStrCxt& curCxt = cts.getContext();
494 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cts.getStmt());
496 std::vector<const CallGraphEdge*> outEdges;
498 for (const CallGraphEdge* edge : outEdges)
499 {
500 if (edge->getEdgeKind() != CallGraphEdge::CallRetEdge ||
502 continue;
503 const FunObjVar* svfcallee = edge->getDstNode()->getFunction();
505 continue;
507 pushCxt(newCxt, call, svfcallee);
508 const ICFGNode* svfInst =
510 if (svfInst == nullptr)
511 continue;
514
515 // Return-flow rendezvous (see MHP::handleCall): forward an already
516 // computed callee-exit lockset to this callsite's return site.
517 if (svfcallee->hasBasicBlock())
518 {
519 const ICFGNode* exitInst =
521 if (exitInst == nullptr)
522 continue;
525 {
526 const ICFGNode* retNode = call->getRetICFGNode();
528 {
531 }
532 }
533 }
534 }
535}
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:440
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:75
void markCxtStmtFlag(const CxtStmt &tgr, const CxtStmt &src)
Mark thread flags for cxtStmt.
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
bool hasCxtLockFromCxtStmt(const CxtStmt &cts) const
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:441

◆ handleCallRelation()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::handleCallRelation ( ICFGGraph  icfg,
CGGraph  cg,
CxtLockProc clp,
const CallGraphEdge cgEdge,
const CallICFGNode cs 
)
protected

Handle call relations.

Handling call relations when collecting context-sensitive locks

Definition at line 342 of file LockAnalysis.cpp.

343{
344
345 CallStrCxt cxt(clp.getContext());
346 const ICFGNode* curNode = cs;
348 return;
349 if (isTDAcquire(curNode))
350 {
351 addCxtLock(cxt,curNode);
352 return;
353 }
354 const FunObjVar* svfcallee = cgEdge->getDstNode()->getFunction();
355 pushCxt(cxt, SVFUtil::cast<CallICFGNode>(curNode), svfcallee);
356
359 {
360 DBOUT(DMTA, outs() << "LockAnalysis Process CallRet old clp --"; clp.dump());
361 DBOUT(DMTA, outs() << "LockAnalysis Process CallRet new clp --"; newclp.dump());
362 }
363
364}

◆ handleFork()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::handleFork ( ICFGGraph  icfg,
CGGraph  cg,
const CxtStmt cts 
)
protected

Handle fork.

Definition at line 463 of file LockAnalysis.cpp.

464{
465 const CallStrCxt& curCxt = cts.getContext();
466 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cts.getStmt());
468 std::vector<const CallGraphEdge*> outEdges;
470 for (const CallGraphEdge* edge : outEdges)
471 {
472 if (!SVFUtil::isa<ThreadForkEdge>(edge) ||
474 continue;
475 const FunObjVar* svfcallee = edge->getDstNode()->getFunction();
477 pushCxt(newCxt, call, svfcallee);
478 const ICFGNode* svfInst =
480 if (svfInst == nullptr)
481 continue;
484 }
485 handleIntra(icfg, cg, cts);
486}

◆ handleIntra()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::handleIntra ( ICFGGraph  icfg,
CGGraph  cg,
const CxtStmt cts 
)
protected

Handle intra.

Definition at line 600 of file LockAnalysis.cpp.

601{
602
603 const ICFGNode* curInst = cts.getStmt();
604 const CallStrCxt& curCxt = cts.getContext();
605
606 std::vector<const ICFGNode*> succ;
608 for (const ICFGNode* dst : succ)
609 {
610 if(dst->getFun() == curInst->getFun())
611 {
612 CxtStmt newCts(curCxt, dst);
614 }
615 }
616}

◆ handleRet()

template<class ICFGGraph , class CGGraph >
void LockAnalysis::handleRet ( ICFGGraph  icfg,
CGGraph  cg,
const CxtStmt cts 
)
protected

Handle return.

Definition at line 566 of file LockAnalysis.cpp.

567{
568
569 const ICFGNode* curInst = cts.getStmt();
570 const FunObjVar* svffun = curInst->getFun();
572
573 std::vector<const ICFGNode*> succ;
575
576 std::vector<const CallGraphEdge*> inEdges;
578 for (const CallGraphEdge* edgeConst : inEdges)
579 {
580 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(edgeConst))
581 continue;
582 std::vector<const CallICFGNode*> directCalls;
584 cg, edgeConst, directCalls);
585 for (const CallICFGNode* callSite : directCalls)
587 cts, curFunNode->getFunction(), callSite, succ);
588
589 std::vector<const CallICFGNode*> indirectCalls;
591 cg, edgeConst, indirectCalls);
592 for (const CallICFGNode* callSite : indirectCalls)
594 cts, curFunNode->getFunction(), callSite, succ);
595 }
596}
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.

◆ handleReturnAtCallsite()

void LockAnalysis::handleReturnAtCallsite ( const CxtStmt exitCxtStmt,
const FunObjVar callee,
const ICFGNode callsite,
const std::vector< const ICFGNode * > &  successors 
)
protected

Propagate a callee-exit lock state to one matching callsite context.

Definition at line 537 of file LockAnalysis.cpp.

540{
541 CallStrCxt callerCxt = exitCxtStmt.getContext();
542 const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(callsite);
543 if (!matchCxt(callerCxt, call, callee))
544 return;
545
546 for (const ICFGNode* successor : successors)
547 {
548 if (successor->getFun() != callsite->getFun())
549 continue;
550
553 if (matchingContexts == nullptr)
554 continue;
555
557 {
560 }
561 }
562}
Set< CallStrCxt > CallStrCxtSet
const CallStrCxtSet * getCallsiteContextsWithSuffix(const ICFGNode *inst, const CallStrCxt &suffix) const
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.

◆ hasAllCxtInLockSpan()

bool SVF::LockAnalysis::hasAllCxtInLockSpan ( const ICFGNode I,
LockSpan  lspan 
) const
inline

Definition at line 336 of file LockAnalysis.h.

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 }
Set< CxtStmt > LockSpan
bool hasCxtStmtFromInst(const ICFGNode *inst) const
Context-sensitive statement and lock spans.
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const

◆ hasCxtLock()

bool SVF::LockAnalysis::hasCxtLock ( const CxtLock cxtLock) const
inline

Get context-sensitive lock.

Definition at line 193 of file LockAnalysis.h.

194 {
195 return cxtLockSet.find(cxtLock)!=cxtLockSet.end();
196 }

◆ hasCxtLockFromCxtStmt()

bool SVF::LockAnalysis::hasCxtLockFromCxtStmt ( const CxtStmt cts) const
inline

Definition at line 269 of file LockAnalysis.h.

270 {
271 CxtStmtToCxtLockSet::const_iterator it = cxtStmtToCxtLockSet.find(cts);
272 return (it != cxtStmtToCxtLockSet.end());
273 }

◆ hasCxtStmtFromInst()

bool SVF::LockAnalysis::hasCxtStmtFromInst ( const ICFGNode inst) const
inline

Context-sensitive statement and lock spans.

Get LockSet and LockSpan

Definition at line 237 of file LockAnalysis.h.

238 {
239 InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
240 return (it != instToCxtStmtSet.end());
241 }

◆ hasIntraLockSet()

bool SVF::LockAnalysis::hasIntraLockSet ( const ICFGNode stmt) const
inline

Whether a statement has an (unconditional) intra-procedural lock set, i.e. getIntraLockSet is valid for it. A statement can be locked (isInsideIntraLock) via a conditional intra lock or a context lock without being here.

Definition at line 159 of file LockAnalysis.h.

160 {
161 return instCILocksMap.find(stmt)!=instCILocksMap.end();
162 }

◆ hasOneCxtInLockSpan()

bool SVF::LockAnalysis::hasOneCxtInLockSpan ( const ICFGNode I,
LockSpan  lspan 
) const
inline

Check if one instruction's context stmt is in a lock span.

Definition at line 321 of file LockAnalysis.h.

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 }

◆ hasSpanFromCxtLock()

bool SVF::LockAnalysis::hasSpanFromCxtLock ( const CxtLock cl)
inline

Definition at line 309 of file LockAnalysis.h.

310 {
311 return cxtLockToSpan.find(cl) != cxtLockToSpan.end();
312 }

◆ indexCallsiteContext()

void SVF::LockAnalysis::indexCallsiteContext ( const ICFGNode inst,
const CallStrCxt cxt 
)
inline

Index a callsite context by each of its suffixes (including itself and the empty suffix). handleRet can then retrieve exactly the contexts accepted by TCT::isContextSuffix without scanning every callsite state.

Definition at line 251 of file LockAnalysis.h.

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 }
Map< CallStrCxt, CallStrCxtSet > ContextSuffixToContexts

◆ intersect()

bool SVF::LockAnalysis::intersect ( CxtLockSet tgrlockset,
const CxtLockSet srclockset 
)
inlineprotected

Definition at line 426 of file LockAnalysis.h.

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 }

◆ intersects()

bool SVF::LockAnalysis::intersects ( const CxtLockSet lockset1,
const CxtLockSet lockset2 
) const
inline

Return true if the intersection of two locksets is not empty.

Definition at line 199 of file LockAnalysis.h.

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 }

◆ intraBackwardTraverse()

template<class ICFGGraph >
bool LockAnalysis::intraBackwardTraverse ( ICFGGraph  icfg,
const InstSet unlockSet,
InstSet backwardInsts 
)

Intra-procedural backward traversal

Definition at line 241 of file LockAnalysis.cpp.

243{
244
245 InstVec worklist;
246 for(InstSet::const_iterator it = unlockSet.begin(), eit = unlockSet.end(); it!=eit; ++it)
247 {
248 const ICFGNode* unlockSite = *it;
250 worklist.push_back(*it);
251
252 while (!worklist.empty())
253 {
254 const ICFGNode *I = worklist.back();
255 worklist.pop_back();
256
257 if(entryInst == I)
258 return false;
259
260 // Skip the visited Instructions.
261 if (backwardInsts.find(I)!=backwardInsts.end())
262 continue;
263 backwardInsts.insert(I);
264
266 {
267 DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << I->getSourceLoc()<<"\n");
268 DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << unlockSite->getSourceLoc()<<"\n");
269 continue;
270 }
271
272 std::vector<const ICFGNode*> pred;
274 for (const ICFGNode* src : pred)
275 {
276 if(src->getFun() == I->getFun())
277 {
278 worklist.push_back(src);
279 }
280 }
281 }
282 }
283
284 return true;
285}
const SVFBasicBlock * getEntryBlock() const
TCT::InstVec InstVec
const ICFGNode * back() const
virtual const std::string getSourceLoc() const
Definition SVFValue.h:194

◆ intraForwardTraverse()

template<class ICFGGraph >
bool LockAnalysis::intraForwardTraverse ( ICFGGraph  icfg,
const ICFGNode lockSite,
InstSet unlockSet,
InstSet forwardInsts 
)

Intra-procedural forward traversal

Definition at line 189 of file LockAnalysis.cpp.

192{
193
194 const FunObjVar* svfFun = lockSite->getFun();
195
196 InstVec worklist;
197 worklist.push_back(lockSite);
198 while (!worklist.empty())
199 {
200 const ICFGNode *I = worklist.back();
201 worklist.pop_back();
202 const ICFGNode* exitInst =
204 if (exitInst == nullptr)
205 return false;
206 if(exitInst == I)
207 return false;
208
209 // Skip the visited Instructions.
210 if (forwardInsts.find(I)!=forwardInsts.end())
211 continue;
212 forwardInsts.insert(I);
213
214 if (isTDRelease(I) && isAliasedLocks(lockSite, I))
215 {
216 unlockSet.insert(I);
217 DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << lockSite->getSourceLoc()<<"\n");
218 DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << I->getSourceLoc()<<"\n");
219 continue;
220 }
221
222 std::vector<const ICFGNode*> succ;
224 for (const ICFGNode* dst : succ)
225 {
226 if(dst->getFun() == I->getFun())
227 {
228 worklist.push_back(dst);
229 }
230 }
231 }
232
233 return true;
234}

◆ isAliasedLocks() [1/2]

bool SVF::LockAnalysis::isAliasedLocks ( const CxtLock cl1,
const CxtLock cl2 
)
inlineprotected

Return true it a lock matches an unlock.

Definition at line 398 of file LockAnalysis.h.

399 {
400 return isAliasedLocks(cl1.getStmt(), cl2.getStmt());
401 }

◆ isAliasedLocks() [2/2]

bool LockAnalysis::isAliasedLocks ( const ICFGNode i1,
const ICFGNode i2 
)
protected

Definition at line 366 of file LockAnalysis.cpp.

367{
368 // Lock matching is conservative: may-alias lock objects are treated as the
369 // same lock, consistent with the existing MTA lock semantics.
370 return tct->getPTA()->alias(getLockVal(i1)->getId(), getLockVal(i2)->getId());
371}
const SVFVar * getLockVal(const ICFGNode *call)
Get lock value.
virtual AliasResult alias(const SVFVar *V1, const SVFVar *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
PointerAnalysis * getPTA() const
Get PTA.
Definition TCT.h:204

◆ isCallSite()

bool SVF::LockAnalysis::isCallSite ( const ICFGNode inst)
inlineprotected

Whether it is a callsite.

Definition at line 516 of file LockAnalysis.h.

517 {
518 return tct->isCallSite(inst);
519 }
bool isCallSite(const ICFGNode *inst)
Whether it is a callsite.
Definition TCT.h:274

◆ isContextSuffix()

bool LockAnalysis::isContextSuffix ( const CallStrCxt lhs,
const CallStrCxt call 
)
protected

If lhs is a suffix of rhs, including equal.

Definition at line 647 of file LockAnalysis.cpp.

648{
649 return tct->isContextSuffix(lhs,call);
650}
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
Definition TCT.cpp:531

◆ isExtCall()

bool SVF::LockAnalysis::isExtCall ( const ICFGNode inst)
inlineprotected

Whether it is calling an external function.

Definition at line 521 of file LockAnalysis.h.

522 {
523 return tct->isExtCall(inst);
524 }
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
Definition TCT.h:267

◆ isInSameCISpan()

bool LockAnalysis::isInSameCISpan ( const ICFGNode i1,
const ICFGNode i2 
) const

Return true if two instructions are inside same context-insensitive lock span

Definition at line 760 of file LockAnalysis.cpp.

761{
763 {
766 for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1!=ecil1; ++cil1)
767 {
768 for (InstSet::const_iterator cil2=lockset2.begin(), ecil2=lockset2.end(); cil2!=ecil2; ++cil2)
769 {
770 if (*cil1==*cil2)
771 return true;
772 }
773 }
774 }
775 return false;
776}
bool isInsideCondIntraLock(const ICFGNode *stmt) const
Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional ...
const InstSet & getIntraLockSet(const ICFGNode *stmt) const

◆ isInSameCSSpan() [1/2]

bool LockAnalysis::isInSameCSSpan ( const CxtStmt cxtStmt1,
const CxtStmt cxtStmt2 
) const

Return true if two context-sensitive instructions are inside same context-insensitive lock spa

Definition at line 781 of file LockAnalysis.cpp.

782{
784 return false;
788}
Set< CxtLock > CxtLockSet
const CxtLockSet & getCxtLockFromCxtStmt(const CxtStmt &cts) const
bool intersects(const CxtLockSet &lockset1, const CxtLockSet &lockset2) const
Return true if the intersection of two locksets is not empty.

◆ isInSameCSSpan() [2/2]

bool LockAnalysis::isInSameCSSpan ( const ICFGNode I1,
const ICFGNode I2 
) const

Return true if two instructions are inside at least one common context-sensitive lock span

Definition at line 792 of file LockAnalysis.cpp.

793{
795 return false;
798
799 for (CxtStmtSet::const_iterator cts1 = ctsset1.begin(), ects1 = ctsset1.end(); cts1 != ects1; cts1++)
800 {
801 const CxtStmt& cxtStmt1 = *cts1;
802 for (CxtStmtSet::const_iterator cts2 = ctsset2.begin(), ects2 = ctsset2.end(); cts2 != ects2; cts2++)
803 {
804 const CxtStmt& cxtStmt2 = *cts2;
805 if(cxtStmt1==cxtStmt2) continue;
807 return false;
808 }
809 }
810 return true;
811}
bool isInSameCSSpan(const ICFGNode *i1, const ICFGNode *i2) const
Set< CxtStmt > CxtStmtSet

◆ isInSameSpan()

bool LockAnalysis::isInSameSpan ( const ICFGNode i1,
const ICFGNode i2 
)

Return true if two instructions are inside at least one common lock span

Definition at line 742 of file LockAnalysis.cpp.

743{
744 DOTIMESTAT(double queryStart = PTAStat::getClk(true));
745
746 bool sameSpan = false;
749 else
751
752 DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
754 return sameSpan;
755}
bool isInsideIntraLock(const ICFGNode *stmt) const
Return true if a statement is inside an intra-procedural lock.
bool isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const

◆ isInsideCondIntraLock()

bool SVF::LockAnalysis::isInsideCondIntraLock ( const ICFGNode stmt) const
inline

Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional unlock)

Definition at line 151 of file LockAnalysis.h.

152 {
153 return instToCondCILocksMap.find(stmt)!=instToCondCILocksMap.end();
154 }

◆ isInsideIntraLock()

bool SVF::LockAnalysis::isInsideIntraLock ( const ICFGNode stmt) const
inline

Return true if a statement is inside an intra-procedural lock.

Definition at line 145 of file LockAnalysis.h.

146 {
147 return instCILocksMap.find(stmt)!=instCILocksMap.end() || isInsideCondIntraLock(stmt);
148 }

◆ isIntraLock()

bool SVF::LockAnalysis::isIntraLock ( const ICFGNode lock) const
inline

Intraprocedural locks.

Return true if the lock is an intra-procedural lock

Definition at line 119 of file LockAnalysis.h.

120 {
121 assert(lockSites.find(lock)!=lockSites.end() && "not a lock site?");
122 return ciLockToSpan.find(lock)!=ciLockToSpan.end();
123 }

◆ isLockCandidateFun()

bool SVF::LockAnalysis::isLockCandidateFun ( const FunObjVar fun) const
inline

Return true if it is a candidate function.

Definition at line 229 of file LockAnalysis.h.

230 {
231 return lockCandidateFuncSet.find(fun)!=lockCandidateFuncSet.end();
232 }

◆ isProtectedByCommonCILock()

bool LockAnalysis::isProtectedByCommonCILock ( const ICFGNode i1,
const ICFGNode i2 
)

Protected by at least one common context-insensitive lock

Definition at line 673 of file LockAnalysis.cpp.

674{
675
677 {
680 for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1!=ecil1; ++cil1)
681 {
682 for (InstSet::const_iterator cil2=lockset2.begin(), ecil2=lockset2.end(); cil2!=ecil2; ++cil2)
683 {
684 if (isAliasedLocks(*cil1, *cil2))
685 return true;
686 }
687 }
688 }
689 return false;
690}

◆ isProtectedByCommonCxtLock() [1/2]

bool LockAnalysis::isProtectedByCommonCxtLock ( const CxtStmt cxtStmt1,
const CxtStmt cxtStmt2 
)

Protected by at least one common context-sensitive lock

Definition at line 695 of file LockAnalysis.cpp.

696{
698 return false;
701 return alias(lockset1,lockset2);
702}
bool alias(const CxtLockSet &lockset1, const CxtLockSet &lockset2)
Return true if two locksets has at least one alias lock.

◆ isProtectedByCommonCxtLock() [2/2]

bool LockAnalysis::isProtectedByCommonCxtLock ( const ICFGNode i1,
const ICFGNode i2 
)

Protected by at least one common context-sensitive lock under each context

Definition at line 707 of file LockAnalysis.cpp.

708{
710 return false;
713 for (CxtStmtSet::const_iterator cts1 = ctsset1.begin(), ects1 = ctsset1.end(); cts1 != ects1; cts1++)
714 {
715 const CxtStmt& cxtStmt1 = *cts1;
716 for (CxtStmtSet::const_iterator cts2 = ctsset2.begin(), ects2 = ctsset2.end(); cts2 != ects2; cts2++)
717 {
718 const CxtStmt& cxtStmt2 = *cts2;
719 if(cxtStmt1==cxtStmt2)
720 {
721 // i1==i2 under the same context: a self-race between two dynamic
722 // instances of one statement (e.g. a thread forked in a loop).
723 // This is the ONLY pair the loop produces for such a query, so
724 // skipping it would fall through to the vacuous "protected" return
725 // below and drop a real race. The two instances are mutually
726 // excluded only if this context actually holds a (non-empty) lock.
728 return false;
729 continue;
730 }
732 return false;
733 }
734 }
735 return true;
736}
bool isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2)

◆ isProtectedByCommonLock()

bool LockAnalysis::isProtectedByCommonLock ( const ICFGNode i1,
const ICFGNode i2 
)

Check if two Instructions are protected by common locks echo inst may have multiple cxt stmt we check whether every cxt stmt of instructions is protected by a common lock.

Protected by at least one common lock under every context

Definition at line 656 of file LockAnalysis.cpp.

657{
659 bool commonlock = false;
660 DOTIMESTAT(double queryStart = PTAStat::getClk(true));
663 else
665 DOTIMESTAT(double queryEnd = PTAStat::getClk(true));
667 return commonlock;
668}
bool isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode *i2)

◆ isTDAcquire()

bool SVF::LockAnalysis::isTDAcquire ( const ICFGNode call)
inlineprotected

Whether it is a lock site.

Definition at line 502 of file LockAnalysis.h.

503 {
504 if(SVFUtil::isa<CallICFGNode>(call) == false)
505 return false;
506 return getTCG()->getThreadAPI()->isTDAcquire(SVFUtil::cast<CallICFGNode>(call));
507 }

◆ isTDFork()

bool SVF::LockAnalysis::isTDFork ( const ICFGNode call)
inlineprotected

Whether it is a lock site.

Definition at line 495 of file LockAnalysis.h.

496 {
497 if(SVFUtil::isa<CallICFGNode>(call) == false)
498 return false;
499 return getTCG()->getThreadAPI()->isTDFork(SVFUtil::cast<CallICFGNode>(call));
500 }
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.

◆ isTDRelease()

bool SVF::LockAnalysis::isTDRelease ( const ICFGNode call)
inlineprotected

Whether it is a unlock site.

Definition at line 509 of file LockAnalysis.h.

510 {
511 if(SVFUtil::isa<CallICFGNode>(call) == false)
512 return false;
513 return getTCG()->getThreadAPI()->isTDRelease(SVFUtil::cast<CallICFGNode>(call));
514 }

◆ isVisitedCTPs()

bool SVF::LockAnalysis::isVisitedCTPs ( const CxtLockProc clp) const
inlineprotected

Definition at line 465 of file LockAnalysis.h.

466 {
467 return visitedCTPs.find(clp) != visitedCTPs.end();
468 }
CxtLockProcSet visitedCTPs
CxtLockProc List.

◆ markCxtStmtFlag()

void SVF::LockAnalysis::markCxtStmtFlag ( const CxtStmt tgr,
const CxtStmt src 
)
inlineprotected

Mark thread flags for cxtStmt.

Transfer function for marking context-sensitive statement

Definition at line 407 of file LockAnalysis.h.

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 }
bool intersect(CxtLockSet &tgrlockset, const CxtLockSet &srclockset)

◆ matchCxt()

bool LockAnalysis::matchCxt ( CallStrCxt cxt,
const CallICFGNode call,
const FunObjVar callee 
)
protected

Match context.

partial match

Definition at line 623 of file LockAnalysis.cpp.

624{
625 const FunObjVar* svfcaller = call->getFun();
626 CallSiteID csId = getTCG()->getCallSiteID(call, callee);
627
628// /// handle calling context for candidate functions only
629// if (isLockCandidateFun(caller) == false)
630// return true;
631
633 if (cxt.empty())
634 return true;
635
636 if (tct->inSameCallGraphSCC(getTCG()->getCallGraphNode(svfcaller), getTCG()->getCallGraphNode(callee)) == false)
637 {
638 if (cxt.back() == csId)
639 cxt.pop_back();
640 else
641 return false;
642 DBOUT(DMTA, tct->dumpCxt(cxt));
643 }
644 return true;
645}
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *callee) const
Get CallSiteID.
Definition CallGraph.h:389
bool inSameCallGraphSCC(const CallGraphNode *src, const CallGraphNode *dst)
Whether two functions in the same callgraph scc.
Definition TCT.h:309
void dumpCxt(CallStrCxt &cxt)
Dump calling context.
Definition TCT.cpp:551
unsigned CallSiteID
Definition GeneralType.h:78

◆ popFromCTPWorkList()

CxtLockProc SVF::LockAnalysis::popFromCTPWorkList ( )
inlineprotected

Definition at line 460 of file LockAnalysis.h.

461 {
463 return clp;
464 }

◆ popFromCTSWorkList()

CxtStmt SVF::LockAnalysis::popFromCTSWorkList ( )
inlineprotected

Definition at line 477 of file LockAnalysis.h.

478 {
479 CxtStmt clp = cxtStmtList.pop();
480 return clp;
481 }

◆ printLocks()

void LockAnalysis::printLocks ( const CxtStmt cts)

Print locks and spans.

Print context-insensitive and context-sensitive locks

Definition at line 449 of file LockAnalysis.cpp.

450{
452 outs() << "\nlock sets size = " << lockset.size() << "\n";
453 for (CxtLockSet::const_iterator it = lockset.begin(), eit = lockset.end(); it != eit; ++it)
454 {
455 (*it).dump();
456 }
457}

◆ pushCxt()

void LockAnalysis::pushCxt ( CallStrCxt cxt,
const CallICFGNode call,
const FunObjVar callee 
)
protected

Context helper functions.

Push calling context

Definition at line 618 of file LockAnalysis.cpp.

619{
620 tct->pushCxt(cxt,call,callee);
621}
virtual void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
Definition TCT.cpp:483

◆ pushToCTPWorkList()

bool SVF::LockAnalysis::pushToCTPWorkList ( const CxtLockProc clp)
inlineprotected

WorkList helper functions.

Definition at line 451 of file LockAnalysis.h.

452 {
453 if (isVisitedCTPs(clp) == false)
454 {
455 visitedCTPs.insert(clp);
456 return clpList.push(clp);
457 }
458 return false;
459 }
bool isVisitedCTPs(const CxtLockProc &clp) const

◆ pushToCTSWorkList()

bool SVF::LockAnalysis::pushToCTSWorkList ( const CxtStmt cs)
inlineprotected

Worklist operations.

Definition at line 473 of file LockAnalysis.h.

474 {
475 return cxtStmtList.push(cs);
476 }

◆ removeCxtStmtToSpan()

bool SVF::LockAnalysis::removeCxtStmtToSpan ( CxtStmt cts,
const CxtLock cl 
)
inline

Add context-sensitive statement.

Definition at line 293 of file LockAnalysis.h.

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 }

◆ touchCxtStmt()

void SVF::LockAnalysis::touchCxtStmt ( CxtStmt cts)
inline

Touch this context statement.

Definition at line 305 of file LockAnalysis.h.

306 {
308 }

Member Data Documentation

◆ callsiteContextSuffixIndex

InstToContextSuffixMap SVF::LockAnalysis::callsiteContextSuffixIndex
protected

Incremental exact suffix index for contexts observed at callsites.

Definition at line 546 of file LockAnalysis.h.

◆ ciLockToSpan

CILockToSpan SVF::LockAnalysis::ciLockToSpan
protected

Used for context-insensitive intra-procedural locks.

Definition at line 577 of file LockAnalysis.h.

◆ clpList

CxtLockProcVec SVF::LockAnalysis::clpList
protected

Following data structures are used for collecting context-sensitive locks.

Definition at line 560 of file LockAnalysis.h.

◆ cxtLockSet

CxtLockSet SVF::LockAnalysis::cxtLockSet
protected

Context-sensitive locks.

Definition at line 549 of file LockAnalysis.h.

◆ cxtLockToSpan

CxtLockToSpan SVF::LockAnalysis::cxtLockToSpan
protected

Map a context-sensitive lock to its lock span statements Map a context-sensitive statement to its context-sensitive lock

Definition at line 554 of file LockAnalysis.h.

◆ cxtStmtList

CxtStmtWorkList SVF::LockAnalysis::cxtStmtList
protected

context-sensitive statement worklist

Definition at line 540 of file LockAnalysis.h.

◆ cxtStmtToCxtLockSet

CxtStmtToCxtLockSet SVF::LockAnalysis::cxtStmtToCxtLockSet
protected

Definition at line 555 of file LockAnalysis.h.

◆ instCILocksMap

InstToInstSetMap SVF::LockAnalysis::instCILocksMap
protected

Definition at line 578 of file LockAnalysis.h.

◆ instToCondCILocksMap

InstToInstSetMap SVF::LockAnalysis::instToCondCILocksMap
protected

Definition at line 579 of file LockAnalysis.h.

◆ instToCxtStmtSet

InstToCxtStmtSet SVF::LockAnalysis::instToCxtStmtSet
protected

Map a statement to all its context-sensitive statements.

Definition at line 543 of file LockAnalysis.h.

◆ lockCandidateFuncSet

FunSet SVF::LockAnalysis::lockCandidateFuncSet
protected

Candidate functions which relevant to locks/unlocks.

Definition at line 572 of file LockAnalysis.h.

◆ lockQueriesTime

double SVF::LockAnalysis::lockQueriesTime

Definition at line 586 of file LockAnalysis.h.

◆ lockSites

InstSet SVF::LockAnalysis::lockSites
protected

Record all visited clps.

Collecting lock/unlock sites

Definition at line 566 of file LockAnalysis.h.

◆ lockTime

double SVF::LockAnalysis::lockTime

Definition at line 583 of file LockAnalysis.h.

◆ numOfLockedQueries

u32_t SVF::LockAnalysis::numOfLockedQueries

Definition at line 585 of file LockAnalysis.h.

◆ numOfTotalQueries

u32_t SVF::LockAnalysis::numOfTotalQueries

Definition at line 584 of file LockAnalysis.h.

◆ tct

TCT* SVF::LockAnalysis::tct
protected

TCT.

Definition at line 537 of file LockAnalysis.h.

◆ unlockSites

InstSet SVF::LockAnalysis::unlockSites
protected

Definition at line 567 of file LockAnalysis.h.

◆ visitedCTPs

CxtLockProcSet SVF::LockAnalysis::visitedCTPs
protected

CxtLockProc List.

Definition at line 561 of file LockAnalysis.h.


The documentation for this class was generated from the following files: