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