47using namespace SVFUtil;
51template<
class ICFGGraph,
class CGGraph>
80template<
class ICFGGraph,
class CGGraph>
123 if (visited.find(
cgnode) == visited.end())
133 if (visited.find(
cgnode) == visited.end())
139 while (!worklist.
empty())
146 if (visited.find(
srcNode) == visited.end())
159template<
class ICFGGraph,
class CGGraph>
188template<
class ICFGGraph,
class CGGraph>
196 while (!worklist.empty())
198 const ICFGNode *I = worklist.back();
217 std::vector<const ICFGNode*>
succ;
221 if(dst->getFun() == I->
getFun())
223 worklist.push_back(dst);
235template<
class ICFGGraph,
class CGGraph>
244 worklist.push_back(*it);
246 while (!worklist.empty())
248 const ICFGNode *I = worklist.back();
266 std::vector<const ICFGNode*>
pred;
270 if(src->getFun() == I->
getFun())
272 worklist.push_back(src);
282template<
class ICFGGraph,
class CGGraph>
286 for (TCT::FunSet::const_iterator it = entryFuncSet.begin(),
eit = entryFuncSet.end(); it !=
eit; ++it)
307 for (CallGraphEdge::CallInstSet::const_iterator
cit =
cgEdge->directCallsBegin(),
ecit =
cgEdge->directCallsEnd();
311 outs() <<
"\nCollecting CxtLocks: handling direct call:" << **
cit <<
"\t" <<
cgEdge->getSrcNode()->getFunction()->getName()
312 <<
"-->" <<
cgEdge->getDstNode()->getFunction()->getName() <<
"\n");
315 for (CallGraphEdge::CallInstSet::const_iterator
ind =
cgEdge->indirectCallsBegin(),
eind =
cgEdge->indirectCallsEnd();
319 outs() <<
"\nCollecting CxtLocks: handling indirect call:" << **
ind <<
"\t"
320 <<
cgEdge->getSrcNode()->getFunction()->getName() <<
"-->" <<
cgEdge->getDstNode()->getFunction()->getName()
332template<
class ICFGGraph,
class CGGraph>
351 DBOUT(
DMTA,
outs() <<
"LockAnalysis Process CallRet old clp --";
clp.dump());
363template<
class ICFGGraph,
class CGGraph>
368 for (TCT::FunSet::const_iterator it = entryFuncSet.begin(),
eit = entryFuncSet.end(); it !=
eit; ++it)
415 else if (SVFUtil::dyn_cast<FunExitICFGNode>(
curInst))
435 outs() <<
"\nlock sets size = " <<
lockset.size() <<
"\n";
445template<
class ICFGGraph,
class CGGraph>
449 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(
cts.getStmt());
450 if(
getTCG()->hasThreadForkEdge(call))
452 for (ThreadCallGraph::ForkEdgeSet::const_iterator
cgIt =
getTCG()->getForkEdgeBegin(call),
469template<
class ICFGGraph,
class CGGraph>
474 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(
cts.getStmt());
475 if (
getTCG()->hasCallGraphEdge(call))
477 for (CallGraph::CallGraphEdgeSet::const_iterator
cgIt =
getTCG()->getCallEdgeBegin(call),
ecgIt =
getTCG()->getCallEdgeEnd(call);
512template<
class ICFGGraph,
class CGGraph>
521 std::vector<const CallGraphEdge*>
inEdges;
525 if (SVFUtil::isa<ThreadForkEdge, ThreadJoinEdge>(
edgeConst))
529 for (CallGraphEdge::CallInstSet::const_iterator
cit = (
edge)->directCallsBegin(),
ecit = (
edge)->directCallsEnd();
cit !=
ecit;
536 std::vector<const ICFGNode*>
succ;
540 if(dst->getFun() == inst->
getFun())
559 for (CallGraphEdge::CallInstSet::const_iterator
cit = (
edge)->indirectCallsBegin(),
ecit = (
edge)->indirectCallsEnd();
566 std::vector<const ICFGNode*>
succ;
570 if(dst->getFun() == inst->
getFun())
593template<
class ICFGGraph,
class CGGraph>
600 std::vector<const ICFGNode*>
succ;
604 if(dst->getFun() ==
curInst->getFun())
632 if (cxt.back() == csId)
809template 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
iterator OutEdgeBegin()
iterators
GEdgeSetTy::const_iterator const_iterator
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 isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2)
bool isInSameSpan(const ICFGNode *I1, const ICFGNode *I2)
bool intraBackwardTraverse(ICFGGraph icfg, CGGraph cg, const InstSet &unlockset, InstSet &backwardInsts)
void buildCandidateFuncSetforLock()
void markCxtStmtFlag(const CxtStmt &tgr, const CxtStmt &src)
Mark thread flags for cxtStmt.
bool hasCxtLockfromCxtStmt(const CxtStmt &cts) const
bool isExtCall(const ICFGNode *inst)
Whether it is calling an external function.
void collectLockUnlocksites(ICFGGraph icfg, CGGraph cg)
Set< CxtStmt > CxtStmtSet
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()
FunSet lockcandidateFuncSet
Candidate functions which relevant to locks/unlocks.
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.
bool intraForwardTraverse(ICFGGraph icfg, CGGraph cg, const ICFGNode *lock, InstSet &unlockset, InstSet &forwardInsts)
void analyzeLockSpanCxtStmt(ICFGGraph icfg, CGGraph cg)
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 ...
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee)
Context helper functions.
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.
bool isTDFork(const ICFGNode *call)
Whether it is a lock site.
void handleRet(ICFGGraph icfg, CGGraph cg, const CxtStmt &cts)
Handle return.
InstSet locksites
Record all visited clps.
void analyzeIntraProcedualLock(ICFGGraph icfg, CGGraph cg)
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.
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
bool isLockCandidateFun(const FunObjVar *fun) const
Return true if it is a candidate function.
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 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.
InstToCxtStmtSet instToCxtStmtSet
Map a statement to all its context-sensitive statements.
const CxtLockSet & getCxtLockfromCxtStmt(const CxtStmt &cts) const
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.
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