1 1.1 mrg /* Trimming an exploded graph to a subset of nodes and edges. 2 1.1 mrg Copyright (C) 2021-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by David Malcolm <dmalcolm (at) redhat.com>. 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify it 8 1.1 mrg under the terms of the GNU General Public License as published by 9 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 10 1.1 mrg any later version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, but 13 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 1.1 mrg General Public License for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg #include "config.h" 22 1.1 mrg #include "system.h" 23 1.1 mrg #include "coretypes.h" 24 1.1 mrg #include "tree.h" 25 1.1 mrg #include "pretty-print.h" 26 1.1 mrg #include "gcc-rich-location.h" 27 1.1 mrg #include "gimple-pretty-print.h" 28 1.1 mrg #include "function.h" 29 1.1 mrg #include "diagnostic-core.h" 30 1.1 mrg #include "diagnostic-event-id.h" 31 1.1 mrg #include "diagnostic-path.h" 32 1.1 mrg #include "alloc-pool.h" 33 1.1 mrg #include "fibonacci_heap.h" 34 1.1 mrg #include "shortest-paths.h" 35 1.1 mrg #include "sbitmap.h" 36 1.1 mrg #include "bitmap.h" 37 1.1 mrg #include "tristate.h" 38 1.1 mrg #include "selftest.h" 39 1.1 mrg #include "ordered-hash-map.h" 40 1.1 mrg #include "json.h" 41 1.1 mrg #include "analyzer/analyzer.h" 42 1.1 mrg #include "analyzer/analyzer-logging.h" 43 1.1 mrg #include "analyzer/sm.h" 44 1.1 mrg #include "analyzer/pending-diagnostic.h" 45 1.1 mrg #include "analyzer/diagnostic-manager.h" 46 1.1 mrg #include "analyzer/call-string.h" 47 1.1 mrg #include "analyzer/program-point.h" 48 1.1 mrg #include "analyzer/store.h" 49 1.1 mrg #include "analyzer/region-model.h" 50 1.1 mrg #include "analyzer/constraint-manager.h" 51 1.1 mrg #include "cfg.h" 52 1.1 mrg #include "basic-block.h" 53 1.1 mrg #include "gimple.h" 54 1.1 mrg #include "gimple-iterator.h" 55 1.1 mrg #include "cgraph.h" 56 1.1 mrg #include "digraph.h" 57 1.1 mrg #include "analyzer/supergraph.h" 58 1.1 mrg #include "analyzer/program-state.h" 59 1.1 mrg #include "analyzer/exploded-graph.h" 60 1.1 mrg #include "analyzer/trimmed-graph.h" 61 1.1 mrg 62 1.1 mrg #if ENABLE_ANALYZER 63 1.1 mrg 64 1.1 mrg namespace ana { 65 1.1 mrg 66 1.1 mrg /* class trimmed_node : public dnode<tg_traits>. */ 67 1.1 mrg 68 1.1 mrg /* Implementation of dump_dot vfunc, delegating to the inner node. */ 69 1.1 mrg 70 1.1 mrg void 71 1.1 mrg trimmed_node::dump_dot (graphviz_out *gv, 72 1.1 mrg const dump_args_t &args) const 73 1.1 mrg { 74 1.1 mrg m_inner_node->dump_dot (gv, args.m_inner_args); 75 1.1 mrg } 76 1.1 mrg 77 1.1 mrg /* class trimmed_edge : public dedge<tg_traits>. */ 78 1.1 mrg 79 1.1 mrg /* trimmed_edge's ctor. */ 80 1.1 mrg 81 1.1 mrg trimmed_edge::trimmed_edge (trimmed_node *src, trimmed_node *dest, 82 1.1 mrg const exploded_edge *inner_edge) 83 1.1 mrg : dedge<tg_traits> (src, dest), m_inner_edge (inner_edge) 84 1.1 mrg { 85 1.1 mrg } 86 1.1 mrg 87 1.1 mrg /* Implementation of dump_dot vfunc, delegating to the inner edge. */ 88 1.1 mrg 89 1.1 mrg void 90 1.1 mrg trimmed_edge::dump_dot (graphviz_out *gv, const dump_args_t &args) const 91 1.1 mrg { 92 1.1 mrg m_inner_edge->dump_dot (gv, args.m_inner_args); 93 1.1 mrg } 94 1.1 mrg 95 1.1 mrg /* class trimmed_graph : public digraph <tg_traits>. */ 96 1.1 mrg 97 1.1 mrg /* Ctor for trimmed_graph: construct a graph equivalent to trimming 98 1.1 mrg INNER_GRAPH to all nodes that can reach INNER_DST_NODE. */ 99 1.1 mrg 100 1.1 mrg trimmed_graph::trimmed_graph (const exploded_graph &inner_graph, 101 1.1 mrg const exploded_node *inner_dst_node) 102 1.1 mrg : m_enodes (), m_eedges () 103 1.1 mrg { 104 1.1 mrg /* Determine what subset of nodes and edges to include in the 105 1.1 mrg trimmed graph. 106 1.1 mrg Walk backwards from INNER_DST_NODE, finding nodes that reach it, 107 1.1 mrg iteratively building the set of nodes and edges. */ 108 1.1 mrg auto_vec <const exploded_node *> worklist; 109 1.1 mrg worklist.safe_push (inner_dst_node); 110 1.1 mrg m_enodes.add (inner_dst_node); 111 1.1 mrg while (worklist.length () > 0) 112 1.1 mrg { 113 1.1 mrg const exploded_node *inner_node = worklist.pop (); 114 1.1 mrg exploded_edge *inner_pred; 115 1.1 mrg unsigned i; 116 1.1 mrg FOR_EACH_VEC_ELT (inner_node->m_preds, i, inner_pred) 117 1.1 mrg { 118 1.1 mrg if (!m_enodes.contains (inner_pred->m_src)) 119 1.1 mrg { 120 1.1 mrg worklist.safe_push (inner_pred->m_src); 121 1.1 mrg m_enodes.add (inner_pred->m_src); 122 1.1 mrg } 123 1.1 mrg m_eedges.add (inner_pred); 124 1.1 mrg } 125 1.1 mrg } 126 1.1 mrg 127 1.1 mrg /* Create trimmed nodes for all enodes in the set. */ 128 1.1 mrg { 129 1.1 mrg /* Iterate over the vec rather than the hash_set 130 1.1 mrg to ensure deterministic order. */ 131 1.1 mrg exploded_node *inner_node; 132 1.1 mrg unsigned i; 133 1.1 mrg FOR_EACH_VEC_ELT (inner_graph.m_nodes, i, inner_node) 134 1.1 mrg if (m_enodes.contains (inner_node)) 135 1.1 mrg { 136 1.1 mrg trimmed_node *tnode = new trimmed_node (inner_node); 137 1.1 mrg add_node (tnode); 138 1.1 mrg m_map_from_enode_to_tnode.put (inner_node, tnode); 139 1.1 mrg } 140 1.1 mrg } 141 1.1 mrg 142 1.1 mrg /* Create trimmed edges for all edges in the set. */ 143 1.1 mrg { 144 1.1 mrg /* Iterate over the vec rather than the hash_set 145 1.1 mrg to ensure deterministic order. */ 146 1.1 mrg exploded_edge *inner_edge; 147 1.1 mrg unsigned i; 148 1.1 mrg FOR_EACH_VEC_ELT (inner_graph.m_edges, i, inner_edge) 149 1.1 mrg if (m_eedges.contains (inner_edge)) 150 1.1 mrg { 151 1.1 mrg const exploded_node *inner_src = inner_edge->m_src; 152 1.1 mrg const exploded_node *inner_dest = inner_edge->m_dest; 153 1.1 mrg trimmed_node *tsrc = *m_map_from_enode_to_tnode.get (inner_src); 154 1.1 mrg trimmed_node *tdest = *m_map_from_enode_to_tnode.get (inner_dest); 155 1.1 mrg trimmed_edge *tedge = new trimmed_edge (tsrc, tdest, inner_edge); 156 1.1 mrg add_edge (tedge); 157 1.1 mrg } 158 1.1 mrg } 159 1.1 mrg } 160 1.1 mrg 161 1.1 mrg /* Dump stats about this graph to LOGGER. */ 162 1.1 mrg 163 1.1 mrg void 164 1.1 mrg trimmed_graph::log_stats (logger *logger) const 165 1.1 mrg { 166 1.1 mrg logger->log ("#nodes: %i", m_nodes.length ()); 167 1.1 mrg logger->log ("#edges: %i", m_edges.length ()); 168 1.1 mrg } 169 1.1 mrg 170 1.1 mrg } // namespace ana 171 1.1 mrg 172 1.1 mrg #endif /* #if ENABLE_ANALYZER */ 173