@@ -123,11 +123,11 @@ void call_grapht::output_dot(std::ostream &out) const
123
123
124
124
125
125
void call_grapht::output_dot (
126
- goto_functionst const &functions,
126
+ const goto_functionst &functions,
127
127
std::ostream &out) const
128
128
{
129
129
out << " digraph call_graph {\n " ;
130
- for (auto const &elem : functions.function_map )
130
+ for (const auto &elem : functions.function_map )
131
131
out << " \" " << elem.first << " \" ;\n " ;
132
132
for (grapht::const_iterator it=graph.begin ();
133
133
it!=graph.end ();
@@ -186,26 +186,52 @@ void call_grapht::output_xml(std::ostream &out) const
186
186
}
187
187
}
188
188
189
+ /* ******************************************************************\
190
+
191
+ Function: call_grapht::out_edges
192
+
193
+ Inputs: `caller`: node to search for
194
+
195
+ Outputs: Returns list of edges whose first component is `caller`.
196
+
197
+ Purpose:
198
+
199
+ \*******************************************************************/
189
200
190
201
call_grapht::call_edges_ranget
191
- call_grapht::out_edges (irep_idt const &caller) const
202
+ call_grapht::out_edges (const irep_idt &caller) const
192
203
{
193
204
return graph.equal_range (caller);
194
205
}
195
206
207
+ /* ******************************************************************\
208
+
209
+ Function: inverted_partial_topological_order
210
+
211
+ Inputs: `call_graph`: Call graph
212
+ `start_function`: start node, must occur in call graph
213
+ `processed_functions`: set of functions already seen
196
214
197
- void inverted_partial_topological_order (
198
- call_grapht const &call_graph,
199
- irep_idt const &start_function,
215
+ Outputs: `output`: inverted topological sort of the graph reachable
216
+ from start node (i.e. leaves first, root last)
217
+ `processed_functions`: set of functions already seen
218
+
219
+ Purpose: Get reverse-top-sorted subgraph
220
+
221
+ \*******************************************************************/
222
+
223
+ void inverted_partial_topological_order (
224
+ const call_grapht &call_graph,
225
+ const irep_idt &start_function,
200
226
std::unordered_set<irep_idt, dstring_hash> &processed_functions,
201
227
std::vector<irep_idt> &output)
202
228
{
203
- if (processed_functions.count (start_function) != 0ULL )
229
+ if (processed_functions.count (start_function)!= 0ULL )
204
230
return ;
205
231
processed_functions.insert (start_function);
206
- call_grapht::call_edges_ranget const range =
232
+ const call_grapht::call_edges_ranget range =
207
233
call_graph.out_edges (start_function);
208
- for (auto it = range.first ; it != range.second ; ++it)
234
+ for (auto it= range.first ; it!= range.second ; ++it)
209
235
inverted_partial_topological_order (
210
236
call_graph,
211
237
it->second ,
@@ -214,99 +240,206 @@ void inverted_partial_topological_order(
214
240
output.push_back (start_function);
215
241
}
216
242
243
+ /* ******************************************************************\
244
+
245
+ Function: get_inverted_topological_order
246
+
247
+ Inputs: `call_graph`: Call graph
248
+ `functions`: map containing all functions of interest;
249
+ only function names are used to index into call graph;
250
+ function bodies are ignored.
251
+
252
+ Outputs: `output`: inverted topological sort of the graph reachable
253
+ from start node (i.e. leaves first, root last)
254
+
255
+ Purpose: Get reverse-top-sorted call graph
256
+
257
+ \*******************************************************************/
258
+
217
259
void get_inverted_topological_order (
218
- call_grapht const & call_graph,
219
- goto_functionst const & functions,
260
+ const call_grapht & call_graph,
261
+ const goto_functionst & functions,
220
262
std::vector<irep_idt>& output)
221
263
{
222
- std::unordered_set<irep_idt, dstring_hash> processed;
223
- for (auto const &elem : functions.function_map )
264
+ std::unordered_set<irep_idt, dstring_hash> processed;
265
+ for (const auto &elem : functions.function_map )
224
266
inverted_partial_topological_order (
225
267
call_graph,
226
268
elem.first ,
227
269
processed,
228
270
output);
229
271
}
230
272
273
+ /* ******************************************************************\
274
+
275
+ Function: exists_direct_call
276
+
277
+ Inputs: `call_graph`: Call graph
278
+ `caller`: Caller
279
+ `callee`: Potential callee
280
+
281
+ Outputs: Returns true if call graph says caller calls callee.
282
+
283
+ Purpose: See output
284
+
285
+ \*******************************************************************/
286
+
287
+
231
288
bool exists_direct_call (
232
- call_grapht const &call_graph,
233
- irep_idt const &caller,
234
- irep_idt const &callee)
289
+ const call_grapht &call_graph,
290
+ const irep_idt &caller,
291
+ const irep_idt &callee)
235
292
{
236
- call_grapht::call_edges_ranget const range =
293
+ const call_grapht::call_edges_ranget range =
237
294
call_graph.out_edges (caller);
238
- for (auto it = range.first ; it != range.second ; ++it)
239
- if (callee == it->second )
295
+ for (auto it= range.first ; it!= range.second ; ++it)
296
+ if (callee== it->second )
240
297
return true ;
241
298
return false ;
242
299
}
243
300
301
+ /* ******************************************************************\
302
+
303
+ Function: exists_direct_or_indirect_call
304
+
305
+ Inputs: `call_graph`: Call graph
306
+ `caller`: Caller
307
+ `callee`: Potential callee
308
+ `ignored_functions`: Functions to exclude from call graph
309
+ for the purposes of finding a path
310
+
311
+ Outputs: Returns true if call graph says caller can reach callee
312
+ via any intermediate sequence of callees not occurring
313
+ in ignored_functions
314
+
315
+ Purpose: See output
316
+
317
+ \*******************************************************************/
318
+
244
319
bool exists_direct_or_indirect_call (
245
- call_grapht const &call_graph,
246
- irep_idt const &caller,
247
- irep_idt const &callee,
320
+ const call_grapht &call_graph,
321
+ const irep_idt &caller,
322
+ const irep_idt &callee,
248
323
std::unordered_set<irep_idt, dstring_hash> &ignored_functions)
249
324
{
250
- if (ignored_functions.count (caller) != 0UL )
325
+ if (ignored_functions.count (caller)!= 0UL )
251
326
return false ;
252
327
ignored_functions.insert (caller);
253
328
if (exists_direct_call (call_graph, caller, callee))
254
- return ignored_functions.count (callee) == 0UL ;
255
- call_grapht::call_edges_ranget const range =
329
+ return ignored_functions.count (callee)== 0UL ;
330
+ const call_grapht::call_edges_ranget range=
256
331
call_graph.out_edges (caller);
257
- for (auto it = range.first ; it != range.second ; ++it)
332
+ for (auto it= range.first ; it!= range.second ; ++it)
258
333
if (exists_direct_or_indirect_call (
259
- call_graph,
260
- it->second ,
261
- callee,
262
- ignored_functions))
334
+ call_graph,
335
+ it->second ,
336
+ callee,
337
+ ignored_functions))
263
338
return true ;
264
339
return false ;
265
340
}
266
341
342
+ /* ******************************************************************\
343
+
344
+ Function: exists_direct_or_indirect_call
345
+
346
+ Inputs: `call_graph`: Call graph
347
+ `caller`: Caller
348
+ `callee`: Potential callee
349
+
350
+ Outputs: Returns true if call graph says caller can reach callee
351
+ via any intermediate sequence of callees
352
+
353
+ Purpose: See output
354
+
355
+ \*******************************************************************/
356
+
267
357
bool exists_direct_or_indirect_call (
268
- call_grapht const &call_graph,
269
- irep_idt const &caller,
270
- irep_idt const &callee)
358
+ const call_grapht &call_graph,
359
+ const irep_idt &caller,
360
+ const irep_idt &callee)
271
361
{
272
362
std::unordered_set<irep_idt, dstring_hash> ignored;
273
363
return exists_direct_or_indirect_call (call_graph, caller, callee, ignored);
274
364
}
275
365
366
+ /* ******************************************************************\
367
+
368
+ Function: computed_inverted_call_graph
369
+
370
+ Inputs: `original_call_graph`: call graph
371
+
372
+ Outputs: `output_inverted_call_graph`: input call graph with caller->
373
+ callee edges reversed.
374
+
375
+ Purpose: See output
376
+
377
+ \*******************************************************************/
378
+
276
379
void compute_inverted_call_graph (
277
- call_grapht const &original_call_graph,
380
+ const call_grapht &original_call_graph,
278
381
call_grapht &output_inverted_call_graph)
279
382
{
280
383
assert (output_inverted_call_graph.graph .empty ());
281
- for (auto const &elem : original_call_graph.graph )
384
+ for (const auto &elem : original_call_graph.graph )
282
385
output_inverted_call_graph.add (elem.second , elem.first );
283
386
}
284
387
285
- void find_leaves_bellow_function (
286
- call_grapht const &call_graph,
287
- irep_idt const &function,
388
+ /* ******************************************************************\
389
+
390
+ Function: find_leaves_below_function
391
+
392
+ Inputs: `call_graph`: call graph
393
+ `function`: start node
394
+ `to_avoid`: functions already visited
395
+
396
+ Outputs: `output`: set of leaves reachable from 'function'
397
+ `to_avoid`: functions already visited (with 'function'
398
+ added)
399
+
400
+ Purpose: See output
401
+
402
+ \*******************************************************************/
403
+
404
+
405
+ void find_leaves_below_function (
406
+ const call_grapht &call_graph,
407
+ const irep_idt &function,
288
408
std::unordered_set<irep_idt, dstring_hash> &to_avoid,
289
409
std::unordered_set<irep_idt, dstring_hash> &output)
290
410
{
291
- if (to_avoid.count (function) != 0UL )
411
+ if (to_avoid.count (function)!= 0UL )
292
412
return ;
293
413
to_avoid.insert (function);
294
- call_grapht::call_edges_ranget const range =
414
+ const call_grapht::call_edges_ranget range =
295
415
call_graph.out_edges (function);
296
- if (range.first == range.second )
416
+ if (range.first == range.second )
297
417
output.insert (function);
298
418
else
299
419
{
300
- for (auto it = range.first ; it != range.second ; ++it)
301
- find_leaves_bellow_function (call_graph, it->second , to_avoid, output);
420
+ for (auto it= range.first ; it!= range.second ; ++it)
421
+ find_leaves_below_function (call_graph, it->second , to_avoid, output);
302
422
}
303
423
}
304
424
425
+ /* ******************************************************************\
426
+
427
+ Function: find_leaves_below_function
428
+
429
+ Inputs: `call_graph`: call graph
430
+ `function`: start node
431
+
432
+ Outputs: `output`: set of leaves reachable from 'function'
433
+
434
+ Purpose: See output
435
+
436
+ \*******************************************************************/
437
+
305
438
void find_leaves_below_function (
306
- call_grapht const &call_graph,
307
- irep_idt const &function,
439
+ const call_grapht &call_graph,
440
+ const irep_idt &function,
308
441
std::unordered_set<irep_idt, dstring_hash> &output)
309
442
{
310
443
std::unordered_set<irep_idt, dstring_hash> to_avoid;
311
- find_leaves_bellow_function (call_graph, function, to_avoid, output);
444
+ find_leaves_below_function (call_graph, function, to_avoid, output);
312
445
}
0 commit comments