30#ifndef INCLUDE_MTA_LockAnalysis_H_
31#define INCLUDE_MTA_LockAnalysis_H_
99 template<
class ICFGGraph,
class CGGraph>
void analyze(ICFGGraph icfg, CGGraph cg);
100 template<
class ICFGGraph>
102 template<
class ICFGGraph>
105 template<
class ICFGGraph>
109 template<
class ICFGGraph,
class CGGraph>
void collectCxtLock(ICFGGraph icfg, CGGraph cg);
113 template<
class CGGraph>
128 for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it)
138 for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it)
201 for(CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it!=eit; ++it)
204 for(CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit!=elit; ++lit)
215 for(CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it!=eit; ++it)
218 for(CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit!=elit; ++lit)
254 for (
size_t begin = 0; begin <= cxt.size(); ++begin)
256 CallStrCxt suffix(cxt.begin() + begin, cxt.end());
257 suffixIndex[suffix].insert(cxt);
266 ContextSuffixToContexts::const_iterator suffixIt = instIt->second.find(suffix);
267 return suffixIt == instIt->second.end() ? nullptr : &suffixIt->second;
326 for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++)
328 if(lspan.find(*cts) != lspan.end())
341 for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++)
343 if (lspan.find(*cts) == lspan.end())
378 template<
class ICFGGraph,
class CGGraph>
void handleFork(ICFGGraph icfg, CGGraph cg,
const CxtStmt& cts);
381 template<
class ICFGGraph,
class CGGraph>
void handleCall(ICFGGraph icfg, CGGraph cg,
const CxtStmt& cts);
384 template<
class ICFGGraph,
class CGGraph>
void handleRet(ICFGGraph icfg, CGGraph cg,
const CxtStmt& cts);
389 const std::vector<const ICFGNode*>& successors);
392 template<
class ICFGGraph,
class CGGraph>
void handleIntra(ICFGGraph icfg, CGGraph cg,
const CxtStmt& cts);
412 for(CxtLockSet::const_iterator it = srclockset.begin(), eit = srclockset.end(); it!=eit; ++it)
428 bool changed =
false;
429 for (CxtLockSet::iterator it = tgrlockset.begin(); it != tgrlockset.end(); )
431 if (srclockset.find(*it) == srclockset.end())
433 it = tgrlockset.erase(it);
518 return tct->isCallSite(inst);
523 return tct->isExtCall(inst);
533 return tct->getThreadCallGraph();
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
void dump() const
Dump CxtStmt.
const ICFGNode * getStmt() const
Return current statement.
FIFOWorkList< CxtLockProc > CxtLockProcVec
Set< CxtLock > CxtLockSet
void analyze(ICFGGraph icfg, CGGraph cg)
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
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)
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)
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.
std::vector< const ICFGNode * > InstVec
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::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
LLVM_NODISCARD bool isa(const Y &Val)
std::ostream & outs()
Overwrite llvm::outs().
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
std::vector< u32_t > CallStrCxt