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. */
26 #ifdef HAVE_SYS_TIMES_H
27 # include <sys/times.h>
33 /* See timevar.h for an explanation of timing variables. */
35 /* This macro evaluates to non-zero if timing variables are enabled. */
36 #define TIMEVAR_ENABLE (!quiet_flag)
38 /* A timing variable. */
42 /* Elapsed time for this variable. */
43 struct timevar_time_def elapsed;
45 /* If this variable is timed independently of the timing stack,
46 using timevar_start, this contains the start time. */
47 struct timevar_time_def start_time;
49 /* The name of this timing variable. */
52 /* Non-zero if this timing variable is running as a standalone
54 unsigned standalone : 1;
56 /* Non-zero if this timing variable was ever started or pushed onto
61 /* An element on the timing stack. Elapsed time is attributed to the
62 topmost timing variable on the stack. */
64 struct timevar_stack_def
66 /* The timing variable at this stack level. */
67 struct timevar_def *timevar;
69 /* The next lower timing variable context in the stack. */
70 struct timevar_stack_def *next;
73 /* Declared timing variables. Constructed from the contents of
75 static struct timevar_def timevars[TIMEVAR_LAST];
77 /* The top of the timing stack. */
78 static struct timevar_stack_def *stack;
80 /* A list of unused (i.e. allocated and subsequently popped)
81 timevar_stack_def instances. */
82 static struct timevar_stack_def *unused_stack_instances;
84 /* The time at which the topmost element on the timing stack was
85 pushed. Time elapsed since then is attributed to the topmost
87 static struct timevar_time_def start_time;
90 PARAMS ((struct timevar_time_def *));
91 static void timevar_add
92 PARAMS ((struct timevar_time_def *, struct timevar_time_def *));
93 static void timevar_accumulate
94 PARAMS ((struct timevar_time_def *, struct timevar_time_def *,
95 struct timevar_time_def *));
97 /* Fill the current times into TIME. The definition of this function
98 also defines any or all of the HAVE_USER_TIME, HAVE_SYS_TIME, and
99 HAVA_WALL_TIME macros. */
103 struct timevar_time_def *now;
115 #if defined (_WIN32) && !defined (__CYGWIN__)
117 now->user = clock () * 1000;
118 #define HAVE_USER_TIME
120 #else /* not _WIN32 */
126 tick = 1000000 / sysconf (_SC_CLK_TCK);
127 now->wall = times (&tms) * tick;
128 now->user = tms.tms_utime * tick;
129 now->sys = tms.tms_stime * tick;
131 #define HAVE_USER_TIME
132 #define HAVE_SYS_TIME
133 #define HAVE_WALL_TIME
139 # if HAVE_SYSCONF && defined _SC_CLK_TCK
140 # define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
143 # define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
145 # define TICKS_PER_SECOND HZ /* traditional UNIX */
148 now->wall = times (&tms) * (1000000 / TICKS_PER_SECOND);
149 now->user = tms.tms_utime * (1000000 / TICKS_PER_SECOND);
150 now->sys = tms.tms_stime * (1000000 / TICKS_PER_SECOND);
152 #define HAVE_USER_TIME
153 #define HAVE_SYS_TIME
154 #define HAVE_WALL_TIME
159 struct rusage rusage;
160 getrusage (0, &rusage);
162 = rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec;
164 = rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec;
166 #define HAVE_USER_TIME
167 #define HAVE_SYS_TIME
174 int proc_system_time;
176 int child_system_time;
178 now->wall = times ((void *) &vms_times) * 10000;
179 now->user = vms_times.proc_user_time * 10000;
180 now->sys = vms_times.proc_system_time * 10000;
182 #define HAVE_USER_TIME
183 #define HAVE_SYS_TIME
184 #define HAVE_WALL_TIME
188 #endif /* _SC_CLK_TCK */
190 #endif /* __BEOS__ */
193 /* Add ELAPSED to TIMER. */
196 timevar_add (timer, elapsed)
197 struct timevar_time_def *timer;
198 struct timevar_time_def *elapsed;
200 timer->user += elapsed->user;
201 timer->sys += elapsed->sys;
202 timer->wall += elapsed->wall;
205 /* Add the difference between STOP_TIME and START_TIME to TIMER. */
208 timevar_accumulate (timer, start_time, stop_time)
209 struct timevar_time_def *timer;
210 struct timevar_time_def *start_time;
211 struct timevar_time_def *stop_time;
213 timer->user += stop_time->user - start_time->user;
214 timer->sys += stop_time->sys - start_time->sys;
215 timer->wall += stop_time->wall - start_time->wall;
218 /* Initialize timing variables. */
226 /* Zero all elapsed times. */
227 memset ((void *) timevars, 0, sizeof (timevars));
229 /* Initialize the names of timing variables. */
230 #define DEFTIMEVAR(identifer__, name__) \
231 timevars[identifer__].name = name__;
232 #include "timevar.def"
236 /* Push TIMEVAR onto the timing stack. No further elapsed time is
237 attributed to the previous topmost timing variable on the stack;
238 subsequent elapsed time is attributed to TIMEVAR, until it is
239 popped or another element is pushed on top.
241 TIMEVAR cannot be running as a standalone timer. */
244 timevar_push (timevar)
245 timevar_id_t timevar;
247 struct timevar_def *tv = &timevars[timevar];
248 struct timevar_stack_def *context;
249 struct timevar_time_def now;
254 /* Mark this timing variable as used. */
257 /* Can't push a standalone timer. */
261 /* What time is it? */
264 /* If the stack isn't empty, attribute the current elapsed time to
265 the old topmost element. */
267 timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
269 /* Reset the start time; from now on, time is attributed to
273 /* See if we have a previously-allocated stack instance. If so,
274 take it off the list. If not, malloc a new one. */
275 if (unused_stack_instances != NULL)
277 context = unused_stack_instances;
278 unused_stack_instances = unused_stack_instances->next;
281 context = (struct timevar_stack_def *)
282 xmalloc (sizeof (struct timevar_stack_def));
284 /* Fill it in and put it on the stack. */
285 context->timevar = tv;
286 context->next = stack;
290 /* Pop the topmost timing variable element off the timing stack. The
291 popped variable must be TIMEVAR. Elapsed time since the that
292 element was pushed on, or since it was last exposed on top of the
293 stack when the element above it was popped off, is credited to that
297 timevar_pop (timevar)
298 timevar_id_t timevar;
300 struct timevar_time_def now;
301 struct timevar_stack_def *popped = stack;
306 if (&timevars[timevar] != stack->timevar)
309 /* What time is it? */
312 /* Attribute the elapsed time to the element we're popping. */
313 timevar_accumulate (&popped->timevar->elapsed, &start_time, &now);
315 /* Reset the start time; from now on, time is attributed to the
316 element just exposed on the stack. */
319 /* Take the item off the stack. */
322 /* Don't delete the stack element; instead, add it to the list of
323 unused elements for later use. */
324 popped->next = unused_stack_instances;
325 unused_stack_instances = popped;
328 /* Start timing TIMEVAR independently of the timing stack. Elapsed
329 time until timevar_stop is called for the same timing variable is
330 attributed to TIMEVAR. */
333 timevar_start (timevar)
334 timevar_id_t timevar;
336 struct timevar_def *tv = &timevars[timevar];
341 /* Mark this timing variable as used. */
344 /* Don't allow the same timing variable to be started more than
350 get_time (&tv->start_time);
353 /* Stop timing TIMEVAR. Time elapsed since timevar_start was called
354 is attributed to it. */
357 timevar_stop (timevar)
358 timevar_id_t timevar;
360 struct timevar_def *tv = &timevars[timevar];
361 struct timevar_time_def now;
366 /* TIMEVAR must have been started via timevar_start. */
371 timevar_accumulate (&tv->elapsed, &tv->start_time, &now);
374 /* Fill the elapsed time for TIMEVAR into ELAPSED. Returns
375 update-to-date information even if TIMEVAR is currently running. */
378 timevar_get (timevar, elapsed)
379 timevar_id_t timevar;
380 struct timevar_time_def *elapsed;
382 struct timevar_def *tv = &timevars[timevar];
384 *elapsed = tv->elapsed;
386 /* Is TIMEVAR currently running as a standalone timer? */
388 /* Add the time elapsed since the it was started. */
389 timevar_add (elapsed, &tv->start_time);
391 /* Is TIMEVAR at the top of the timer stack? */
392 if (stack->timevar == tv)
393 /* Add the elapsed time since it was pushed. */
394 timevar_add (elapsed, &start_time);
397 /* Summarize timing variables to FP. The timing variable TV_TOTAL has
398 a special meaning -- it's considered to be the total elapsed time,
399 for normalizing the others, and is displayed last. */
405 /* Only print stuff if we have some sort of time information. */
406 #if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME)
408 struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed;
409 struct timevar_time_def now;
414 /* Update timing information in case we're calling this from GDB. */
419 /* What time is it? */
422 /* If the stack isn't empty, attribute the current elapsed time to
423 the old topmost element. */
425 timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
427 /* Reset the start time; from now on, time is attributed to
431 fprintf (fp, _("\nExecution times (seconds)\n"));
432 for (id = 0; id < TIMEVAR_LAST; ++id)
434 struct timevar_def *tv = &timevars[id];
436 /* Don't print the total execution time here; that goes at the
441 /* Don't print timing variables that were never used. */
445 /* The timing variable name. */
446 fprintf (fp, " %-22s:", tv->name);
448 #ifdef HAVE_USER_TIME
449 /* Print user-mode time for this process. */
450 fprintf (fp, "%4ld.%02ld (%2.0f%%) usr",
451 tv->elapsed.user / 1000000,
452 (tv->elapsed.user % 1000000) / 10000,
453 (total->user == 0) ? 0.0
454 : (100.0 * tv->elapsed.user / (double) total->user));
455 #endif /* HAVE_USER_TIME */
458 /* Print system-mode time for this process. */
459 fprintf (fp, "%4ld.%02ld (%2.0f%%) sys",
460 tv->elapsed.sys / 1000000,
461 (tv->elapsed.sys % 1000000) / 10000,
462 (total->sys == 0) ? 0.0
463 : (100.0 * tv->elapsed.sys / (double) total->sys));
464 #endif /* HAVE_SYS_TIME */
466 #ifdef HAVE_WALL_TIME
467 /* Print wall clock time elapsed. */
468 fprintf (fp, "%4ld.%02ld (%2.0f%%) wall",
469 tv->elapsed.wall / 1000000,
470 (tv->elapsed.wall % 1000000) / 10000,
471 (total->wall == 0) ? 0.0
472 : (100.0 * tv->elapsed.wall / (double) total->wall));
473 #endif /* HAVE_WALL_TIME */
478 /* Print total time. */
479 fprintf (fp, _(" TOTAL :"));
480 #ifdef HAVE_USER_TIME
481 fprintf (fp, "%4ld.%02ld ",
482 total->user / 1000000, (total->user % 1000000) / 10000);
485 fprintf (fp, "%4ld.%02ld ",
486 total->sys / 1000000, (total->sys % 1000000) / 10000);
488 #ifdef HAVE_WALL_TIME
489 fprintf (fp, "%4ld.%02ld\n",
490 total->wall / 1000000, (total->wall % 1000000) / 10000);
493 #endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
494 || defined (HAVE_WALL_TIME) */
497 /* Returns time (user + system) used so far by the compiler process,
503 struct timevar_time_def total_elapsed;
504 timevar_get (TV_TOTAL, &total_elapsed);
505 return total_elapsed.user + total_elapsed.sys;
508 /* Prints a message to stderr stating that time elapsed in STR is
509 TOTAL (given in microseconds). */
512 print_time (str, total)
516 long all_time = get_run_time ();
518 _("time in %s: %ld.%06ld (%ld%%)\n"),
519 str, total / 1000000, total % 1000000,
521 : (long) (((100.0 * (double) total) / (double) all_time) + .5));