Skip to content

Commit 4bd055b

Browse files
smowtonpeterschrammel
authored andcommitted
Style and document call graph
1 parent af7599f commit 4bd055b

File tree

2 files changed

+211
-78
lines changed

2 files changed

+211
-78
lines changed

src/analyses/call_graph.cpp

+179-46
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ void call_grapht::output_dot(std::ostream &out) const
123123

124124

125125
void call_grapht::output_dot(
126-
goto_functionst const &functions,
126+
const goto_functionst &functions,
127127
std::ostream &out) const
128128
{
129129
out << "digraph call_graph {\n";
130-
for(auto const &elem : functions.function_map)
130+
for(const auto &elem : functions.function_map)
131131
out << " \"" << elem.first << "\";\n";
132132
for(grapht::const_iterator it=graph.begin();
133133
it!=graph.end();
@@ -186,26 +186,52 @@ void call_grapht::output_xml(std::ostream &out) const
186186
}
187187
}
188188

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+
\*******************************************************************/
189200

190201
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
192203
{
193204
return graph.equal_range(caller);
194205
}
195206

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
196214
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,
200226
std::unordered_set<irep_idt, dstring_hash> &processed_functions,
201227
std::vector<irep_idt> &output)
202228
{
203-
if(processed_functions.count(start_function) != 0ULL)
229+
if(processed_functions.count(start_function)!=0ULL)
204230
return;
205231
processed_functions.insert(start_function);
206-
call_grapht::call_edges_ranget const range =
232+
const call_grapht::call_edges_ranget range =
207233
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)
209235
inverted_partial_topological_order(
210236
call_graph,
211237
it->second,
@@ -214,99 +240,206 @@ void inverted_partial_topological_order(
214240
output.push_back(start_function);
215241
}
216242

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+
217259
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,
220262
std::vector<irep_idt>& output)
221263
{
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)
224266
inverted_partial_topological_order(
225267
call_graph,
226268
elem.first,
227269
processed,
228270
output);
229271
}
230272

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+
231288
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)
235292
{
236-
call_grapht::call_edges_ranget const range =
293+
const call_grapht::call_edges_ranget range =
237294
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)
240297
return true;
241298
return false;
242299
}
243300

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+
244319
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,
248323
std::unordered_set<irep_idt, dstring_hash> &ignored_functions)
249324
{
250-
if(ignored_functions.count(caller) != 0UL)
325+
if(ignored_functions.count(caller)!=0UL)
251326
return false;
252327
ignored_functions.insert(caller);
253328
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=
256331
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)
258333
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))
263338
return true;
264339
return false;
265340
}
266341

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+
267357
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)
271361
{
272362
std::unordered_set<irep_idt, dstring_hash> ignored;
273363
return exists_direct_or_indirect_call(call_graph, caller, callee, ignored);
274364
}
275365

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+
276379
void compute_inverted_call_graph(
277-
call_grapht const &original_call_graph,
380+
const call_grapht &original_call_graph,
278381
call_grapht &output_inverted_call_graph)
279382
{
280383
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)
282385
output_inverted_call_graph.add(elem.second, elem.first);
283386
}
284387

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,
288408
std::unordered_set<irep_idt, dstring_hash> &to_avoid,
289409
std::unordered_set<irep_idt, dstring_hash> &output)
290410
{
291-
if(to_avoid.count(function) != 0UL)
411+
if(to_avoid.count(function)!=0UL)
292412
return;
293413
to_avoid.insert(function);
294-
call_grapht::call_edges_ranget const range =
414+
const call_grapht::call_edges_ranget range =
295415
call_graph.out_edges(function);
296-
if(range.first == range.second)
416+
if(range.first==range.second)
297417
output.insert(function);
298418
else
299419
{
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);
302422
}
303423
}
304424

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+
305438
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,
308441
std::unordered_set<irep_idt, dstring_hash> &output)
309442
{
310443
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);
312445
}

0 commit comments

Comments
 (0)