41using namespace SVFUtil;
45template<
class ICFGGraph,
class CGGraph>
73template<
class ICFGGraph,
class CGGraph>
79 for (
auto nodeIt = CGTraits::nodes_begin(
cg),
106template<
class CGGraph>
119 if (visited.find(
cgnode) == visited.end())
129 if (visited.find(
cgnode) == visited.end())
135 while (!worklist.
empty())
139 std::vector<const CallGraphEdge*>
inEdges;
144 if (visited.find(
srcNode) == visited.end())
157template<
class ICFGGraph>
188template<
class ICFGGraph>
198 while (!worklist.empty())
200 const ICFGNode *I = worklist.back();
222 std::vector<const ICFGNode*>
succ;
226 if(dst->getFun() == I->
getFun())
228 worklist.push_back(dst);
240template<
class ICFGGraph>
250 worklist.push_back(*it);
252 while (!worklist.empty())
254 const ICFGNode *I = worklist.back();
272 std::vector<const ICFGNode*>
pred;
276 if(src->getFun() == I->
getFun())
278 worklist.push_back(src);
288template<
class ICFGGraph,
class CGGraph>
292 for (TCT::FunSet::const_iterator it = entryFuncSet.begin(),
eit = entryFuncSet.end(); it !=
eit; ++it)
308 std::vector<const CallGraphEdge*>
outEdges;
312 std::vector<const CallICFGNode*> directCalls;
318 outs() <<
"\nCollecting CxtLocks: handling direct call:" << *
callSite <<
"\t" <<
cgEdge->getSrcNode()->getFunction()->getName()
319 <<
"-->" <<
cgEdge->getDstNode()->getFunction()->getName() <<
"\n");
322 std::vector<const CallICFGNode*> indirectCalls;
328 outs() <<
"\nCollecting CxtLocks: handling indirect call:" << *
callSite <<
"\t"
329 <<
cgEdge->getSrcNode()->getFunction()->getName() <<
"-->" <<
cgEdge->getDstNode()->getFunction()->getName()
341template<
class ICFGGraph,
class CGGraph>
360 DBOUT(
DMTA,
outs() <<
"LockAnalysis Process CallRet old clp --";
clp.dump());
373template<
class ICFGGraph,
class CGGraph>
378 for (TCT::FunSet::const_iterator it = entryFuncSet.begin(),
eit = entryFuncSet.end(); it !=
eit; ++it)
432 else if (SVFUtil::dyn_cast<FunExitICFGNode>(
curInst))
452 outs() <<
"\nlock sets size = " <<
lockset.size() <<
"\n";
462template<
class ICFGGraph,
class CGGraph>
466 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(
cts.getStmt());
468 std::vector<const CallGraphEdge*>
outEdges;
472 if (!SVFUtil::isa<ThreadForkEdge>(
edge) ||
489template<
class ICFGGraph,
class CGGraph>
494 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(
cts.getStmt());
496 std::vector<const CallGraphEdge*>
outEdges;
539 const ICFGNode* callsite,
const std::vector<const ICFGNode*>& successors)
542 const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(callsite);
565template<
class ICFGGraph,
class CGGraph>
573 std::vector<const ICFGNode*>
succ;
576 std::vector<const CallGraphEdge*>
inEdges;
580 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(
edgeConst))
582 std::vector<const CallICFGNode*> directCalls;
589 std::vector<const CallICFGNode*> indirectCalls;
599template<
class ICFGGraph,
class CGGraph>
606 std::vector<const ICFGNode*>
succ;
610 if(dst->getFun() ==
curInst->getFun())
638 if (cxt.back() == csId)
815template void LockAnalysis::analyze<ICFG*, CallGraph*>(
ICFG*,
CallGraph*);
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
const FunObjVar * getFunction() const
Get function of this call node.
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *callee) const
Get CallSiteID.
const RetICFGNode * getRetICFGNode() const
Return callsite.
bool push(const Data &data)
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
const SVFBasicBlock * getEntryBlock() const
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Set< CxtLock > CxtLockSet
void analyze(ICFGGraph icfg, CGGraph cg)
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)
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.
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.
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.
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 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.
bool isTDRelease(const ICFGNode *call)
Whether it is a unlock site.
bool addCxtStmtToSpan(const CxtStmt &cts, const CxtLock &cl)
Add context-sensitive statement.
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.
const InstSet & getIntraLockSet(const ICFGNode *stmt) const
void handleCall(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle call.
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.
void addIntraLock(const ICFGNode *lockSite, const InstSet &stmts)
Add intra-procedural lock.
void touchCxtStmt(CxtStmt &cts)
Touch this context statement.
Set< const ICFGNode * > InstSet
const CallStrCxtSet * getCallsiteContextsWithSuffix(const ICFGNode *inst, const CallStrCxt &suffix) const
bool isLockCandidateFun(const FunObjVar *fun) const
Return true if it is a candidate function.
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.
CxtLockProc popFromCTPWorkList()
bool matchCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Match context.
void collectLockUnlockSites(ICFGGraph icfg, CGGraph cg)
void handleCallRelation(ICFGGraph icfg, CGGraph cg, CxtLockProc &clp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
bool isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const
void collectCxtLock(ICFGGraph icfg, CGGraph cg)
bool isAliasedLocks(const CxtLock &cl1, const CxtLock &cl2)
Return true it a lock matches an unlock.
bool hasCxtLockFromCxtStmt(const CxtStmt &cts) const
InstToCxtStmtSet instToCxtStmtSet
Map a statement to all its context-sensitive statements.
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.
CxtLockProcVec clpList
Following data structures are used for collecting context-sensitive locks.
bool isTDAcquire(const ICFGNode *call)
Whether it is a lock site.
virtual AliasResult alias(const SVFVar *V1, const SVFVar *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
const std::vector< const ICFGNode * > & getICFGNodeList() const
const ICFGNode * back() const
static double getClk(bool mark=false)
virtual const std::string getSourceLoc() const
bool isContextSuffix(const CallStrCxt &lhs, const CallStrCxt &call)
If lhs is a suffix of rhs, including equal.
OrderedSet< const FunObjVar *, FunObjVarIdCmp > FunSet
PointerAnalysis * getPTA() const
Get PTA.
Set< const CallGraphNode * > PTACGNodeSet
ThreadCallGraph * getThreadCallGraph() const
Get TCG.
bool inSameCallGraphSCC(const CallGraphNode *src, const CallGraphNode *dst)
Whether two functions in the same callgraph scc.
void dumpCxt(CallStrCxt &cxt)
Dump calling context.
const FunSet & getEntryProcs() const
Get marked candidate functions.
virtual void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
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.
bool isExtCall(const FunObjVar *fun)
std::ostream & outs()
Overwrite llvm::outs()
llvm::IRBuilder IRBuilder
std::vector< u32_t > CallStrCxt