CBMC
call_graph_helpers.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Function Call Graph Helpers
4 
5 Author: Chris Smowton, chris.smowton@diffblue.com
6 
7 \*******************************************************************/
8 
11 
12 #include "call_graph_helpers.h"
13 
18 static std::set<irep_idt> get_neighbours(
19  const call_grapht::directed_grapht &graph,
20  const irep_idt &function,
21  bool forwards)
22 {
23  std::set<irep_idt> result;
24  const auto &fnode = graph[*(graph.get_node_index(function))];
25  const auto &neighbours = forwards ? fnode.out : fnode.in;
26  for(const auto &succ_edge : neighbours)
27  result.insert(graph[succ_edge.first].function);
28  return result;
29 }
30 
31 std::set<irep_idt> get_callees(
32  const call_grapht::directed_grapht &graph, const irep_idt &function)
33 {
34  return get_neighbours(graph, function, true);
35 }
36 
37 std::set<irep_idt> get_callers(
38  const call_grapht::directed_grapht &graph, const irep_idt &function)
39 {
40  return get_neighbours(graph, function, false);
41 }
42 
49 static std::set<irep_idt> get_connected_functions(
50  const call_grapht::directed_grapht &graph,
51  const irep_idt &function,
52  bool forwards)
53 {
54  std::vector<call_grapht::directed_grapht::node_indext> connected_nodes =
55  graph.get_reachable(*(graph.get_node_index(function)), forwards);
56  std::set<irep_idt> result;
57  for(const auto i : connected_nodes)
58  result.insert(graph[i].function);
59  return result;
60 }
61 
62 std::set<irep_idt> get_reachable_functions(
63  const call_grapht::directed_grapht &graph, const irep_idt &function)
64 {
65  return get_connected_functions(graph, function, true);
66 }
67 
68 std::set<irep_idt> get_reaching_functions(
69  const call_grapht::directed_grapht &graph, const irep_idt &function)
70 {
71  return get_connected_functions(graph, function, false);
72 }
73 
75  const call_grapht::directed_grapht &graph,
76  const std::set<irep_idt> &start_functions,
77  std::size_t n)
78 {
79  std::vector<std::size_t> start_indices;
80  std::set<irep_idt> result;
81 
82  for(const auto &func : start_functions)
83  start_indices.push_back(*(graph.get_node_index(func)));
84 
85  for(const auto &index : graph.depth_limited_search(start_indices, n))
86  result.insert(graph[index].function);
87 
88  return result;
89 }
90 
92  const call_grapht::directed_grapht &graph,
93  const irep_idt &start_function,
94  std::size_t n)
95 {
96  std::set<irep_idt> start_functions({start_function});
97  return get_functions_reachable_within_n_steps(graph, start_functions, n);
98 }
99 
102  const irep_idt &function)
103 {
104  graph.disconnect_unreachable(*(graph.get_node_index(function)));
105 }
106 
107 std::list<irep_idt> get_shortest_function_path(
108  const call_grapht::directed_grapht &graph,
109  const irep_idt &src,
110  const irep_idt &dest)
111 {
112  std::list<irep_idt> result;
113  std::list<std::size_t> path;
114 
115  graph.shortest_path(
116  *(graph.get_node_index(src)), *(graph.get_node_index(dest)), path);
117 
118  for(const auto &n : path)
119  result.push_back(graph[n].function);
120 
121  return result;
122 }
std::set< irep_idt > get_reaching_functions(const call_grapht::directed_grapht &graph, const irep_idt &function)
Get functions that can reach a given function.
std::set< irep_idt > get_reachable_functions(const call_grapht::directed_grapht &graph, const irep_idt &function)
Get functions reachable from a given function.
std::set< irep_idt > get_callees(const call_grapht::directed_grapht &graph, const irep_idt &function)
Get functions directly callable from a given function.
static std::set< irep_idt > get_neighbours(const call_grapht::directed_grapht &graph, const irep_idt &function, bool forwards)
Get either callers or callees of a given function.
std::list< irep_idt > get_shortest_function_path(const call_grapht::directed_grapht &graph, const irep_idt &src, const irep_idt &dest)
Get list of functions on the shortest path between two functions.
void disconnect_unreachable_functions(call_grapht::directed_grapht &graph, const irep_idt &function)
Disconnects all functions in the call graph that are unreachable from a given start function.
std::set< irep_idt > get_functions_reachable_within_n_steps(const call_grapht::directed_grapht &graph, const std::set< irep_idt > &start_functions, std::size_t n)
Get either callers or callees reachable from a given list of functions within N steps.
std::set< irep_idt > get_callers(const call_grapht::directed_grapht &graph, const irep_idt &function)
Get functions that call a given function.
static std::set< irep_idt > get_connected_functions(const call_grapht::directed_grapht &graph, const irep_idt &function, bool forwards)
Get either reachable functions or functions that can reach a given function.
Function Call Graph Helpers.
Directed graph representation of this call graph.
Definition: call_graph.h:140
std::optional< node_indext > get_node_index(const irep_idt &function) const
Find the graph node by function name.
Definition: call_graph.cpp:300
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
std::vector< node_indext > get_reachable(node_indext src, bool forwards) const
Run depth-first search on the graph, starting from a single source node.
Definition: graph.h:602
std::vector< typename N::node_indext > depth_limited_search(typename N::node_indext src, std::size_t limit) const
Run recursive depth-limited search on the graph, starting from multiple source nodes,...
Definition: graph.h:653
void shortest_path(node_indext src, node_indext dest, patht &path) const
Definition: graph.h:267
void disconnect_unreachable(node_indext src)
Removes any edges between nodes in a graph that are unreachable from a given start node.
Definition: graph.h:527
const edgest & out(node_indext n) const
Definition: graph.h:227