1*38fd1498Szrj /* Timing variables for measuring compiler performance.
2*38fd1498Szrj Copyright (C) 2000-2018 Free Software Foundation, Inc.
3*38fd1498Szrj Contributed by Alex Samuel <samuel@codesourcery.com>
4*38fd1498Szrj
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it
8*38fd1498Szrj under the terms of the GNU General Public License as published by
9*38fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
10*38fd1498Szrj any later version.
11*38fd1498Szrj
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT
13*38fd1498Szrj ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14*38fd1498Szrj or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15*38fd1498Szrj License for more details.
16*38fd1498Szrj
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3. If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>. */
20*38fd1498Szrj
21*38fd1498Szrj #ifndef GCC_TIMEVAR_H
22*38fd1498Szrj #define GCC_TIMEVAR_H
23*38fd1498Szrj
24*38fd1498Szrj /* Timing variables are used to measure elapsed time in various
25*38fd1498Szrj portions of the compiler. Each measures elapsed user, system, and
26*38fd1498Szrj wall-clock time, as appropriate to and supported by the host
27*38fd1498Szrj system.
28*38fd1498Szrj
29*38fd1498Szrj Timing variables are defined using the DEFTIMEVAR macro in
30*38fd1498Szrj timevar.def. Each has an enumeral identifier, used when referring
31*38fd1498Szrj to the timing variable in code, and a character string name.
32*38fd1498Szrj
33*38fd1498Szrj Timing variables can be used in two ways:
34*38fd1498Szrj
35*38fd1498Szrj - On the timing stack, using timevar_push and timevar_pop.
36*38fd1498Szrj Timing variables may be pushed onto the stack; elapsed time is
37*38fd1498Szrj attributed to the topmost timing variable on the stack. When
38*38fd1498Szrj another variable is pushed on, the previous topmost variable is
39*38fd1498Szrj `paused' until the pushed variable is popped back off.
40*38fd1498Szrj
41*38fd1498Szrj - As a standalone timer, using timevar_start and timevar_stop.
42*38fd1498Szrj All time elapsed between the two calls is attributed to the
43*38fd1498Szrj variable.
44*38fd1498Szrj */
45*38fd1498Szrj
46*38fd1498Szrj /* This structure stores the various varieties of time that can be
47*38fd1498Szrj measured. Times are stored in seconds. The time may be an
48*38fd1498Szrj absolute time or a time difference; in the former case, the time
49*38fd1498Szrj base is undefined, except that the difference between two times
50*38fd1498Szrj produces a valid time difference. */
51*38fd1498Szrj
52*38fd1498Szrj struct timevar_time_def
53*38fd1498Szrj {
54*38fd1498Szrj /* User time in this process. */
55*38fd1498Szrj double user;
56*38fd1498Szrj
57*38fd1498Szrj /* System time (if applicable for this host platform) in this
58*38fd1498Szrj process. */
59*38fd1498Szrj double sys;
60*38fd1498Szrj
61*38fd1498Szrj /* Wall clock time. */
62*38fd1498Szrj double wall;
63*38fd1498Szrj
64*38fd1498Szrj /* Garbage collector memory. */
65*38fd1498Szrj size_t ggc_mem;
66*38fd1498Szrj };
67*38fd1498Szrj
68*38fd1498Szrj /* An enumeration of timing variable identifiers. Constructed from
69*38fd1498Szrj the contents of timevar.def. */
70*38fd1498Szrj
71*38fd1498Szrj #define DEFTIMEVAR(identifier__, name__) \
72*38fd1498Szrj identifier__,
73*38fd1498Szrj typedef enum
74*38fd1498Szrj {
75*38fd1498Szrj TV_NONE,
76*38fd1498Szrj #include "timevar.def"
77*38fd1498Szrj TIMEVAR_LAST
78*38fd1498Szrj }
79*38fd1498Szrj timevar_id_t;
80*38fd1498Szrj #undef DEFTIMEVAR
81*38fd1498Szrj
82*38fd1498Szrj /* A class to hold all state relating to timing. */
83*38fd1498Szrj
84*38fd1498Szrj class timer;
85*38fd1498Szrj
86*38fd1498Szrj /* The singleton instance of timing state.
87*38fd1498Szrj
88*38fd1498Szrj This is non-NULL if timevars should be used. In GCC, this happens with
89*38fd1498Szrj the -ftime-report flag. Hence this is NULL for the common,
90*38fd1498Szrj needs-to-be-fast case, with an early reject happening for this being
91*38fd1498Szrj NULL. */
92*38fd1498Szrj extern timer *g_timer;
93*38fd1498Szrj
94*38fd1498Szrj /* Total amount of memory allocated by garbage collector. */
95*38fd1498Szrj extern size_t timevar_ggc_mem_total;
96*38fd1498Szrj
97*38fd1498Szrj extern void timevar_init (void);
98*38fd1498Szrj extern void timevar_start (timevar_id_t);
99*38fd1498Szrj extern void timevar_stop (timevar_id_t);
100*38fd1498Szrj extern bool timevar_cond_start (timevar_id_t);
101*38fd1498Szrj extern void timevar_cond_stop (timevar_id_t, bool);
102*38fd1498Szrj
103*38fd1498Szrj /* The public (within GCC) interface for timing. */
104*38fd1498Szrj
105*38fd1498Szrj class timer
106*38fd1498Szrj {
107*38fd1498Szrj public:
108*38fd1498Szrj timer ();
109*38fd1498Szrj ~timer ();
110*38fd1498Szrj
111*38fd1498Szrj void start (timevar_id_t tv);
112*38fd1498Szrj void stop (timevar_id_t tv);
113*38fd1498Szrj void push (timevar_id_t tv);
114*38fd1498Szrj void pop (timevar_id_t tv);
115*38fd1498Szrj bool cond_start (timevar_id_t tv);
116*38fd1498Szrj void cond_stop (timevar_id_t tv);
117*38fd1498Szrj
118*38fd1498Szrj void push_client_item (const char *item_name);
119*38fd1498Szrj void pop_client_item ();
120*38fd1498Szrj
121*38fd1498Szrj void print (FILE *fp);
122*38fd1498Szrj
123*38fd1498Szrj const char *get_topmost_item_name () const;
124*38fd1498Szrj
125*38fd1498Szrj private:
126*38fd1498Szrj /* Private member functions. */
127*38fd1498Szrj void validate_phases (FILE *fp) const;
128*38fd1498Szrj
129*38fd1498Szrj struct timevar_def;
130*38fd1498Szrj void push_internal (struct timevar_def *tv);
131*38fd1498Szrj void pop_internal ();
132*38fd1498Szrj static void print_row (FILE *fp,
133*38fd1498Szrj const timevar_time_def *total,
134*38fd1498Szrj const char *name, const timevar_time_def &elapsed);
135*38fd1498Szrj static bool all_zero (const timevar_time_def &elapsed);
136*38fd1498Szrj
137*38fd1498Szrj private:
138*38fd1498Szrj typedef hash_map<timevar_def *, timevar_time_def> child_map_t;
139*38fd1498Szrj
140*38fd1498Szrj /* Private type: a timing variable. */
141*38fd1498Szrj struct timevar_def
142*38fd1498Szrj {
143*38fd1498Szrj /* Elapsed time for this variable. */
144*38fd1498Szrj struct timevar_time_def elapsed;
145*38fd1498Szrj
146*38fd1498Szrj /* If this variable is timed independently of the timing stack,
147*38fd1498Szrj using timevar_start, this contains the start time. */
148*38fd1498Szrj struct timevar_time_def start_time;
149*38fd1498Szrj
150*38fd1498Szrj /* The name of this timing variable. */
151*38fd1498Szrj const char *name;
152*38fd1498Szrj
153*38fd1498Szrj /* Nonzero if this timing variable is running as a standalone
154*38fd1498Szrj timer. */
155*38fd1498Szrj unsigned standalone : 1;
156*38fd1498Szrj
157*38fd1498Szrj /* Nonzero if this timing variable was ever started or pushed onto
158*38fd1498Szrj the timing stack. */
159*38fd1498Szrj unsigned used : 1;
160*38fd1498Szrj
161*38fd1498Szrj child_map_t *children;
162*38fd1498Szrj };
163*38fd1498Szrj
164*38fd1498Szrj /* Private type: an element on the timing stack
165*38fd1498Szrj Elapsed time is attributed to the topmost timing variable on the
166*38fd1498Szrj stack. */
167*38fd1498Szrj struct timevar_stack_def
168*38fd1498Szrj {
169*38fd1498Szrj /* The timing variable at this stack level. */
170*38fd1498Szrj struct timevar_def *timevar;
171*38fd1498Szrj
172*38fd1498Szrj /* The next lower timing variable context in the stack. */
173*38fd1498Szrj struct timevar_stack_def *next;
174*38fd1498Szrj };
175*38fd1498Szrj
176*38fd1498Szrj /* A class for managing a collection of named timing items, for use
177*38fd1498Szrj e.g. by libgccjit for timing client code. This class is declared
178*38fd1498Szrj inside timevar.c to avoid everything using timevar.h
179*38fd1498Szrj from needing vec and hash_map. */
180*38fd1498Szrj class named_items;
181*38fd1498Szrj
182*38fd1498Szrj private:
183*38fd1498Szrj
184*38fd1498Szrj /* Data members (all private). */
185*38fd1498Szrj
186*38fd1498Szrj /* Declared timing variables. Constructed from the contents of
187*38fd1498Szrj timevar.def. */
188*38fd1498Szrj timevar_def m_timevars[TIMEVAR_LAST];
189*38fd1498Szrj
190*38fd1498Szrj /* The top of the timing stack. */
191*38fd1498Szrj timevar_stack_def *m_stack;
192*38fd1498Szrj
193*38fd1498Szrj /* A list of unused (i.e. allocated and subsequently popped)
194*38fd1498Szrj timevar_stack_def instances. */
195*38fd1498Szrj timevar_stack_def *m_unused_stack_instances;
196*38fd1498Szrj
197*38fd1498Szrj /* The time at which the topmost element on the timing stack was
198*38fd1498Szrj pushed. Time elapsed since then is attributed to the topmost
199*38fd1498Szrj element. */
200*38fd1498Szrj timevar_time_def m_start_time;
201*38fd1498Szrj
202*38fd1498Szrj /* If non-NULL, for use when timing libgccjit's client code. */
203*38fd1498Szrj named_items *m_jit_client_items;
204*38fd1498Szrj
205*38fd1498Szrj friend class named_items;
206*38fd1498Szrj };
207*38fd1498Szrj
208*38fd1498Szrj /* Provided for backward compatibility. */
209*38fd1498Szrj static inline void
timevar_push(timevar_id_t tv)210*38fd1498Szrj timevar_push (timevar_id_t tv)
211*38fd1498Szrj {
212*38fd1498Szrj if (g_timer)
213*38fd1498Szrj g_timer->push (tv);
214*38fd1498Szrj }
215*38fd1498Szrj
216*38fd1498Szrj static inline void
timevar_pop(timevar_id_t tv)217*38fd1498Szrj timevar_pop (timevar_id_t tv)
218*38fd1498Szrj {
219*38fd1498Szrj if (g_timer)
220*38fd1498Szrj g_timer->pop (tv);
221*38fd1498Szrj }
222*38fd1498Szrj
223*38fd1498Szrj // This is a simple timevar wrapper class that pushes a timevar in its
224*38fd1498Szrj // constructor and pops the timevar in its destructor.
225*38fd1498Szrj class auto_timevar
226*38fd1498Szrj {
227*38fd1498Szrj public:
auto_timevar(timer * t,timevar_id_t tv)228*38fd1498Szrj auto_timevar (timer *t, timevar_id_t tv)
229*38fd1498Szrj : m_timer (t),
230*38fd1498Szrj m_tv (tv)
231*38fd1498Szrj {
232*38fd1498Szrj if (m_timer)
233*38fd1498Szrj m_timer->push (m_tv);
234*38fd1498Szrj }
235*38fd1498Szrj
auto_timevar(timevar_id_t tv)236*38fd1498Szrj explicit auto_timevar (timevar_id_t tv)
237*38fd1498Szrj : m_timer (g_timer)
238*38fd1498Szrj , m_tv (tv)
239*38fd1498Szrj {
240*38fd1498Szrj if (m_timer)
241*38fd1498Szrj m_timer->push (m_tv);
242*38fd1498Szrj }
243*38fd1498Szrj
~auto_timevar()244*38fd1498Szrj ~auto_timevar ()
245*38fd1498Szrj {
246*38fd1498Szrj if (m_timer)
247*38fd1498Szrj m_timer->pop (m_tv);
248*38fd1498Szrj }
249*38fd1498Szrj
250*38fd1498Szrj private:
251*38fd1498Szrj
252*38fd1498Szrj // Private to disallow copies.
253*38fd1498Szrj auto_timevar (const auto_timevar &);
254*38fd1498Szrj
255*38fd1498Szrj timer *m_timer;
256*38fd1498Szrj timevar_id_t m_tv;
257*38fd1498Szrj };
258*38fd1498Szrj
259*38fd1498Szrj extern void print_time (const char *, long);
260*38fd1498Szrj
261*38fd1498Szrj #endif /* ! GCC_TIMEVAR_H */
262