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/CallGraph.h"
34
35namespace SVF
36{
37
38class ThreadAPI;
39class PointerAnalysis;
44{
45
46public:
54 {
55 }
56
58
59 static inline bool classof(const ThreadForkEdge*)
60 {
61 return true;
62 }
63 static inline bool classof(const CallGraphEdge*edge)
64 {
65 return edge->getEdgeKind() == CallGraphEdge::TDForkEdge;
66 }
68
69 virtual const std::string toString() const;
70
72};
73
78{
79
80public:
88 {
89 }
90
91 static inline bool classof(const ThreadJoinEdge*)
92 {
93 return true;
94 }
95 static inline bool classof(const CallGraphEdge*edge)
96 {
97 return edge->getEdgeKind() == CallGraphEdge::TDJoinEdge;
98 }
99
100 virtual const std::string toString() const;
101
103};
104
109{
110
111public:
119 {
120 }
121
123
124 static inline bool classof(const HareParForEdge*)
125 {
126 return true;
127 }
128 static inline bool classof(const CallGraphEdge*edge)
129 {
130 return edge->getEdgeKind() == CallGraphEdge::HareParForEdge;
131 }
133
135};
136
137
142{
143
144public:
150 {
151 bool operator()(const CallICFGNode* lhs, const CallICFGNode* rhs) const
152 {
153 return lhs->getId() < rhs->getId();
154 }
155 };
165
168
170
172 virtual ~ThreadCallGraph();
173
175
176 static inline bool classof(const ThreadCallGraph *)
177 {
178 return true;
179 }
180 static inline bool classof(const CallGraph*g)
181 {
182 return g->getKind() == CallGraph::ThdCallGraph;
183 }
185
190
191
193
194
195 inline bool hasThreadForkEdge(const CallICFGNode* cs) const
196 {
197 return callinstToThreadForkEdgesMap.find(cs) !=
199 }
200 inline ForkEdgeSet::const_iterator getForkEdgeBegin(const CallICFGNode* cs) const
201 {
202 CallInstToForkEdgesMap::const_iterator it = callinstToThreadForkEdgesMap.find(cs);
203 assert(it != callinstToThreadForkEdgesMap.end() && "call instruction not found");
204 return it->second.begin();
205 }
206 inline ForkEdgeSet::const_iterator getForkEdgeEnd(const CallICFGNode* cs) const
207 {
208 CallInstToForkEdgesMap::const_iterator it = callinstToThreadForkEdgesMap.find(cs);
209 assert(it != callinstToThreadForkEdgesMap.end() && "call instruction not found");
210 return it->second.end();
211 }
212
214
215
216 inline bool hasThreadJoinEdge(const CallICFGNode* cs) const
217 {
219 }
220 inline JoinEdgeSet::const_iterator getJoinEdgeBegin(const CallICFGNode* cs) const
221 {
222 CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(cs);
223 assert(it != callinstToThreadJoinEdgesMap.end() && "call instruction does not have a valid callee");
224 return it->second.begin();
225 }
226 inline JoinEdgeSet::const_iterator getJoinEdgeEnd(const CallICFGNode* cs) const
227 {
228 CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(cs);
229 assert(it != callinstToThreadJoinEdgesMap.end() && "call instruction does not have a valid callee");
230 return it->second.end();
231 }
233 {
234 for(CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.begin(), eit = callinstToThreadJoinEdgesMap.end(); it!=eit; ++it)
235 {
236 for(JoinEdgeSet::const_iterator jit = it->second.begin(), ejit = it->second.end(); jit!=ejit; ++jit)
237 {
238 if((*jit)->getDstNode() == routine)
239 {
240 csSet.insert(it->first);
241 }
242 }
243 }
244 }
246
249 inline bool isForksite(const CallICFGNode* csInst)
250 {
251 return forksites.find(csInst) != forksites.end();
252 }
253 inline bool isJoinsite(const CallICFGNode* csInst)
254 {
255 return joinsites.find(csInst) != joinsites.end();
256 }
257 inline bool isParForSite(const CallICFGNode* csInst)
258 {
259 return parForSites.find(csInst) != parForSites.end();
260 }
262
264
265 inline CallSiteSet::const_iterator forksitesBegin() const
266 {
267 return forksites.begin();
268 }
269 inline CallSiteSet::const_iterator forksitesEnd() const
270 {
271 return forksites.end();
272 }
274
276
277 inline CallSiteSet::const_iterator joinsitesBegin() const
278 {
279 return joinsites.begin();
280 }
281 inline CallSiteSet::const_iterator joinsitesEnd() const
282 {
283 return joinsites.end();
284 }
286
288
289 inline CallSiteSet::const_iterator parForSitesBegin() const
290 {
291 return parForSites.begin();
292 }
293 inline CallSiteSet::const_iterator parForSitesEnd() const
294 {
295 return parForSites.end();
296 }
298
300
301 inline u32_t getNumOfForksite() const
302 {
303 return forksites.size();
304 }
305 inline u32_t getNumOfJoinsite() const
306 {
307 return joinsites.size();
308 }
310 {
311 return parForSites.size();
312 }
314
316 inline ThreadAPI* getThreadAPI() const
317 {
318 return tdAPI;
319 }
320
322
323 inline bool addForksite(const CallICFGNode* cs)
324 {
326 return forksites.insert(cs).second;
327 }
328 inline bool addJoinsite(const CallICFGNode* cs)
329 {
331 return joinsites.insert(cs).second;
332 }
333 inline bool addParForSite(const CallICFGNode* cs)
334 {
336 return parForSites.insert(cs).second;
337 }
339
341
342 bool addDirectForkEdge(const CallICFGNode* cs);
343 bool addIndirectForkEdge(const CallICFGNode* cs, const FunObjVar* callee);
345
347
348 void addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet& forksite);
350
351
354 {
355 if(edge!=nullptr)
356 {
359 }
360 }
361
364 {
365 if(edge!=nullptr)
366 {
369 }
370 }
371
374 {
375 if(edge!=nullptr)
376 {
379 }
380 }
381
384 {
386 CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(call);
387 if(it != callinstToThreadJoinEdgesMap.end())
388 {
389 JoinEdgeSet::const_iterator jit = it->second.find(&joinEdge);
390 if(jit!=it->second.end())
391 return *jit;
392 }
393 return nullptr;
394 }
395
396private:
404};
405
406} // End namespace SVF
407
408#endif /* RCG_H_ */
CallSiteID csId
Definition CallGraph.h:65
CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap
Map a call instruction to its corresponding call edges.
Definition CallGraph.h:268
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
GenericNode< CallGraphNode, HareParForEdge >::GEdgeSetTy ParForEdgeSet
HareParForEdge(CallGraphNode *s, CallGraphNode *d, CallSiteID csId)
Constructor.
virtual ~HareParForEdge()
Destructor.
static bool classof(const HareParForEdge *)
ClassOf.
static bool classof(const CallGraphEdge *edge)
bool isForksite(const CallICFGNode *csInst)
OrderedSet< const CallICFGNode *, CallSiteIdCmp > InstSet
CallSiteSet::const_iterator forksitesEnd() const
CallSiteSet::const_iterator parForSitesBegin() const
hare_parallel_for sites iterators
bool addDirectForkEdge(const CallICFGNode *cs)
Add direct/indirect thread fork edges.
Set< CallSiteSet * > CtxSet
virtual ~ThreadCallGraph()
Destructor.
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.
bool hasThreadJoinEdge(const CallICFGNode *cs) const
Get call graph edge via call instruction.
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)
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 addIndirectForkEdge(const CallICFGNode *cs, const FunObjVar *callee)
bool hasThreadForkEdge(const CallICFGNode *cs) const
Get call graph edge via call instruction.
CallSiteSet::const_iterator joinsitesBegin() const
Join sites iterators.
ThreadJoinEdge * hasThreadJoinEdge(const CallICFGNode *call, CallGraphNode *joinFunNode, CallGraphNode *threadRoutineFunNode, CallSiteID csId) const
has thread join edge
ThreadForkEdge::ForkEdgeSet ForkEdgeSet
u32_t getNumOfForksite() const
Num of fork/join sites.
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)
static bool classof(const CallGraph *g)
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.
void getJoinSites(const CallGraphNode *routine, InstSet &csSet)
JoinEdgeSet::const_iterator getJoinEdgeBegin(const CallICFGNode *cs) const
static bool classof(const ThreadForkEdge *)
ClassOf.
virtual ~ThreadForkEdge()
Destructor.
ThreadForkEdge(CallGraphNode *s, CallGraphNode *d, CallSiteID csId)
Constructor.
static bool classof(const CallGraphEdge *edge)
GenericNode< CallGraphNode, ThreadForkEdge >::GEdgeSetTy ForkEdgeSet
virtual const std::string toString() const
virtual ~ThreadJoinEdge()
Destructor.
static bool classof(const ThreadJoinEdge *)
virtual const std::string toString() const
static bool classof(const CallGraphEdge *edge)
ThreadJoinEdge(CallGraphNode *s, CallGraphNode *d, CallSiteID csId)
Constructor.
GenericNode< CallGraphNode, ThreadJoinEdge >::GEdgeSetTy JoinEdgeSet
for isBitcode
Definition BasicTypes.h:70
unsigned CallSiteID
Definition GeneralType.h:78
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:67
bool operator()(const CallICFGNode *lhs, const CallICFGNode *rhs) const