OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [statistics.c] - Blame information for rev 720

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.