]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/statistics.c
[Ada] Improved support for aspect alignment in CCG
[thirdparty/gcc.git] / gcc / statistics.c
CommitLineData
82e6d02f 1/* Optimization statistics functions.
8d9254fc 2 Copyright (C) 2008-2020 Free Software Foundation, Inc.
82e6d02f
RB
3 Contributed by Richard Guenther <rguenther@suse.de>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
82e6d02f 24#include "function.h"
957060b5 25#include "tree-pass.h"
315f8c0e
DM
26#include "context.h"
27#include "pass_manager.h"
82e6d02f
RB
28
29static int statistics_dump_nr;
1a817418 30static dump_flags_t statistics_dump_flags;
82e6d02f
RB
31static FILE *statistics_dump_file;
32
33/* Statistics entry. A integer counter associated to a string ID
34 and value. */
35
526ceb68 36struct statistics_counter {
82e6d02f
RB
37 const char *id;
38 int val;
39 bool histogram_p;
40 unsigned HOST_WIDE_INT count;
41 unsigned HOST_WIDE_INT prev_dumped_count;
526ceb68 42};
82e6d02f 43
bf190e8d
LC
44/* Hashtable helpers. */
45
526ceb68 46struct stats_counter_hasher : pointer_hash <statistics_counter>
bf190e8d 47{
526ceb68
TS
48 static inline hashval_t hash (const statistics_counter *);
49 static inline bool equal (const statistics_counter *,
50 const statistics_counter *);
51 static inline void remove (statistics_counter *);
bf190e8d 52};
82e6d02f
RB
53
54/* Hash a statistic counter by its string ID. */
55
bf190e8d 56inline hashval_t
526ceb68 57stats_counter_hasher::hash (const statistics_counter *c)
82e6d02f 58{
82e6d02f
RB
59 return htab_hash_string (c->id) + c->val;
60}
61
62/* Compare two statistic counters by their string IDs. */
63
bf190e8d 64inline bool
526ceb68
TS
65stats_counter_hasher::equal (const statistics_counter *c1,
66 const statistics_counter *c2)
82e6d02f 67{
82e6d02f
RB
68 return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
69}
70
71/* Free a statistics entry. */
72
bf190e8d 73inline void
526ceb68 74stats_counter_hasher::remove (statistics_counter *v)
82e6d02f 75{
c3284718 76 free (CONST_CAST (char *, v->id));
bf190e8d 77 free (v);
82e6d02f
RB
78}
79
c203e8a7 80typedef hash_table<stats_counter_hasher> stats_counter_table_type;
bf190e8d
LC
81
82/* Array of statistic hashes, indexed by pass id. */
c203e8a7 83static stats_counter_table_type **statistics_hashes;
bf190e8d
LC
84static unsigned nr_statistics_hashes;
85
82e6d02f
RB
86/* Return the current hashtable to be used for recording or printing
87 statistics. */
88
c203e8a7 89static stats_counter_table_type *
82e6d02f
RB
90curr_statistics_hash (void)
91{
5e1b50f6
AB
92 unsigned idx;
93
94 gcc_assert (current_pass->static_pass_number >= 0);
95 idx = current_pass->static_pass_number;
82e6d02f
RB
96
97 if (idx < nr_statistics_hashes
c203e8a7 98 && statistics_hashes[idx])
82e6d02f
RB
99 return statistics_hashes[idx];
100
101 if (idx >= nr_statistics_hashes)
102 {
c203e8a7 103 statistics_hashes = XRESIZEVEC (stats_counter_table_type *,
bf190e8d 104 statistics_hashes, idx+1);
82e6d02f 105 memset (statistics_hashes + nr_statistics_hashes, 0,
bf190e8d 106 (idx + 1 - nr_statistics_hashes)
c203e8a7 107 * sizeof (stats_counter_table_type *));
82e6d02f
RB
108 nr_statistics_hashes = idx + 1;
109 }
110
c203e8a7 111 statistics_hashes[idx] = new stats_counter_table_type (15);
82e6d02f
RB
112
113 return statistics_hashes[idx];
114}
115
116/* Helper for statistics_fini_pass. Print the counter difference
117 since the last dump for the pass dump files. */
118
bf190e8d 119int
526ceb68 120statistics_fini_pass_1 (statistics_counter **slot,
bf190e8d 121 void *data ATTRIBUTE_UNUSED)
82e6d02f 122{
526ceb68 123 statistics_counter *counter = *slot;
82e6d02f
RB
124 unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
125 if (count == 0)
126 return 1;
127 if (counter->histogram_p)
128 fprintf (dump_file, "%s == %d: " HOST_WIDE_INT_PRINT_DEC "\n",
129 counter->id, counter->val, count);
130 else
131 fprintf (dump_file, "%s: " HOST_WIDE_INT_PRINT_DEC "\n",
132 counter->id, count);
133 counter->prev_dumped_count = counter->count;
134 return 1;
135}
136
137/* Helper for statistics_fini_pass. Print the counter difference
138 since the last dump for the statistics dump. */
139
bf190e8d 140int
526ceb68 141statistics_fini_pass_2 (statistics_counter **slot,
bf190e8d 142 void *data ATTRIBUTE_UNUSED)
82e6d02f 143{
526ceb68 144 statistics_counter *counter = *slot;
82e6d02f
RB
145 unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
146 if (count == 0)
147 return 1;
148 counter->prev_dumped_count = counter->count;
149 if (counter->histogram_p)
150 fprintf (statistics_dump_file,
151 "%d %s \"%s == %d\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
152 current_pass->static_pass_number,
153 current_pass->name,
154 counter->id, counter->val,
532aafad 155 current_function_name (),
82e6d02f
RB
156 count);
157 else
158 fprintf (statistics_dump_file,
159 "%d %s \"%s\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
160 current_pass->static_pass_number,
161 current_pass->name,
162 counter->id,
532aafad 163 current_function_name (),
82e6d02f
RB
164 count);
165 counter->prev_dumped_count = counter->count;
166 return 1;
167}
168
169/* Helper for statistics_fini_pass, reset the counters. */
170
bf190e8d 171int
526ceb68 172statistics_fini_pass_3 (statistics_counter **slot,
bf190e8d 173 void *data ATTRIBUTE_UNUSED)
82e6d02f 174{
526ceb68 175 statistics_counter *counter = *slot;
82e6d02f
RB
176 counter->prev_dumped_count = counter->count;
177 return 1;
178}
179
180/* Dump the current statistics incrementally. */
181
182void
183statistics_fini_pass (void)
184{
185 if (current_pass->static_pass_number == -1)
186 return;
187
188 if (dump_file
189 && dump_flags & TDF_STATS)
190 {
191 fprintf (dump_file, "\n");
ec09a694 192 fprintf (dump_file, "Pass statistics of \"%s\": ", current_pass->name);
82e6d02f 193 fprintf (dump_file, "----------------\n");
bf190e8d 194 curr_statistics_hash ()
c203e8a7 195 ->traverse_noresize <void *, statistics_fini_pass_1> (NULL);
82e6d02f
RB
196 fprintf (dump_file, "\n");
197 }
198 if (statistics_dump_file
199 && !(statistics_dump_flags & TDF_STATS
200 || statistics_dump_flags & TDF_DETAILS))
bf190e8d 201 curr_statistics_hash ()
c203e8a7 202 ->traverse_noresize <void *, statistics_fini_pass_2> (NULL);
bf190e8d 203 curr_statistics_hash ()
c203e8a7 204 ->traverse_noresize <void *, statistics_fini_pass_3> (NULL);
82e6d02f
RB
205}
206
207/* Helper for printing summary information. */
208
bf190e8d 209int
526ceb68 210statistics_fini_1 (statistics_counter **slot, opt_pass *pass)
82e6d02f 211{
526ceb68 212 statistics_counter *counter = *slot;
82e6d02f
RB
213 if (counter->count == 0)
214 return 1;
215 if (counter->histogram_p)
216 fprintf (statistics_dump_file,
217 "%d %s \"%s == %d\" " HOST_WIDE_INT_PRINT_DEC "\n",
218 pass->static_pass_number,
219 pass->name,
220 counter->id, counter->val,
221 counter->count);
222 else
223 fprintf (statistics_dump_file,
224 "%d %s \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
225 pass->static_pass_number,
226 pass->name,
227 counter->id,
228 counter->count);
229 return 1;
230}
231
232/* Finish the statistics and dump summary information. */
233
234void
235statistics_fini (void)
236{
315f8c0e 237 gcc::pass_manager *passes = g->get_passes ();
82e6d02f
RB
238 if (!statistics_dump_file)
239 return;
240
241 if (statistics_dump_flags & TDF_STATS)
242 {
243 unsigned i;
244 for (i = 0; i < nr_statistics_hashes; ++i)
c203e8a7 245 if (statistics_hashes[i]
315f8c0e 246 && passes->get_pass_for_id (i) != NULL)
bf190e8d 247 statistics_hashes[i]
c203e8a7 248 ->traverse_noresize <opt_pass *, statistics_fini_1>
315f8c0e 249 (passes->get_pass_for_id (i));
82e6d02f
RB
250 }
251
252 dump_end (statistics_dump_nr, statistics_dump_file);
253}
254
255/* Register the statistics dump file. */
256
257void
258statistics_early_init (void)
259{
47e0da37
DM
260 gcc::dump_manager *dumps = g->get_dumps ();
261 statistics_dump_nr = dumps->dump_register (".statistics", "statistics",
8264c84d 262 "statistics", DK_tree,
10fdd6e9
DM
263 OPTGROUP_NONE,
264 false);
82e6d02f
RB
265}
266
267/* Init the statistics. */
268
269void
270statistics_init (void)
271{
47e0da37 272 gcc::dump_manager *dumps = g->get_dumps ();
82e6d02f 273 statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
47e0da37 274 statistics_dump_flags = dumps->get_dump_file_info (statistics_dump_nr)->pflags;
82e6d02f
RB
275}
276
277/* Lookup or add a statistics counter in the hashtable HASH with ID, VAL
278 and HISTOGRAM_P. */
279
526ceb68 280static statistics_counter *
c203e8a7 281lookup_or_add_counter (stats_counter_table_type *hash, const char *id, int val,
82e6d02f
RB
282 bool histogram_p)
283{
526ceb68
TS
284 statistics_counter **counter;
285 statistics_counter c;
82e6d02f
RB
286 c.id = id;
287 c.val = val;
c203e8a7 288 counter = hash->find_slot (&c, INSERT);
82e6d02f
RB
289 if (!*counter)
290 {
526ceb68 291 *counter = XNEW (statistics_counter);
82e6d02f
RB
292 (*counter)->id = xstrdup (id);
293 (*counter)->val = val;
294 (*counter)->histogram_p = histogram_p;
295 (*counter)->prev_dumped_count = 0;
296 (*counter)->count = 0;
297 }
298 return *counter;
299}
300
301/* Add statistics information about event ID in function FN.
302 This will increment the counter associated with ID by INCR.
303 It will also dump the event to the global statistics file if requested. */
304
305void
306statistics_counter_event (struct function *fn, const char *id, int incr)
307{
526ceb68 308 statistics_counter *counter;
82e6d02f
RB
309
310 if ((!(dump_flags & TDF_STATS)
311 && !statistics_dump_file)
312 || incr == 0)
313 return;
314
e83421c0
RB
315 if (current_pass
316 && current_pass->static_pass_number != -1)
5e1b50f6
AB
317 {
318 counter = lookup_or_add_counter (curr_statistics_hash (), id, 0, false);
319 gcc_assert (!counter->histogram_p);
320 counter->count += incr;
321 }
82e6d02f
RB
322
323 if (!statistics_dump_file
324 || !(statistics_dump_flags & TDF_DETAILS))
325 return;
326
327 fprintf (statistics_dump_file,
328 "%d %s \"%s\" \"%s\" %d\n",
e83421c0
RB
329 current_pass ? current_pass->static_pass_number : -1,
330 current_pass ? current_pass->name : "none",
82e6d02f 331 id,
532aafad 332 function_name (fn),
82e6d02f
RB
333 incr);
334}
335
336/* Add statistics information about event ID in function FN with the
337 histogram value VAL.
338 It will dump the event to the global statistics file if requested. */
339
340void
341statistics_histogram_event (struct function *fn, const char *id, int val)
342{
526ceb68 343 statistics_counter *counter;
82e6d02f
RB
344
345 if (!(dump_flags & TDF_STATS)
346 && !statistics_dump_file)
347 return;
348
349 counter = lookup_or_add_counter (curr_statistics_hash (), id, val, true);
350 gcc_assert (counter->histogram_p);
351 counter->count += 1;
352
353 if (!statistics_dump_file
354 || !(statistics_dump_flags & TDF_DETAILS))
355 return;
356
357 fprintf (statistics_dump_file,
358 "%d %s \"%s == %d\" \"%s\" 1\n",
359 current_pass->static_pass_number,
360 current_pass->name,
361 id, val,
532aafad 362 function_name (fn));
82e6d02f 363}