1 /* Timing variables for measuring compiler performance.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3 Contributed by Alex Samuel <samuel@codesourcery.com>
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
25 #ifdef HAVE_SYS_TIMES_H
26 # include <sys/times.h>
32 /* See timevar.h for an explanation of timing variables. */
34 /* This macro evaluates to non-zero if timing variables are enabled. */
35 #define TIMEVAR_ENABLE (!quiet_flag)
37 /* A timing variable. */
41 /* Elapsed time for this variable. */
42 struct timevar_time_def elapsed;
44 /* If this variable is timed independently of the timing stack,
45 using timevar_start, this contains the start time. */
46 struct timevar_time_def start_time;
48 /* The name of this timing variable. */
51 /* Non-zero if this timing variable is running as a standalone
53 unsigned standalone : 1;
55 /* Non-zero if this timing variable was ever started or pushed onto
60 /* An element on the timing stack. Elapsed time is attributed to the
61 topmost timing variable on the stack. */
63 struct timevar_stack_def
65 /* The timing variable at this stack level. */
66 struct timevar_def *timevar;
68 /* The next lower timing variable context in the stack. */
69 struct timevar_stack_def *next;
72 /* Declared timing variables. Constructed from the contents of
74 static struct timevar_def timevars[TIMEVAR_LAST];
76 /* The top of the timing stack. */
77 static struct timevar_stack_def *stack;
79 /* A list of unused (i.e. allocated and subsequently popped)
80 timevar_stack_def instances. */
81 static struct timevar_stack_def *unused_stack_instances;
83 /* The time at which the topmost element on the timing stack was
84 pushed. Time elapsed since then is attributed to the topmost
86 static struct timevar_time_def start_time;
89 PARAMS ((struct timevar_time_def *));
90 static void timevar_add
91 PARAMS ((struct timevar_time_def *, struct timevar_time_def *));
92 static void timevar_accumulate
93 PARAMS ((struct timevar_time_def *, struct timevar_time_def *,
94 struct timevar_time_def *));
96 /* Fill the current times into TIME. The definition of this function
97 also defines any or all of the HAVE_USER_TIME, HAVE_SYS_TIME, and
98 HAVA_WALL_TIME macros. */
102 struct timevar_time_def *now;
114 #if defined (_WIN32) && !defined (__CYGWIN__)
116 now->user = clock () * 1000;
117 #define HAVE_USER_TIME
119 #else /* not _WIN32 */
125 tick = 1000000 / sysconf (_SC_CLK_TCK);
126 now->wall = times (&tms) * tick;
127 now->user = tms.tms_utime * tick;
128 now->sys = tms.tms_stime * tick;
130 #define HAVE_USER_TIME
131 #define HAVE_SYS_TIME
132 #define HAVE_WALL_TIME
138 # if HAVE_SYSCONF && defined _SC_CLK_TCK
139 # define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
142 # define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
144 # define TICKS_PER_SECOND HZ /* traditional UNIX */
147 now->wall = times (&tms) * (1000000 / TICKS_PER_SECOND);
148 now->user = tms.tms_utime * (1000000 / TICKS_PER_SECOND);
149 now->sys = tms.tms_stime * (1000000 / TICKS_PER_SECOND);
151 #define HAVE_USER_TIME
152 #define HAVE_SYS_TIME
153 #define HAVE_WALL_TIME
158 struct rusage rusage;
159 getrusage (0, &rusage);
161 = rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec;
163 = rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec;
165 #define HAVE_USER_TIME
166 #define HAVE_SYS_TIME
173 int proc_system_time;
175 int child_system_time;
177 now->wall = times ((void *) &vms_times) * 10000;
178 now->user = vms_times.proc_user_time * 10000;
179 now->sys = vms_times.proc_system_time * 10000;
181 #define HAVE_USER_TIME
182 #define HAVE_SYS_TIME
183 #define HAVE_WALL_TIME
187 #endif /* _SC_CLK_TCK */
189 #endif /* __BEOS__ */
192 /* Add ELAPSED to TIMER. */
195 timevar_add (timer, elapsed)
196 struct timevar_time_def *timer;
197 struct timevar_time_def *elapsed;
199 timer->user += elapsed->user;
200 timer->sys += elapsed->sys;
201 timer->wall += elapsed->wall;
204 /* Add the difference between STOP_TIME and START_TIME to TIMER. */
207 timevar_accumulate (timer, start_time, stop_time)
208 struct timevar_time_def *timer;
209 struct timevar_time_def *start_time;
210 struct timevar_time_def *stop_time;
212 timer->user += stop_time->user - start_time->user;
213 timer->sys += stop_time->sys - start_time->sys;
214 timer->wall += stop_time->wall - start_time->wall;
217 /* Initialize timing variables. */
225 /* Zero all elapsed times. */
226 memset ((void *) timevars, 0, sizeof (timevars));
228 /* Initialize the names of timing variables. */
229 #define DEFTIMEVAR(identifer__, name__) \
230 timevars[identifer__].name = name__;
231 #include "timevar.def"
235 /* Push TIMEVAR onto the timing stack. No further elapsed time is
236 attributed to the previous topmost timing variable on the stack;
237 subsequent elapsed time is attributed to TIMEVAR, until it is
238 popped or another element is pushed on top.
240 TIMEVAR cannot be running as a standalone timer. */
243 timevar_push (timevar)
244 timevar_id_t timevar;
246 struct timevar_def *tv = &timevars[timevar];
247 struct timevar_stack_def *context;
248 struct timevar_time_def now;
253 /* Mark this timing variable as used. */
256 /* Can't push a standalone timer. */
260 /* What time is it? */
263 /* If the stack isn't empty, attribute the current elapsed time to
264 the old topmost element. */
266 timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
268 /* Reset the start time; from now on, time is attributed to
272 /* See if we have a previously-allocated stack instance. If so,
273 take it off the list. If not, malloc a new one. */
274 if (unused_stack_instances != NULL)
276 context = unused_stack_instances;
277 unused_stack_instances = unused_stack_instances->next;
280 context = (struct timevar_stack_def *)
281 xmalloc (sizeof (struct timevar_stack_def));
283 /* Fill it in and put it on the stack. */
284 context->timevar = tv;
285 context->next = stack;
289 /* Pop the topmost timing variable element off the timing stack. The
290 popped variable must be TIMEVAR. Elapsed time since the that
291 element was pushed on, or since it was last exposed on top of the
292 stack when the element above it was popped off, is credited to that
296 timevar_pop (timevar)
297 timevar_id_t timevar;
299 struct timevar_time_def now;
300 struct timevar_stack_def *popped = stack;
305 if (&timevars[timevar] != stack->timevar)
308 /* What time is it? */
311 /* Attribute the elapsed time to the element we're popping. */
312 timevar_accumulate (&popped->timevar->elapsed, &start_time, &now);
314 /* Reset the start time; from now on, time is attributed to the
315 element just exposed on the stack. */
318 /* Take the item off the stack. */
321 /* Don't delete the stack element; instead, add it to the list of
322 unused elements for later use. */
323 popped->next = unused_stack_instances;
324 unused_stack_instances = popped;
327 /* Start timing TIMEVAR independently of the timing stack. Elapsed
328 time until timevar_stop is called for the same timing variable is
329 attributed to TIMEVAR. */
332 timevar_start (timevar)
333 timevar_id_t timevar;
335 struct timevar_def *tv = &timevars[timevar];
340 /* Mark this timing variable as used. */
343 /* Don't allow the same timing variable to be started more than
349 get_time (&tv->start_time);
352 /* Stop timing TIMEVAR. Time elapsed since timevar_start was called
353 is attributed to it. */
356 timevar_stop (timevar)
357 timevar_id_t timevar;
359 struct timevar_def *tv = &timevars[timevar];
360 struct timevar_time_def now;
365 /* TIMEVAR must have been started via timevar_start. */
370 timevar_accumulate (&tv->elapsed, &tv->start_time, &now);
373 /* Fill the elapsed time for TIMEVAR into ELAPSED. Returns
374 update-to-date information even if TIMEVAR is currently running. */
377 timevar_get (timevar, elapsed)
378 timevar_id_t timevar;
379 struct timevar_time_def *elapsed;
381 struct timevar_def *tv = &timevars[timevar];
383 *elapsed = tv->elapsed;
385 /* Is TIMEVAR currently running as a standalone timer? */
387 /* Add the time elapsed since the it was started. */
388 timevar_add (elapsed, &tv->start_time);
390 /* Is TIMEVAR at the top of the timer stack? */
391 if (stack->timevar == tv)
392 /* Add the elapsed time since it was pushed. */
393 timevar_add (elapsed, &start_time);
396 /* Summarize timing variables to FP. The timing variable TV_TOTAL has
397 a special meaning -- it's considered to be the total elapsed time,
398 for normalizing the others, and is displayed last. */
404 /* Only print stuff if we have some sort of time information. */
405 #if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME)
407 struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed;
408 struct timevar_time_def now;
413 /* Update timing information in case we're calling this from GDB. */
418 /* What time is it? */
421 /* If the stack isn't empty, attribute the current elapsed time to
422 the old topmost element. */
424 timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
426 /* Reset the start time; from now on, time is attributed to
430 fprintf (fp, _("\nExecution times (seconds)\n"));
431 for (id = 0; id < TIMEVAR_LAST; ++id)
433 struct timevar_def *tv = &timevars[id];
435 /* Don't print the total execution time here; that goes at the
440 /* Don't print timing variables that were never used. */
444 /* The timing variable name. */
445 fprintf (fp, " %-22s:", tv->name);
447 #ifdef HAVE_USER_TIME
448 /* Print user-mode time for this process. */
449 fprintf (fp, "%4ld.%02ld (%2.0f%%) usr",
450 tv->elapsed.user / 1000000,
451 (tv->elapsed.user % 1000000) / 10000,
452 (total->user == 0) ? 0.0
453 : (100.0 * tv->elapsed.user / (double) total->user));
454 #endif /* HAVE_USER_TIME */
457 /* Print system-mode time for this process. */
458 fprintf (fp, "%4ld.%02ld (%2.0f%%) sys",
459 tv->elapsed.sys / 1000000,
460 (tv->elapsed.sys % 1000000) / 10000,
461 (total->sys == 0) ? 0.0
462 : (100.0 * tv->elapsed.sys / (double) total->sys));
463 #endif /* HAVE_SYS_TIME */
465 #ifdef HAVE_WALL_TIME
466 /* Print wall clock time elapsed. */
467 fprintf (fp, "%4ld.%02ld (%2.0f%%) wall",
468 tv->elapsed.wall / 1000000,
469 (tv->elapsed.wall % 1000000) / 10000,
470 (total->wall == 0) ? 0.0
471 : (100.0 * tv->elapsed.wall / (double) total->wall));
472 #endif /* HAVE_WALL_TIME */
477 /* Print total time. */
478 fprintf (fp, _(" TOTAL :"));
479 #ifdef HAVE_USER_TIME
480 fprintf (fp, "%4ld.%02ld ",
481 total->user / 1000000, (total->user % 1000000) / 10000);
484 fprintf (fp, "%4ld.%02ld ",
485 total->sys / 1000000, (total->sys % 1000000) / 10000);
487 #ifdef HAVE_WALL_TIME
488 fprintf (fp, "%4ld.%02ld\n",
489 total->wall / 1000000, (total->wall % 1000000) / 10000);
492 #endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
493 || defined (HAVE_WALL_TIME) */
496 /* Returns time (user + system) used so far by the compiler process,
502 struct timevar_time_def total_elapsed;
503 timevar_get (TV_TOTAL, &total_elapsed);
504 return total_elapsed.user + total_elapsed.sys;
507 /* Prints a message to stderr stating that time elapsed in STR is
508 TOTAL (given in microseconds). */
511 print_time (str, total)
515 long all_time = get_run_time ();
517 _("time in %s: %ld.%06ld (%ld%%)\n"),
518 str, total / 1000000, total % 1000000,
520 : (long) (((100.0 * (double) total) / (double) all_time) + .5));