Static Value-Flow Analysis
Loading...
Searching...
No Matches
ThreadCallGraph.h
Go to the documentation of this file.
1//===- ThreadCallGraph.h -- Call graph considering thread fork/join-----------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23/*
24 * ThreadCallGraph.h
25 *
26 * Created on: Jul 7, 2014
27 * Authors: Peng Di, Yulei Sui, Ding Ye
28 */
29
30#ifndef RCG_H_
31#define RCG_H_
32
33#include "Graphs/PTACallGraph.h"
34
35namespace SVF
36{
37
38class SVFModule;
39class ThreadAPI;
40class PointerAnalysis;
45{
46
47public:
55 {
56 }
57
59
60 static inline bool classof(const ThreadForkEdge*)
61 {
62 return true;
63 }
64 static inline bool classof(const PTACallGraphEdge*edge)
65 {
66 return edge->getEdgeKind() == PTACallGraphEdge::TDForkEdge;
67 }
69
70 virtual const std::string toString() const
71 {
72 std::string str;
73 std::stringstream rawstr(str);
74 rawstr << "ThreadForkEdge ";
75 rawstr << "CallSiteID: " << getCallSiteID();
76 rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getFunction()->getName() << ")";
77 rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getFunction()->getName() << ")";
78 return rawstr.str();
79 }
80
82};
83
88{
89
90public:
98 {
99 }
100
101 static inline bool classof(const ThreadJoinEdge*)
102 {
103 return true;
104 }
105 static inline bool classof(const PTACallGraphEdge*edge)
106 {
107 return edge->getEdgeKind() == PTACallGraphEdge::TDJoinEdge;
108 }
109
110 virtual const std::string toString() const
111 {
112 std::string str;
113 std::stringstream rawstr(str);
114 rawstr << "ThreadJoinEdge ";
115 rawstr << "CallSiteID: " << getCallSiteID();
116 rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getFunction()->getName() << ")";
117 rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getFunction()->getName() << ")";
118 return rawstr.str();
119 }
120
122};
123
128{
129
130public:
138 {
139 }
140
142
143 static inline bool classof(const HareParForEdge*)
144 {
145 return true;
146 }
147 static inline bool classof(const PTACallGraphEdge*edge)
148 {
149 return edge->getEdgeKind() == PTACallGraphEdge::HareParForEdge;
150 }
152
154};
155
156
161{
162
163public:
173
176
178
181 {
182 }
183
185
186 static inline bool classof(const ThreadCallGraph *)
187 {
188 return true;
189 }
190 static inline bool classof(const PTACallGraph*g)
191 {
192 return g->getKind() == PTACallGraph::ThdCallGraph;
193 }
195
200
201
203
204
205 inline bool hasThreadForkEdge(const CallICFGNode* cs) const
206 {
207 return callinstToThreadForkEdgesMap.find(cs) !=
209 }
210 inline ForkEdgeSet::const_iterator getForkEdgeBegin(const CallICFGNode* cs) const
211 {
212 CallInstToForkEdgesMap::const_iterator it = callinstToThreadForkEdgesMap.find(cs);
213 assert(it != callinstToThreadForkEdgesMap.end() && "call instruction not found");
214 return it->second.begin();
215 }
216 inline ForkEdgeSet::const_iterator getForkEdgeEnd(const CallICFGNode* cs) const
217 {
218 CallInstToForkEdgesMap::const_iterator it = callinstToThreadForkEdgesMap.find(cs);
219 assert(it != callinstToThreadForkEdgesMap.end() && "call instruction not found");
220 return it->second.end();
221 }
222
224
225
226 inline bool hasThreadJoinEdge(const CallICFGNode* cs) const
227 {
229 }
230 inline JoinEdgeSet::const_iterator getJoinEdgeBegin(const CallICFGNode* cs) const
231 {
232 CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(cs);
233 assert(it != callinstToThreadJoinEdgesMap.end() && "call instruction does not have a valid callee");
234 return it->second.begin();
235 }
236 inline JoinEdgeSet::const_iterator getJoinEdgeEnd(const CallICFGNode* cs) const
237 {
238 CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(cs);
239 assert(it != callinstToThreadJoinEdgesMap.end() && "call instruction does not have a valid callee");
240 return it->second.end();
241 }
243 {
244 for(CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.begin(), eit = callinstToThreadJoinEdgesMap.end(); it!=eit; ++it)
245 {
246 for(JoinEdgeSet::const_iterator jit = it->second.begin(), ejit = it->second.end(); jit!=ejit; ++jit)
247 {
248 if((*jit)->getDstNode() == routine)
249 {
250 csSet.insert(it->first);
251 }
252 }
253 }
254 }
256
259 inline bool isForksite(const CallICFGNode* csInst)
260 {
261 return forksites.find(csInst) != forksites.end();
262 }
263 inline bool isJoinsite(const CallICFGNode* csInst)
264 {
265 return joinsites.find(csInst) != joinsites.end();
266 }
267 inline bool isParForSite(const CallICFGNode* csInst)
268 {
269 return parForSites.find(csInst) != parForSites.end();
270 }
272
274
275 inline CallSiteSet::const_iterator forksitesBegin() const
276 {
277 return forksites.begin();
278 }
279 inline CallSiteSet::const_iterator forksitesEnd() const
280 {
281 return forksites.end();
282 }
284
286
287 inline CallSiteSet::const_iterator joinsitesBegin() const
288 {
289 return joinsites.begin();
290 }
291 inline CallSiteSet::const_iterator joinsitesEnd() const
292 {
293 return joinsites.end();
294 }
296
298
299 inline CallSiteSet::const_iterator parForSitesBegin() const
300 {
301 return parForSites.begin();
302 }
303 inline CallSiteSet::const_iterator parForSitesEnd() const
304 {
305 return parForSites.end();
306 }
308
310
311 inline u32_t getNumOfForksite() const
312 {
313 return forksites.size();
314 }
315 inline u32_t getNumOfJoinsite() const
316 {
317 return joinsites.size();
318 }
320 {
321 return parForSites.size();
322 }
324
326 inline ThreadAPI* getThreadAPI() const
327 {
328 return tdAPI;
329 }
330
332
333 inline bool addForksite(const CallICFGNode* cs)
334 {
336 return forksites.insert(cs).second;
337 }
338 inline bool addJoinsite(const CallICFGNode* cs)
339 {
341 return joinsites.insert(cs).second;
342 }
343 inline bool addParForSite(const CallICFGNode* cs)
344 {
346 return parForSites.insert(cs).second;
347 }
349
351
352 bool addDirectForkEdge(const CallICFGNode* cs);
353 bool addIndirectForkEdge(const CallICFGNode* cs, const SVFFunction* callee);
355
357
358 void addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet& forksite);
360
361
364 {
365 if(edge!=nullptr)
366 {
369 }
370 }
371
374 {
375 if(edge!=nullptr)
376 {
379 }
380 }
381
384 {
385 if(edge!=nullptr)
386 {
389 }
390 }
391
394 {
396 CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(call);
398 {
399 JoinEdgeSet::const_iterator jit = it->second.find(&joinEdge);
400 if(jit!=it->second.end())
401 return *jit;
402 }
403 return nullptr;
404 }
405
406private:
414};
415
416} // End namespace SVF
417
418#endif /* RCG_H_ */
NodeType * getSrcNode() const
NodeType * getDstNode() const
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
HareParForEdge(PTACallGraphNode *s, PTACallGraphNode *d, CallSiteID csId)
Constructor.
virtual ~HareParForEdge()
Destructor.
GenericNode< PTACallGraphNode, HareParForEdge >::GEdgeSetTy ParForEdgeSet
static bool classof(const HareParForEdge *)
ClassOf.
static bool classof(const PTACallGraphEdge *edge)
CallSiteID getCallSiteID() const
Get direct and indirect calls.
CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap
Map a call instruction to its corresponding call edges.
bool isForksite(const CallICFGNode *csInst)
CallSiteSet::const_iterator forksitesEnd() const
bool addIndirectForkEdge(const CallICFGNode *cs, const SVFFunction *callee)
CallSiteSet::const_iterator parForSitesBegin() const
hare_parallel_for sites iterators
bool addDirectForkEdge(const CallICFGNode *cs)
Add direct/indirect thread fork edges.
Set< CallSiteSet * > CtxSet
CallSiteSet::const_iterator forksitesBegin() const
Fork sites iterators.
CallInstToParForEdgesMap callinstToHareParForEdgesMap
Map a call instruction to its corresponding hare_parallel_for edges.
void updateJoinEdge(PointerAnalysis *pta)
Update join edge using pointer analysis results.
static bool classof(const ThreadCallGraph *)
ClassOf.
CallSiteSet::const_iterator joinsitesEnd() const
CallSiteSet::const_iterator parForSitesEnd() const
bool addForksite(const CallICFGNode *cs)
Add fork sites which directly or indirectly create a thread.
Set< const CallICFGNode * > InstSet
static bool classof(const PTACallGraph *g)
bool hasThreadJoinEdge(const CallICFGNode *cs) const
Get call graph edge via call instruction.
ThreadJoinEdge * hasThreadJoinEdge(const CallICFGNode *call, PTACallGraphNode *joinFunNode, PTACallGraphNode *threadRoutineFunNode, CallSiteID csId) const
has thread join edge
bool addParForSite(const CallICFGNode *cs)
CallSiteSet forksites
all thread fork sites
CallSiteSet parForSites
all parallel for sites
void addThreadJoinEdgeSetMap(const CallICFGNode *cs, ThreadJoinEdge *edge)
map call instruction to its PTACallGraphEdge map
u32_t getNumOfJoinsite() const
bool addJoinsite(const CallICFGNode *cs)
virtual ~ThreadCallGraph()
Destructor.
CallInstToForkEdgesMap callinstToThreadForkEdgesMap
Map a call instruction to its corresponding fork edges.
JoinEdgeSet::const_iterator getJoinEdgeEnd(const CallICFGNode *cs) const
ForkEdgeSet::const_iterator getForkEdgeEnd(const CallICFGNode *cs) const
ForkEdgeSet::const_iterator getForkEdgeBegin(const CallICFGNode *cs) const
void addDirectJoinEdge(const CallICFGNode *cs, const CallSiteSet &forksite)
Add thread join edges.
bool hasThreadForkEdge(const CallICFGNode *cs) const
Get call graph edge via call instruction.
CallSiteSet::const_iterator joinsitesBegin() const
Join sites iterators.
ThreadForkEdge::ForkEdgeSet ForkEdgeSet
u32_t getNumOfForksite() const
Num of fork/join sites.
void getJoinSites(const PTACallGraphNode *routine, InstSet &csSet)
ThreadAPI * getThreadAPI() const
Thread API.
ThreadJoinEdge::JoinEdgeSet JoinEdgeSet
CallSiteSet joinsites
all thread fork sites
void addHareParForEdgeSetMap(const CallICFGNode *cs, HareParForEdge *edge)
map call instruction to its PTACallGraphEdge map
void addThreadForkEdgeSetMap(const CallICFGNode *cs, ThreadForkEdge *edge)
map call instruction to its PTACallGraphEdge map
Map< const CallICFGNode *, JoinEdgeSet > CallInstToJoinEdgesMap
Map< const CallICFGNode *, ParForEdgeSet > CallInstToParForEdgesMap
HareParForEdge::ParForEdgeSet ParForEdgeSet
bool isJoinsite(const CallICFGNode *csInst)
ThreadCallGraph(ThreadCallGraph &cg)=delete
u32_t getNumOfParForSite() const
bool isParForSite(const CallICFGNode *csInst)
void updateCallGraph(PointerAnalysis *pta)
Update call graph using pointer results.
Map< const CallICFGNode *, ForkEdgeSet > CallInstToForkEdgesMap
ThreadAPI * tdAPI
Thread API.
CallInstToJoinEdgesMap callinstToThreadJoinEdgesMap
Map a call instruction to its corresponding join edges.
JoinEdgeSet::const_iterator getJoinEdgeBegin(const CallICFGNode *cs) const
static bool classof(const ThreadForkEdge *)
ClassOf.
virtual ~ThreadForkEdge()
Destructor.
virtual const std::string toString() const
GenericNode< PTACallGraphNode, ThreadForkEdge >::GEdgeSetTy ForkEdgeSet
static bool classof(const PTACallGraphEdge *edge)
ThreadForkEdge(PTACallGraphNode *s, PTACallGraphNode *d, CallSiteID csId)
Constructor.
virtual ~ThreadJoinEdge()
Destructor.
static bool classof(const ThreadJoinEdge *)
virtual const std::string toString() const
GenericNode< PTACallGraphNode, ThreadJoinEdge >::GEdgeSetTy JoinEdgeSet
ThreadJoinEdge(PTACallGraphNode *s, PTACallGraphNode *d, CallSiteID csId)
Constructor.
static bool classof(const PTACallGraphEdge *edge)
for isBitcode
Definition BasicTypes.h:68
unsigned CallSiteID
Definition GeneralType.h:58
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:46