1*e4b17023SJohn Marino /* Debug counter for debugging support
2*e4b17023SJohn Marino Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3*e4b17023SJohn Marino
4*e4b17023SJohn Marino This file is part of GCC.
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
7*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
8*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
9*e4b17023SJohn Marino version.
10*e4b17023SJohn Marino
11*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*e4b17023SJohn Marino for more details.
15*e4b17023SJohn Marino
16*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
17*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
18*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino See dbgcnt.def for usage information. */
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "diagnostic-core.h"
26*e4b17023SJohn Marino #include "tm.h"
27*e4b17023SJohn Marino #include "rtl.h"
28*e4b17023SJohn Marino #include "output.h"
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino #include "dbgcnt.h"
31*e4b17023SJohn Marino
32*e4b17023SJohn Marino struct string2counter_map {
33*e4b17023SJohn Marino const char *name;
34*e4b17023SJohn Marino enum debug_counter counter;
35*e4b17023SJohn Marino };
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino #define DEBUG_COUNTER(a) { #a , a },
38*e4b17023SJohn Marino
39*e4b17023SJohn Marino static struct string2counter_map map[debug_counter_number_of_counters] =
40*e4b17023SJohn Marino {
41*e4b17023SJohn Marino #include "dbgcnt.def"
42*e4b17023SJohn Marino };
43*e4b17023SJohn Marino #undef DEBUG_COUNTER
44*e4b17023SJohn Marino
45*e4b17023SJohn Marino #define DEBUG_COUNTER(a) UINT_MAX,
46*e4b17023SJohn Marino static unsigned int limit[debug_counter_number_of_counters] =
47*e4b17023SJohn Marino {
48*e4b17023SJohn Marino #include "dbgcnt.def"
49*e4b17023SJohn Marino };
50*e4b17023SJohn Marino #undef DEBUG_COUNTER
51*e4b17023SJohn Marino
52*e4b17023SJohn Marino static unsigned int count[debug_counter_number_of_counters];
53*e4b17023SJohn Marino
54*e4b17023SJohn Marino bool
dbg_cnt_is_enabled(enum debug_counter index)55*e4b17023SJohn Marino dbg_cnt_is_enabled (enum debug_counter index)
56*e4b17023SJohn Marino {
57*e4b17023SJohn Marino return count[index] <= limit[index];
58*e4b17023SJohn Marino }
59*e4b17023SJohn Marino
60*e4b17023SJohn Marino bool
dbg_cnt(enum debug_counter index)61*e4b17023SJohn Marino dbg_cnt (enum debug_counter index)
62*e4b17023SJohn Marino {
63*e4b17023SJohn Marino count[index]++;
64*e4b17023SJohn Marino if (dump_file && count[index] == limit[index])
65*e4b17023SJohn Marino fprintf (dump_file, "***dbgcnt: limit reached for %s.***\n",
66*e4b17023SJohn Marino map[index].name);
67*e4b17023SJohn Marino
68*e4b17023SJohn Marino return dbg_cnt_is_enabled (index);
69*e4b17023SJohn Marino }
70*e4b17023SJohn Marino
71*e4b17023SJohn Marino
72*e4b17023SJohn Marino static void
dbg_cnt_set_limit_by_index(enum debug_counter index,int value)73*e4b17023SJohn Marino dbg_cnt_set_limit_by_index (enum debug_counter index, int value)
74*e4b17023SJohn Marino {
75*e4b17023SJohn Marino limit[index] = value;
76*e4b17023SJohn Marino
77*e4b17023SJohn Marino fprintf (stderr, "dbg_cnt '%s' set to %d\n", map[index].name, value);
78*e4b17023SJohn Marino }
79*e4b17023SJohn Marino
80*e4b17023SJohn Marino static bool
dbg_cnt_set_limit_by_name(const char * name,int len,int value)81*e4b17023SJohn Marino dbg_cnt_set_limit_by_name (const char *name, int len, int value)
82*e4b17023SJohn Marino {
83*e4b17023SJohn Marino int i;
84*e4b17023SJohn Marino for (i = debug_counter_number_of_counters - 1; i >= 0; i--)
85*e4b17023SJohn Marino if (strncmp (map[i].name, name, len) == 0
86*e4b17023SJohn Marino && map[i].name[len] == '\0')
87*e4b17023SJohn Marino break;
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino if (i < 0)
90*e4b17023SJohn Marino return false;
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino dbg_cnt_set_limit_by_index ((enum debug_counter) i, value);
93*e4b17023SJohn Marino return true;
94*e4b17023SJohn Marino }
95*e4b17023SJohn Marino
96*e4b17023SJohn Marino
97*e4b17023SJohn Marino /* Process a single "name:value" pair.
98*e4b17023SJohn Marino Returns NULL if there's no valid pair is found.
99*e4b17023SJohn Marino Otherwise returns a pointer to the end of the pair. */
100*e4b17023SJohn Marino
101*e4b17023SJohn Marino static const char *
dbg_cnt_process_single_pair(const char * arg)102*e4b17023SJohn Marino dbg_cnt_process_single_pair (const char *arg)
103*e4b17023SJohn Marino {
104*e4b17023SJohn Marino const char *colon = strchr (arg, ':');
105*e4b17023SJohn Marino char *endptr = NULL;
106*e4b17023SJohn Marino int value;
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino if (colon == NULL)
109*e4b17023SJohn Marino return NULL;
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino value = strtol (colon + 1, &endptr, 10);
112*e4b17023SJohn Marino
113*e4b17023SJohn Marino if (endptr != NULL && endptr != colon + 1
114*e4b17023SJohn Marino && dbg_cnt_set_limit_by_name (arg, colon - arg, value))
115*e4b17023SJohn Marino return endptr;
116*e4b17023SJohn Marino
117*e4b17023SJohn Marino return NULL;
118*e4b17023SJohn Marino }
119*e4b17023SJohn Marino
120*e4b17023SJohn Marino void
dbg_cnt_process_opt(const char * arg)121*e4b17023SJohn Marino dbg_cnt_process_opt (const char *arg)
122*e4b17023SJohn Marino {
123*e4b17023SJohn Marino const char *start = arg;
124*e4b17023SJohn Marino const char *next;
125*e4b17023SJohn Marino do {
126*e4b17023SJohn Marino next = dbg_cnt_process_single_pair (arg);
127*e4b17023SJohn Marino if (next == NULL)
128*e4b17023SJohn Marino break;
129*e4b17023SJohn Marino } while (*next == ',' && (arg = next + 1));
130*e4b17023SJohn Marino
131*e4b17023SJohn Marino if (next == NULL || *next != 0)
132*e4b17023SJohn Marino {
133*e4b17023SJohn Marino char *buffer = XALLOCAVEC (char, arg - start + 2);
134*e4b17023SJohn Marino sprintf (buffer, "%*c", (int)(1 + (arg - start)), '^');
135*e4b17023SJohn Marino error ("cannot find a valid counter:value pair:");
136*e4b17023SJohn Marino error ("-fdbg-cnt=%s", start);
137*e4b17023SJohn Marino error (" %s", buffer);
138*e4b17023SJohn Marino }
139*e4b17023SJohn Marino }
140*e4b17023SJohn Marino
141*e4b17023SJohn Marino /* Print name, limit and count of all counters. */
142*e4b17023SJohn Marino
143*e4b17023SJohn Marino void
dbg_cnt_list_all_counters(void)144*e4b17023SJohn Marino dbg_cnt_list_all_counters (void)
145*e4b17023SJohn Marino {
146*e4b17023SJohn Marino int i;
147*e4b17023SJohn Marino printf (" %-30s %-5s %-5s\n", "counter name", "limit", "value");
148*e4b17023SJohn Marino printf ("----------------------------------------------\n");
149*e4b17023SJohn Marino for (i = 0; i < debug_counter_number_of_counters; i++)
150*e4b17023SJohn Marino printf (" %-30s %5d %5u\n",
151*e4b17023SJohn Marino map[i].name, limit[map[i].counter], count[map[i].counter]);
152*e4b17023SJohn Marino printf ("\n");
153*e4b17023SJohn Marino }
154