Line data Source code
1 : /* Fixing up location_t values of supernodes.
2 : Copyright (C) 2025-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #define INCLUDE_DEQUE
22 : #include "analyzer/common.h"
23 :
24 : #include "timevar.h"
25 :
26 : #include "analyzer/supergraph.h"
27 : #include "analyzer/analyzer-logging.h"
28 : #include "analyzer/supergraph-manipulation.h"
29 :
30 : #if ENABLE_ANALYZER
31 :
32 : namespace ana {
33 :
34 : namespace {
35 :
36 3377 : class location_fixer
37 : {
38 : public:
39 3377 : location_fixer (supergraph &sg,
40 : ana::logger *logger)
41 6754 : : m_logger (logger),
42 3377 : m_stats ()
43 : {
44 197777 : for (auto node : sg.m_nodes)
45 187654 : if (node->m_loc == UNKNOWN_LOCATION)
46 31444 : m_worklist.ensure_node_queued (node, logger);
47 3377 : }
48 :
49 : /* High level ops. */
50 :
51 : supernode *
52 60472 : pop_next_node_in_queue ()
53 : {
54 60472 : return m_worklist.pop ();
55 : }
56 :
57 : void
58 57095 : consider_node (supernode *node)
59 : {
60 57095 : m_stats.m_num_iterations++;
61 :
62 57095 : log_nesting_level sentinel (m_logger, "considering SN: %i", node->m_id);
63 :
64 : /* Already have a location for this node. */
65 57095 : if (useful_location_p (node->m_loc))
66 24634 : return;
67 :
68 : /* For snodes with UNKNOWN_LOCATION with a single in-edge, try to
69 : propagate the location from it. */
70 62802 : if (node->m_preds.length () == 1)
71 : {
72 30341 : auto in_edge = node->m_preds[0];
73 30341 : if (useful_location_p (in_edge->m_src->m_loc))
74 : {
75 28639 : node->m_loc = in_edge->m_src->m_loc;
76 28639 : m_stats.m_num_copies++;
77 28639 : if (m_logger)
78 18 : m_logger->log ("copying location 0x%lx from SN %i to SN %i",
79 : node->m_loc,
80 : in_edge->m_src->m_id, node->m_id);
81 112043 : for (auto out_edge : node->m_succs)
82 28268 : m_worklist.ensure_node_queued (out_edge->m_dest, m_logger);
83 : }
84 : }
85 57095 : }
86 :
87 : private:
88 : supergraph_manipulation::worklist m_worklist;
89 : ana::logger *m_logger;
90 : struct stats
91 : {
92 : stats () = default;
93 :
94 : void log (ana::logger &logger)
95 : {
96 : logger.log ("# iterations taken: " HOST_SIZE_T_PRINT_UNSIGNED,
97 : (fmt_size_t)m_num_iterations);
98 : logger.log ("# locations copied: " HOST_SIZE_T_PRINT_UNSIGNED,
99 : (fmt_size_t)m_num_copies);
100 : }
101 :
102 : size_t m_num_iterations;
103 : size_t m_num_copies;
104 :
105 : } m_stats;
106 : };
107 :
108 : } // anonymous namespace
109 :
110 : void
111 3377 : supergraph::fixup_locations (logger *logger)
112 : {
113 3377 : auto_timevar tv (TV_ANALYZER_SUPERGRAPH_FIXUP_LOCATIONS);
114 3377 : LOG_SCOPE (logger);
115 :
116 3377 : location_fixer opt (*this, logger);
117 60472 : while (supernode *node = opt.pop_next_node_in_queue ())
118 57095 : opt.consider_node (node);
119 3377 : }
120 :
121 : } // namespace ana
122 :
123 : #endif /* #if ENABLE_ANALYZER */
|