xref: /dragonfly/contrib/gcc-8.0/gcc/timevar.h (revision 38fd1498)
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