50#include <unordered_map>
69 maxContextLen(maxContextLen)
125 std::vector<const CallGraphEdge*>
outEdges;
222 std::vector<const CallGraphEdge*>
inEdges;
258 cxt.erase(cxt.begin());
311 std::vector<const CallGraphEdge*>
outEdges;
374 std::vector<const CallGraphEdge*>
inEdges;
412 : svfIr(svfIr), pta(pta), mhp(mhp), lockAnalysis(lockAnalysis), vfg(vfg)
511 assert(
vfg !=
nullptr &&
"data-dependence slice requires the thread-aware VFG_pre");
514 std::deque<const SVFGNode*> worklist;
517 if (
n !=
nullptr && visited.insert(
n).second)
518 worklist.push_back(
n);
536 if (
const LoadStmt*
ld = SVFUtil::dyn_cast<LoadStmt>(stmt))
538 else if (
const StoreStmt*
st = SVFUtil::dyn_cast<StoreStmt>(stmt))
551 while (!worklist.empty())
554 worklist.pop_front();
555 for (
const VFGEdge* e :
n->getInEdges())
556 seed(e->getSrcNode());
568 if (
const StmtVFGNode*
s = SVFUtil::dyn_cast<StmtVFGNode>(
n))
569 if (
s->getICFGNode() !=
nullptr)
570 result.insert(
s->getICFGNode());
572 result.insert(stmt->getICFGNode());
751 std::deque<const ICFGNode*> worklist;
757 worklist.push_back(node);
761 while (!worklist.empty())
764 worklist.pop_front();
823 if (node !=
nullptr && node->getFun() !=
nullptr)
857 if (
inEdge ==
nullptr)
continue;
880 if (fun->hasBasicBlock())
901 if (
inEdge ==
nullptr)
continue;
988 if (!
threadAPI->isTDJoin(
c) ||
c->getBB() ==
nullptr)
continue;
989 std::vector<const SVFBasicBlock*>
exitbbs;
990 c->getFun()->getExitBlocksOfLoop(
c->getBB(),
exitbbs);
992 if (!
eb->getICFGNodeList().empty())
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
AliasResult alias(const SVFVar *V1, const SVFVar *V2) override
Interface expose to users of our pointer analysis, given Value infos.
Set< const CallICFGNode * > CallInstSet
const FunObjVar * getFunction() const
Get function of this call node.
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
CallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *callee) const
Get CallSiteID.
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
const SVFBasicBlock * getEntryBlock() const
const SVFBasicBlock * front() const
const SVFBasicBlock * getExitBB() const
iterator begin()
Iterators.
bool hasGNode(NodeID id) const
Has a node.
NodeType * getGNode(NodeID id) const
Get a node.
const GEdgeSetTy & getInEdges() const
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
std::list< const SVFStmt * > SVFStmtList
const SVFStmtList & getSVFStmts() const
ICFGNodeIDToNodeMapTy::iterator iterator
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Set< CxtLock > CxtLockSet
bool hasCxtLockfromCxtStmt(const CxtStmt &cts) const
Set< CxtStmt > CxtStmtSet
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 ...
const InstSet & getIntraLockSet(const ICFGNode *stmt) const
bool hasCxtStmtFromInst(const ICFGNode *inst) const
Context-sensitive statement and lock spans.
Set< const ICFGNode * > InstSet
const CxtStmtSet & getCxtStmtsFromInst(const ICFGNode *inst) const
const CxtLockSet & getCxtLockfromCxtStmt(const CxtStmt &cts) const
virtual bool mayHappenInParallelCache(const ICFGNode *i1, const ICFGNode *i2)
ThreadCallGraph * getThreadCallGraph() const
Get ThreadCallGraph.
const CxtThreadStmtSet & getThreadStmtSet(const ICFGNode *inst) const
Get/has ThreadStmt.
bool hasThreadStmtSet(const ICFGNode *inst) const
TCT * getTCT() const
Get Thread Creation Tree.
SVFG * vfg
thread-aware VFG_pre (PTA/Single slicers; null for MTA)
OrderedSet< const SVFStmt * > getDependentThreadCreate(const SVFStmt *stmt)
OrderedSet< const ICFGNode * > buildBackwardICFGNodeSet(const OrderedSet< const ICFGNode * > &vulnerableNodes)
std::pair< OrderedSet< const CallICFGNode * >, OrderedSet< const CallICFGNode * > > collectCommonThreadStatements(const OrderedSet< const SVFStmt * > &vulnerableStatements)
OrderedSet< const VFGNode * > computeDataDependenceSVFGNodes(const OrderedSet< const SVFStmt * > &seeds, SVFG *vfg)
OrderedSet< const CallICFGNode * > collectMutexStatements(const OrderedSet< const SVFStmt * > &vulnerableStmts)
OrderedSet< const ICFGNode * > expandCallDependence(const OrderedSet< const ICFGNode * > &nodes)
MTASlicerBase(SVFIR *svfIr, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, SVFG *vfg=nullptr)
OrderedSet< const ICFGNode * > runDualSlicing(const OrderedSet< const ICFGNode * > &slicedNodes)
OrderedSet< const CallICFGNode * > collectPthreadStatements(const OrderedSet< const SVFStmt * > &vulnerableStmts)
OrderedSet< const ICFGNode * > getLockSet(const ICFGNode *node)
OrderedSet< const ICFGNode * > sliceDataDependenceOverVFG(const OrderedSet< const SVFStmt * > &seeds, SVFG *vfg)
OrderedSet< const TCTNode * > getTCTNodeSetFromNode(const ICFGNode *node)
LockAnalysis * lockAnalysis
OrderedSet< const ICFGNode * > svfgNodesToICFGNodes(const OrderedSet< const VFGNode * > &nodes, const OrderedSet< const SVFStmt * > &seeds)
Project the retained VFG nodes (plus the seeds) onto their ICFG nodes.
OrderedSet< const VFGNode * > retainedSVFGNodes
memoised data-dependence slice
const OrderedSet< const VFGNode * > & getRetainedSVFGNodes(const OrderedSet< const SVFStmt * > &vulnerableStatements)
MultiStageSlicer(SVFIR *svfIr, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, SVFG *vfg=nullptr)
OrderedSet< const ICFGNode * > runILASlicing(const OrderedSet< const SVFStmt * > &vulnerableStatements, const OrderedSet< const ICFGNode * > &threadVFSources={})
OrderedSet< const ICFGNode * > runPTASlicing(const OrderedSet< const SVFStmt * > &vulnerableStatements)
static Option< u32_t > MaxContextLen
CallGraph * getCallGraph() const
Return call graph.
bool hasDefSVFGNode(const ValVar *valVar) const
Given a valVar, return whether it has definition site.
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
Given a valVar, return its definition site.
ICFGNode * getICFGNode() const
OrderedSet< const ICFGNode * > runSlicing(const OrderedSet< const SVFStmt * > &vulnerableStatements)
SingleSlicer(SVFIR *svfIr, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, SVFG *vfg=nullptr)
void getKeptForkSites(std::vector< const ICFGNode * > &out) const
void collectEntryFunInCallGraph() override
Get entry functions that are neither called by other functions nor extern functions.
void collectLoopInfoForJoin() override
Handle join site in loop.
void pushCxt(CallStrCxt &cxt, const CallICFGNode *call, const FunObjVar *callee) override
Override pushCxt to use the custom maxContextLen.
void handleCallRelation(CxtThreadProc &ctp, const CallGraphEdge *cgEdge, const CallICFGNode *cs) override
Handle call relations.
const SlicedThreadCallGraphView * tcgView
bool isKeptEdge(const CallGraphEdge *edge) const
void getKeptJoinSites(std::vector< const ICFGNode * > &out) const
bool isKeptNode(const CallGraphNode *node) const
SlicedTCT(PointerAnalysis *p, const SlicedSVFIRView *slicedView, u32_t maxContextLen=0)
void build() override
Build TCT.
void markRelProcs() override
Mark relevant procedures that are backward reachable from any fork/join site.
const OrderedSet< const CallGraphNode * > & getKeptNodes() const
Get all kept nodes.
bool isKeptNode(const CallGraphNode *node) const
Check if a node is in the sliced view.
const CallGraph::CallGraphEdgeSet & getKeptEdges() const
Get all kept edges.
void getOutEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get out edges of a node (only returns kept edges and target nodes)
void getInEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get in edges of a node (only returns kept edges and source nodes)
const FunSet & getMakredProcs() const
Get marked candidate functions.
bool isInRecursion(const ICFGNode *inst) const
Whether an instruction is in a recursion.
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
virtual void collectLoopInfoForJoin()
Handle join site in loop.
virtual void collectEntryFunInCallGraph()
Get entry functions that are neither called by other functions nor extern functions.
InstToLoopMap joinSiteToLoopMap
Map a CxtThread to its start routine function.
FunSet candidateFuncSet
Procedures that are neither called by other functions nor extern functions.
bool inSameCallGraphSCC(const CallGraphNode *src, const CallGraphNode *dst)
Whether two functions in the same callgraph scc.
bool isJoinMustExecutedInLoop(const LoopBBs &lp, const ICFGNode *join)
Return true if a join instruction must be executed inside a loop.
virtual void markRelProcs()
Mark relevant procedures that are backward reachable from any fork/join site.
Set< const ICFGNode * > inRecurJoinSites
Fork or Join sites in recursions.
void dumpCxt(CallStrCxt &cxt)
Dump calling context.
const FunSet & getEntryProcs() const
Get marked candidate functions.
virtual void build()
Build TCT.
virtual void handleCallRelation(CxtThreadProc &ctp, const CallGraphEdge *cgEdge, const CallICFGNode *call)
Handle call relations.
SVFLoopAndDomInfo::LoopBBs LoopBBs
CallSiteSet::const_iterator forksitesEnd() const
CallSiteSet::const_iterator forksitesBegin() const
Fork sites iterators.
CallSiteSet::const_iterator joinsitesEnd() const
CallSiteSet::const_iterator joinsitesBegin() const
Join sites iterators.
ThreadAPI * getThreadAPI() const
Thread API.
bool hasStmtVFGNode(const SVFStmt *svfStmt) const
Existence checks for VFGNodes.
StmtVFGNode * getStmtVFGNode(const SVFStmt *svfStmt) const
Get an VFGNode.
bool isExtCall(const FunObjVar *fun)
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
llvm::IRBuilder IRBuilder
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
std::vector< u32_t > CallStrCxt
static void collectLockFunctionMarkers(const OrderedSet< const CallICFGNode * > &mutexCallNodes, OrderedSet< const ICFGNode * > &sliceResult)