36 using namespace SVFUtil;
56 initFromThreadAPI(mod);
72 if (isSpawneeFun(fun1) ==
false && isSpawneeFun(fun2) ==
false)
75 if (isSpawnerFun(fun1) ==
false && isSpawneeFun(fun1) ==
false && isFollowerFun(fun1) ==
false)
77 if (isSpawnerFun(fun2) ==
false && isSpawneeFun(fun2) ==
false && isFollowerFun(fun2) ==
false)
87 return mayHappenInParallelBetweenFunctions(fun1, fun2);
104 if (tdAPI->isTDFork(inst))
106 const SVFValue* forkVal = tdAPI->getForkedFun(inst);
107 if (
const SVFFunction* svForkfun = SVFUtil::dyn_cast<SVFFunction>(forkVal))
110 spawners.insert(fun);
111 spawnees.insert(svForkfun);
117 outs() << inst->toString() <<
"\n";
151 for (FunSet::iterator it = spawners.begin(), eit = spawners.end(); it != eit; ++it)
155 while (!worklist.
empty())
164 if (isSpawnerFun(caller) ==
false)
166 worklist.
push(caller);
167 addSpawnerFun(caller);
170 for (PTACallGraphEdge::CallInstSet::const_iterator dit = callEdge->
directCallsBegin(), deit =
173 addSpawnsite((*dit)->getCallSite());
175 for (PTACallGraphEdge::CallInstSet::const_iterator dit = callEdge->
indirectCallsBegin(), deit =
178 addSpawnsite((*dit)->getCallSite());
192 for (FunSet::iterator it = spawnees.begin(), eit = spawnees.end(); it != eit; ++it)
196 while (!worklist.
empty())
203 const SVFFunction* caller = (*it)->getDstNode()->getFunction();
204 if (isSpawneeFun(caller) ==
false)
206 worklist.
push(caller);
207 addSpawneeFun(caller);
220 for (CallInstSet::const_iterator sit = spawnSitesBegin(), esit = spawnSitesEnd(); sit != esit; ++sit)
226 while (!bb_worklist.
empty())
237 if (callgraph->hasCallGraphEdge(cbn))
239 for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = callgraph->getCallEdgeBegin(cbn),
240 ecgIt = callgraph->getCallEdgeEnd(cbn); cgIt != ecgIt; ++cgIt)
243 addFollowerFun(edge->
getDstNode()->getFunction());
250 if (visitedBBs.count(svf_scc_bb) == 0)
252 visitedBBs.insert(svf_scc_bb);
253 bb_worklist.
push(svf_scc_bb);
273 for (FunSet::iterator it = followers.begin(), eit = followers.end(); it != eit; ++it)
277 while (!worklist.
empty())
284 const SVFFunction* caller = (*it)->getDstNode()->getFunction();
285 if (isFollowerFun(caller) ==
false)
287 worklist.
push(caller);
288 addFollowerFun(caller);
313 worklist.push_back(fun);
316 while (!worklist.empty())
321 bool ismhpfun =
false;
322 for (PCG::FunVec::iterator it = worklist.begin(), eit = worklist.end(); it != eit; ++it)
325 if (mayHappenInParallelBetweenFunctions(fun1, fun2))
328 mhpfuns.insert(fun2);
333 mhpfuns.insert(fun1);
359 std::string isSpawner = isSpawnerFun(fun) ?
" SPAWNER " :
"";
360 std::string isSpawnee = isSpawneeFun(fun) ?
" CHILDREN " :
"";
361 std::string isFollower = isFollowerFun(fun) ?
" FOLLOWER " :
"";
362 outs() << fun->
getName() <<
" [" << isSpawner << isSpawnee << isFollower <<
"]\n";
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
bool push(const Data &data)
NodeType * getSrcNode() const
NodeType * getDstNode() const
iterator OutEdgeBegin()
iterators
void interferenceAnalysis()
Thread interferenceAnalysis.
virtual bool mayHappenInParallel(const SVFInstruction *i1, const SVFInstruction *i2) const
Interface to query whether two function may happen-in-parallel.
std::vector< const SVFFunction * > FunVec
void initFromThreadAPI(SVFModule *module)
Initialize spawner and spawnee sets with threadAPI.
virtual bool analyze()
We start the pass here.
void printResults()
Print analysis results.
void inferFromCallGraph()
Infer spawner spawnee and followers sets by traversing on callGraph.
bool mayHappenInParallelBetweenFunctions(const SVFFunction *fun1, const SVFFunction *fun2) const
CallInstSet::const_iterator indirectCallsEnd() const
CallInstSet::const_iterator directCallsBegin() const
Iterators for direct and indirect callsites.
CallInstSet::const_iterator directCallsEnd() const
CallInstSet::const_iterator indirectCallsBegin() const
PTACallGraphEdge::CallGraphEdgeSet::const_iterator const_iterator
const std::vector< const SVFBasicBlock * > & getSuccessors() const
std::vector< const SVFInstruction * >::const_iterator const_iterator
const_iterator end() const
const_iterator begin() const
const SVFBasicBlock * back() const
bool isDeclaration() const
const SVFBasicBlock * getParent() const
const SVFFunction * getFunction() const
const FunctionSetType & getFunctionSet() const
FunctionSetType::const_iterator const_iterator
const std::string & getName() const
bool isExtCall(const SVFFunction *fun)
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
bool isIntrinsicInst(const SVFInstruction *inst)
Return true if it is an llvm intrinsic instruction.
std::ostream & outs()
Overwrite llvm::outs()
bool isCallSite(const SVFInstruction *inst)
Whether an instruction is a call or invoke instruction.
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set