summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorsamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-04-28 00:59:40 +0000
committersamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-04-28 00:59:40 +0000
commit74d2af64d63318d222416bac013bb32cbabb725c (patch)
tree721fcd61f706b846a8cfad4302cec9e16abe799a /gcc
parentd31bba8b87a06bf99851897c356d5c1161aebd4f (diff)
downloadgcc-74d2af64d63318d222416bac013bb32cbabb725c.tar.gz
hangeLog:
* Makefile.in (OBJS): Add timevar.o. (toplev.o): Depend on timevar.h. (ggc-simple.o): Likewise. (ggc-page.o): Likewise. (timevar.o): New rule. (timevar.h): New rule. * timevar.h: New file. * timevar.c: Likewise. * timevar.def: Likewise. * toplev.h (gc_time, parse_time, varconst_time): Remove. * toplev.c: Use timevar_push and timevar_pop instead of TIMEVAR throughout. (TIMEVAR): Remove macro. (gc_time, parse_time, varconst_time, integration_time, jump_time, cse_time, gcse_time, loop_time, cse2_time, branch_prob_time, flow_time, combine_time, regmove_time, sched_time, local_alloc_time, global_alloc_time, flow2_time, peephole2_time, sched2_time, dbr_sched_time, reorder_blocks_time, rename_registers_time, shorten_branch_time, stack_reg_time, to_ssa_time, from_ssa_time, final_time, symout_time, dump_time, all_time): Remove. (compile_file): Don't initialize time variables. Call init_timevar and start TV_TOTAL timer. Call timevar_print instead of many calls to print_time. (rest_of_compilation): Add timing for reload_cse_regs. (get_run_time): Removed to timevar.c. (print_time): Likewise. (get_run_time): Implement using TV_TOTAL time variable. (print_time): Get total run time from get_run_time. * ggc-page.c (ggc_collect): Push and pop TV_GC instead of computing elapsed time explicitly. * ggc-simple.c (ggc_collect): Likewise. (gc_time): Remove declaration. cp/ChangeLog: * lex.c (my_get_run_time): Remove. (init_filename_times): Use get_run_time instead of my_get_run_time. (check_newline): Likewise. (dump_time_statistics): Likewise. * decl2.c (finish_file): Push and pop timevar TV_VARCONST instead of computing elapsed time explicitly. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33496 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog38
-rw-r--r--gcc/Makefile.in10
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/decl2.c8
-rw-r--r--gcc/cp/lex.c19
-rw-r--r--gcc/ggc-page.c13
-rw-r--r--gcc/ggc-simple.c14
-rw-r--r--gcc/timevar.c448
-rw-r--r--gcc/timevar.def73
-rw-r--r--gcc/timevar.h86
-rw-r--r--gcc/toplev.c999
-rw-r--r--gcc/toplev.h4
12 files changed, 1101 insertions, 620 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc52ec72e13..35d7605fbbd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,41 @@
+2000-04-27 Alex Samuel <samuel@codesourcery.com>
+
+ * Makefile.in (OBJS): Add timevar.o.
+ (toplev.o): Depend on timevar.h.
+ (ggc-simple.o): Likewise.
+ (ggc-page.o): Likewise.
+ (timevar.o): New rule.
+ (timevar.h): New rule.
+
+ * timevar.h: New file.
+ * timevar.c: Likewise.
+ * timevar.def: Likewise.
+
+ * toplev.h (gc_time, parse_time, varconst_time): Remove.
+ * toplev.c: Use timevar_push and timevar_pop instead of TIMEVAR
+ throughout.
+ (TIMEVAR): Remove macro.
+ (gc_time, parse_time, varconst_time, integration_time, jump_time,
+ cse_time, gcse_time, loop_time, cse2_time, branch_prob_time,
+ flow_time, combine_time, regmove_time, sched_time,
+ local_alloc_time, global_alloc_time, flow2_time, peephole2_time,
+ sched2_time, dbr_sched_time, reorder_blocks_time,
+ rename_registers_time, shorten_branch_time, stack_reg_time,
+ to_ssa_time, from_ssa_time, final_time, symout_time, dump_time,
+ all_time): Remove.
+ (compile_file): Don't initialize time variables. Call
+ init_timevar and start TV_TOTAL timer. Call timevar_print instead
+ of many calls to print_time.
+ (rest_of_compilation): Add timing for reload_cse_regs.
+ (get_run_time): Removed to timevar.c.
+ (print_time): Likewise.
+ (get_run_time): Implement using TV_TOTAL time variable.
+ (print_time): Get total run time from get_run_time.
+ * ggc-page.c (ggc_collect): Push and pop TV_GC instead of
+ computing elapsed time explicitly.
+ * ggc-simple.c (ggc_collect): Likewise.
+ (gc_time): Remove declaration.
+
2000-04-27 Mark Mitchell <mark@codesourcery.com>
* calls.c (combine_pending_stack_adjustment_and_call): New function.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 50856b8d955..e3c13f0b050 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -684,7 +684,7 @@ OBJS = diagnostic.o \
profile.o insn-attrtab.o $(out_object_file) $(EXTRA_OBJS) convert.o \
mbchar.o dyn-string.o splay-tree.o graph.o sbitmap.o resource.o hash.o \
predict.o lists.o ggc-common.o $(GGC) simplify-rtx.o ssa.o bb-reorder.o \
- sibcall.o conflict.o
+ sibcall.o conflict.o timevar.o
# GEN files are listed separately, so they can be built before doing parallel
# makes for cc1 or cc1plus. Otherwise sequent parallel make attempts to load
@@ -1470,10 +1470,10 @@ ggc-common.o: ggc-common.c $(CONFIG_H) $(RTL_H) $(TREE_H) \
flags.h $(GGC_H) varray.h hash.h
ggc-simple.o: ggc-simple.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
- $(GGC_H) varray.h
+ $(GGC_H) varray.h timevar.h
ggc-page.o: ggc-page.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h toplev.h \
- $(GGC_H) varray.h
+ $(GGC_H) varray.h timevar.h
ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_H) $(GGC_H)
@@ -1505,7 +1505,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \
insn-codes.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h dwarfout.h \
dwarf2out.h sdbout.h dbxout.h $(EXPR_H) $(BASIC_BLOCK_H) graph.h loop.h \
- except.h regs.h $(lang_options_files)
+ except.h regs.h timevar.h $(lang_options_files)
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(MAYBE_USE_COLLECT2) \
-DTARGET_NAME=\"$(target_alias)\" \
-c `echo $(srcdir)/toplev.c | sed 's,^\./,,'`
@@ -1658,6 +1658,8 @@ lists.o: lists.c $(CONFIG_H) system.h toplev.h $(RTL_H) $(GGC_H)
bb-reorder.o : bb-reorder.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) insn-flags.h function.h except.h $(EXPR_H)
+timevar.o : timevar.c $(CONFIG_H) system.h timevar.h timevar.def
+timevar.h : timevar.def
regrename.o : regrename.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h \
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f8357254c7e..fdad42247fb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2000-04-27 Alex Samuel <samuel@codesourcery.com>
+
+ * lex.c (my_get_run_time): Remove.
+ (init_filename_times): Use get_run_time instead of my_get_run_time.
+ (check_newline): Likewise.
+ (dump_time_statistics): Likewise.
+ * decl2.c (finish_file): Push and pop timevar TV_VARCONST instead
+ of computing elapsed time explicitly.
+
2000-04-26 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (TREE_READONLY_DECL_P): Use DECL_P.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index dd89057f0a4..99473a88a09 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA. */
#include "dwarf2out.h"
#include "dwarfout.h"
#include "ggc.h"
+#include "timevar.h"
#if USE_CPPLIB
#include "cpplib.h"
@@ -3429,7 +3430,6 @@ generate_ctor_and_dtor_functions_for_priority (n, data)
void
finish_file ()
{
- long start_time, this_time;
tree vars;
int reconsider;
size_t i;
@@ -3463,7 +3463,7 @@ finish_file ()
generating the intiailzer for an object may cause templates to be
instantiated, etc., etc. */
- start_time = get_run_time ();
+ timevar_push (TV_VARCONST);
if (new_abi_rtti_p ())
emit_support_tinfos ();
@@ -3686,9 +3686,7 @@ finish_file ()
if (back_end_hook)
(*back_end_hook) (global_namespace);
- this_time = get_run_time ();
- parse_time -= this_time - start_time;
- varconst_time += this_time - start_time;
+ timevar_pop (TV_VARCONST);
if (flag_detailed_statistics)
{
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 7dc6d308422..ba32971d259 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "ggc.h"
#include "tm_p.h"
+#include "timevar.h"
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
@@ -56,7 +57,6 @@ static int check_newline PARAMS ((void));
static int whitespace_cr PARAMS ((int));
static int skip_white_space PARAMS ((int));
static void finish_defarg PARAMS ((void));
-static int my_get_run_time PARAMS ((void));
static int interface_strcmp PARAMS ((const char *));
static int readescape PARAMS ((int *));
static char *extend_token_buffer PARAMS ((const char *));
@@ -388,17 +388,6 @@ get_time_identifier (name)
}
return time_identifier;
}
-
-static inline int
-my_get_run_time ()
-{
- int old_quiet_flag = quiet_flag;
- int this_time;
- quiet_flag = 0;
- this_time = get_run_time ();
- quiet_flag = old_quiet_flag;
- return this_time;
-}
/* Table indexed by tree code giving a string containing a character
classifying the tree code. Possibilities are
@@ -488,7 +477,7 @@ init_filename_times ()
if (flag_detailed_statistics)
{
header_time = 0;
- body_time = my_get_run_time ();
+ body_time = get_run_time ();
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
= body_time;
}
@@ -2390,7 +2379,7 @@ linenum:
is charged against header time, and body time starts back at 0. */
if (flag_detailed_statistics)
{
- int this_time = my_get_run_time ();
+ int this_time = get_run_time ();
tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
header_time += this_time - body_time;
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
@@ -5086,7 +5075,7 @@ void
dump_time_statistics ()
{
register tree prev = 0, decl, next;
- int this_time = my_get_run_time ();
+ int this_time = get_run_time ();
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+= this_time - body_time;
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index 7fc8b2c3038..924e952b336 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */
#include "varray.h"
#include "flags.h"
#include "ggc.h"
+#include "timevar.h"
#ifdef HAVE_MMAP_ANYWHERE
#include <sys/mman.h>
@@ -1101,8 +1102,6 @@ poison_pages ()
void
ggc_collect ()
{
- long time;
-
/* Avoid frequent unnecessary work by skipping collection if the
total allocations haven't expanded much since the last
collection. */
@@ -1111,7 +1110,7 @@ ggc_collect ()
return;
#endif
- time = get_run_time ();
+ timevar_push (TV_GC);
if (!quiet_flag)
fprintf (stderr, " {GC %luk -> ", (unsigned long) G.allocated / 1024);
@@ -1136,14 +1135,10 @@ ggc_collect ()
if (G.allocated_last_gc < GGC_MIN_LAST_ALLOCATED)
G.allocated_last_gc = GGC_MIN_LAST_ALLOCATED;
- time = get_run_time () - time;
- gc_time += time;
+ timevar_pop (TV_GC);
if (!quiet_flag)
- {
- fprintf (stderr, "%luk in %.3f}",
- (unsigned long) G.allocated / 1024, time * 1e-6);
- }
+ fprintf (stderr, "%luk}", (unsigned long) G.allocated / 1024);
}
/* Print allocation statistics. */
diff --git a/gcc/ggc-simple.c b/gcc/ggc-simple.c
index 6d1545c4112..b7b6a660bea 100644
--- a/gcc/ggc-simple.c
+++ b/gcc/ggc-simple.c
@@ -26,6 +26,7 @@
#include "flags.h"
#include "varray.h"
#include "ggc.h"
+#include "timevar.h"
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
@@ -58,7 +59,6 @@
/* Constants for general use. */
char *empty_string;
-extern int gc_time;
#ifndef HOST_BITS_PER_PTR
#define HOST_BITS_PER_PTR HOST_BITS_PER_LONG
@@ -339,8 +339,6 @@ sweep_objs (root)
void
ggc_collect ()
{
- int time;
-
#ifndef GGC_ALWAYS_COLLECT
if (G.allocated < GGC_MIN_EXPAND_FOR_GC * G.allocated_last_gc)
return;
@@ -350,7 +348,7 @@ ggc_collect ()
debug_ggc_balance ();
#endif
- time = get_run_time ();
+ timevar_push (TV_GC);
if (!quiet_flag)
fprintf (stderr, " {GC %luk -> ", (unsigned long)G.allocated / 1024);
@@ -365,14 +363,10 @@ ggc_collect ()
if (G.allocated_last_gc < GGC_MIN_LAST_ALLOCATED)
G.allocated_last_gc = GGC_MIN_LAST_ALLOCATED;
- time = get_run_time () - time;
- gc_time += time;
+ timevar_pop (TV_GC);
if (!quiet_flag)
- {
- fprintf (stderr, "%luk in %.3f}",
- (unsigned long) G.allocated / 1024, time * 1e-6);
- }
+ fprintf (stderr, "%luk}", (unsigned long) G.allocated / 1024);
#ifdef GGC_BALANCE
debug_ggc_balance ();
diff --git a/gcc/timevar.c b/gcc/timevar.c
new file mode 100644
index 00000000000..61fc92d21ce
--- /dev/null
+++ b/gcc/timevar.c
@@ -0,0 +1,448 @@
+/* Timing variables for measuring compiler performance.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Alex Samuel <samuel@codesourcery.com>
+
+ This file is part of GNU CC.
+
+ GNU CC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+
+#ifdef HAVE_SYS_TIMES_H
+# include <sys/times.h>
+#endif
+
+#include "timevar.h"
+
+/* See timevar.h for an explanation of timing variables. */
+
+/* A timing variable. */
+
+struct timevar_def
+{
+ /* Elapsed time for this variable. */
+ struct timevar_time_def elapsed;
+
+ /* If this variable is timed independently of the timing stack,
+ using timevar_start, this contains the start time. */
+ struct timevar_time_def start_time;
+
+ /* Non-zero if this timing variable is running as a standalone
+ timer. */
+ int standalone;
+
+ /* The name of this timing variable. */
+ const char *name;
+};
+
+/* An element on the timing stack. Elapsed time is attributed to the
+ topmost timing variable on the stack. */
+
+struct timevar_stack_def
+{
+ /* The timing variable at this stack level. */
+ struct timevar_def *timevar;
+
+ /* The next lower timing variable context in the stack. */
+ struct timevar_stack_def *next;
+};
+
+/* Declared timing variables. Constructed from the contents of
+ timevar.def. */
+static struct timevar_def timevars[TIMEVAR_LAST];
+
+/* The top of the timing stack. */
+static struct timevar_stack_def *stack;
+
+/* The time at which the topmost element on the timing stack was
+ pushed. Time elapsed since then is attributed to the topmost
+ element. */
+static struct timevar_time_def start_time;
+
+static void get_time
+ PARAMS ((struct timevar_time_def *));
+static void timevar_add
+ PARAMS ((struct timevar_time_def *, struct timevar_time_def *));
+static void timevar_accumulate
+ PARAMS ((struct timevar_time_def *, struct timevar_time_def *,
+ struct timevar_time_def *));
+
+/* Fill the current times into TIME. The definition of this function
+ also defines any or all of the HAVE_USER_TIME, HAVE_SYS_TIME, and
+ HAVA_WALL_TIME macros. */
+
+static void
+get_time (time)
+ struct timevar_time_def *time;
+{
+ time->user = 0;
+ time->sys = 0;
+ time->wall = 0;
+
+#ifdef __BEOS__
+ /* Nothing. */
+#else /* not BeOS */
+#if defined (_WIN32) && !defined (__CYGWIN__)
+ if (clock () >= 0)
+ time->user = clock () * 1000;
+#define HAVE_USER_TIME
+
+#else /* not _WIN32 */
+#ifdef _SC_CLK_TCK
+ {
+ static int tick;
+ struct tms tms;
+ if (tick == 0)
+ tick = 1000000 / sysconf (_SC_CLK_TCK);
+ time->wall = times (&tms) * tick;
+ time->user = tms.tms_utime * tick;
+ time->sys = tms.tms_stime * tick;
+ }
+#define HAVE_USER_TIME
+#define HAVE_SYS_TIME
+#define HAVE_WALL_TIME
+
+#else
+#ifdef USG
+ {
+ struct tms tms;
+# if HAVE_SYSCONF && defined _SC_CLK_TCK
+# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
+# else
+# ifdef CLK_TCK
+# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
+# else
+# define TICKS_PER_SECOND HZ /* traditional UNIX */
+# endif
+# endif
+ time->wall = times (&tms) * (1000000 / TICKS_PER_SECOND);
+ time->user = tms.tms_utime * (1000000 / TICKS_PER_SECOND);
+ time->sys = tms.tms_stime * (1000000 / TICKS_PER_SECOND);
+ }
+#define HAVE_USER_TIME
+#define HAVE_SYS_TIME
+#define HAVE_WALL_TIME
+
+#else
+#ifndef VMS
+ {
+ struct rusage rusage;
+ getrusage (0, &rusage);
+ time->user
+ = rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec;
+ time->sys
+ = rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec;
+ }
+#define HAVE_USER_TIME
+#define HAVE_SYS_TIME
+
+#else /* VMS */
+ {
+ struct
+ {
+ int proc_user_time;
+ int proc_system_time;
+ int child_user_time;
+ int child_system_time;
+ } vms_times;
+ time->wall = times ((void *) &vms_times) * 10000;
+ time->user = vms_times.proc_user_time * 10000;
+ time->sys = vms_times.proc_system_time * 10000;
+ }
+#define HAVE_USER_TIME
+#define HAVE_SYS_TIME
+#define HAVE_WALL_TIME
+
+#endif /* VMS */
+#endif /* USG */
+#endif /* _SC_CLK_TCK */
+#endif /* _WIN32 */
+#endif /* __BEOS__ */
+}
+
+/* Add ELAPSED to TIMER. */
+
+static void
+timevar_add (timer, elapsed)
+ struct timevar_time_def *timer;
+ struct timevar_time_def *elapsed;
+{
+ timer->user += elapsed->user;
+ timer->sys += elapsed->sys;
+ timer->wall += elapsed->wall;
+}
+
+/* Add the difference between STOP_TIME and START_TIME to TIMER. */
+
+static void
+timevar_accumulate (timer, start_time, stop_time)
+ struct timevar_time_def *timer;
+ struct timevar_time_def *start_time;
+ struct timevar_time_def *stop_time;
+{
+ timer->user += stop_time->user - start_time->user;
+ timer->sys += stop_time->sys - start_time->sys;
+ timer->wall += stop_time->wall - start_time->wall;
+}
+
+/* Initialize timing variables. */
+
+void
+init_timevar (void)
+{
+ /* Zero all elapsed times. */
+ memset ((void *) timevars, 0, sizeof (timevars));
+
+ /* Initialize the names of timing variables. */
+#define DEFTIMEVAR(identifer__, name__) \
+ timevars[identifer__].name = name__;
+#include "timevar.def"
+#undef DEFTIMEVAR
+}
+
+/* Push TIMEVAR onto the timing stack. No further elapsed time is
+ attributed to the previous topmost timing variable on the stack;
+ subsequent elapsed time is attributed to TIMEVAR, until it is
+ popped or another element is pushed on top.
+
+ TIMEVAR cannot be running as a standalone timer. */
+
+void
+timevar_push (timevar)
+ timevar_id_t timevar;
+{
+ struct timevar_def *tv = &timevars[timevar];
+ struct timevar_stack_def *context;
+ struct timevar_time_def now;
+
+ /* Can't push a standalone timer. */
+ if (tv->standalone)
+ abort ();
+
+ /* What time is it? */
+ get_time (&now);
+
+ /* If the stack isn't empty, attribute the current elapsed time to
+ the old topmost element. */
+ if (stack)
+ timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
+
+ /* Reset the start time; from now on, time is attributed to
+ TIMEVAR. */
+ start_time = now;
+
+ /* Create a new stack element, and push it. */
+ context = (struct timevar_stack_def *)
+ xmalloc (sizeof (struct timevar_stack_def));
+ context->timevar = tv;
+ context->next = stack;
+ stack = context;
+}
+
+/* Pop the topmost timing variable element off the timing stack. The
+ popped variable must be TIMEVAR. Elapsed time since the that
+ element was pushed on, or since it was last exposed on top of the
+ stack when the element above it was popped off, is credited to that
+ timing variable. */
+
+void
+timevar_pop (timevar)
+ timevar_id_t timevar;
+{
+ struct timevar_time_def now;
+ struct timevar_stack_def *next = stack->next;
+
+ if (&timevars[timevar] != stack->timevar)
+ abort ();
+
+ /* What time is it? */
+ get_time (&now);
+
+ /* Attribute the elapsed time to the element we're popping. */
+ timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
+
+ /* Reset the start time; from now on, time is attributed to the
+ element just exposed on the stack. */
+ start_time = now;
+
+ /* Remove the stack element. */
+ free (stack);
+ stack = next;
+}
+
+/* Start timing TIMEVAR independently of the timing stack. Elapsed
+ time until timevar_stop is called for the same timing variable is
+ attributed to TIMEVAR. */
+
+void
+timevar_start (timevar)
+ timevar_id_t timevar;
+{
+ struct timevar_def *tv = &timevars[timevar];
+
+ /* Don't allow the same timing variable to be started more than
+ once. */
+ if (tv->standalone)
+ abort ();
+ tv->standalone = 1;
+
+ get_time (&tv->start_time);
+}
+
+/* Stop timing TIMEVAR. Time elapsed since timevar_start was called
+ is attributed to it. */
+
+void
+timevar_stop (timevar)
+ timevar_id_t timevar;
+{
+ struct timevar_def *tv = &timevars[timevar];
+ struct timevar_time_def now;
+
+ /* TIMEVAR must have been started via timevar_start. */
+ if (!tv->standalone)
+ abort ();
+
+ get_time (&now);
+ timevar_accumulate (&tv->elapsed, &tv->start_time, &now);
+}
+
+/* Fill the elapsed time for TIMEVAR into ELAPSED. Returns
+ update-to-date information even if TIMEVAR is currently running. */
+
+void
+timevar_get (timevar, elapsed)
+ timevar_id_t timevar;
+ struct timevar_time_def *elapsed;
+{
+ struct timevar_def *tv = &timevars[timevar];
+
+ *elapsed = tv->elapsed;
+
+ /* Is TIMEVAR currently running as a standalone timer? */
+ if (tv->standalone)
+ /* Add the time elapsed since the it was started. */
+ timevar_add (elapsed, &tv->start_time);
+
+ /* Is TIMEVAR at the top of the timer stack? */
+ if (stack->timevar == tv)
+ /* Add the elapsed time since it was pushed. */
+ timevar_add (elapsed, &start_time);
+}
+
+/* Summarize timing variables to FP. The timing variable TV_TOTAL has
+ a special meaning -- it's considered to be the total elapsed time,
+ for normalizing the others, and is displayed last. */
+
+void
+timevar_print (fp)
+ FILE *fp;
+{
+ /* Only print stuff if we have some sort of time information. */
+#if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME)
+ timevar_id_t id;
+ struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed;
+
+ fprintf (fp, "\nExecution times (seconds)\n");
+ for (id = 0; id < TIMEVAR_LAST; ++id)
+ {
+ struct timevar_def *tv = &timevars[id];
+
+ /* Don't print the total execution time here; that goes at the
+ end. */
+ if (id == TV_TOTAL)
+ continue;
+
+ /* The timing variable name. */
+ fprintf (fp, " %-22s:", tv->name);
+
+#ifdef HAVE_USER_TIME
+ /* Print user-mode time for this process. */
+ fprintf (fp, "%4ld.%02ld (%2.0f%%) usr",
+ tv->elapsed.user / 1000000,
+ (tv->elapsed.user % 1000000) / 10000,
+ (total->user == 0) ? 0.0
+ : (100.0 * tv->elapsed.user / (double) total->user));
+#endif /* HAVE_USER_TIME */
+
+#ifdef HAVE_SYS_TIME
+ /* Print system-mode time for this process. */
+ fprintf (fp, "%4ld.%02ld (%2.0f%%) sys",
+ tv->elapsed.sys / 1000000,
+ (tv->elapsed.sys % 1000000) / 10000,
+ (total->sys == 0) ? 0.0
+ : (100.0 * tv->elapsed.sys / (double) total->sys));
+#endif /* HAVE_SYS_TIME */
+
+#ifdef HAVE_WALL_TIME
+ /* Print wall clock time elapsed. */
+ fprintf (fp, "%4ld.%02ld (%2.0f%%) wall",
+ tv->elapsed.wall / 1000000,
+ (tv->elapsed.wall % 1000000) / 10000,
+ (total->wall == 0) ? 0.0
+ : (100.0 * tv->elapsed.wall / (double) total->wall));
+#endif /* HAVE_WALL_TIME */
+
+ fprintf (fp, "\n");
+ }
+
+ /* Print total time. */
+ fprintf (fp, " TOTAL :");
+#ifdef HAVE_USER_TIME
+ fprintf (fp, "%4ld.%02ld ",
+ total->user / 1000000, (total->user % 1000000) / 10000);
+#endif
+#ifdef HAVE_SYS_TIME
+ fprintf (fp, "%4ld.%02ld ",
+ total->sys / 1000000, (total->sys % 1000000) / 10000);
+#endif
+#ifdef HAVE_WALL_TIME
+ fprintf (fp, "%4ld.%02ld\n",
+ total->wall / 1000000, (total->wall % 1000000) / 10000);
+#endif
+
+#endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
+ || defined (HAVE_WALL_TIME) */
+}
+
+/* Returns time (user + system) used so far by the compiler process,
+ in microseconds. */
+
+long
+get_run_time ()
+{
+ struct timevar_time_def total_elapsed;
+ timevar_get (TV_TOTAL, &total_elapsed);
+ return total_elapsed.user + total_elapsed.sys;
+}
+
+/* Prints a message to stderr stating that time elapsed in STR is
+ TOTAL (given in microseconds). */
+
+void
+print_time (str, total)
+ const char *str;
+ long total;
+{
+ long all_time = get_run_time ();
+ fprintf (stderr,
+ "time in %s: %ld.%06ld (%ld%%)\n",
+ str, total / 1000000, total % 1000000,
+ all_time == 0 ? 0
+ : (long) (((100.0 * (double) total) / (double) all_time) + .5));
+}
+
diff --git a/gcc/timevar.def b/gcc/timevar.def
new file mode 100644
index 00000000000..865d074df6a
--- /dev/null
+++ b/gcc/timevar.def
@@ -0,0 +1,73 @@
+/* This file contains the definitions for timing variables used to
+ measure run-time performance of the compiler.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Alex Samuel <samuel@codesourcery.com>
+
+ This file is part of GNU CC.
+
+ GNU CC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This file contains timing variable definitions, used by timevar.h
+ and timevar.c.
+
+ Syntax:
+
+ DEFTIMEVAR (id, name)
+
+ where ID is the enumeral value used to identify the timing
+ variable, and NAME is a character string describing its purpose. */
+
+/* The total execution time. */
+DEFTIMEVAR (TV_TOTAL , "total time")
+
+/* Time spent garbage-collecting. */
+DEFTIMEVAR (TV_GC , "garbage collection")
+
+/* Time spent generating dump files. */
+DEFTIMEVAR (TV_DUMP , "dump files")
+
+/* Timing in various stages of the compiler. */
+DEFTIMEVAR (TV_PARSE , "parser")
+DEFTIMEVAR (TV_VARCONST , "varconst")
+DEFTIMEVAR (TV_INTEGRATION , "integration")
+DEFTIMEVAR (TV_JUMP , "jump")
+DEFTIMEVAR (TV_CSE , "CSE")
+DEFTIMEVAR (TV_GCSE , "global CSE")
+DEFTIMEVAR (TV_LOOP , "loop analysis")
+DEFTIMEVAR (TV_CSE2 , "CSE 2")
+DEFTIMEVAR (TV_BRANCH_PROB , "branch prediction")
+DEFTIMEVAR (TV_FLOW , "flow analysis")
+DEFTIMEVAR (TV_COMBINE , "combiner")
+DEFTIMEVAR (TV_REGMOVE , "regmove")
+DEFTIMEVAR (TV_SCHED , "scheduling")
+DEFTIMEVAR (TV_LOCAL_ALLOC , "local alloc")
+DEFTIMEVAR (TV_GLOBAL_ALLOC , "global alloc")
+DEFTIMEVAR (TV_RELOAD_CSE_REGS , "reload CSE regs")
+DEFTIMEVAR (TV_FLOW2 , "flow 2")
+DEFTIMEVAR (TV_PEEPHOLE2 , "peephole 2")
+DEFTIMEVAR (TV_SCHED2 , "schedulding 2")
+DEFTIMEVAR (TV_DBR_SCHED , "delay branch sched")
+DEFTIMEVAR (TV_REORDER_BLOCKS , "reorder blocks")
+DEFTIMEVAR (TV_RENAME_REGISTERS , "rename registers")
+DEFTIMEVAR (TV_SHORTEN_BRANCH , "shorten branches")
+DEFTIMEVAR (TV_REG_STACK , "reg stack")
+DEFTIMEVAR (TV_TO_SSA , "convert to SSA")
+DEFTIMEVAR (TV_FROM_SSA , "convert from SSA")
+DEFTIMEVAR (TV_FINAL , "final")
+DEFTIMEVAR (TV_SYMOUT , "symout")
+
+/* Everything else in rest_of_compilation not included above. */
+DEFTIMEVAR (TV_REST_OF_COMPILATION , "rest of compilation")
diff --git a/gcc/timevar.h b/gcc/timevar.h
new file mode 100644
index 00000000000..c7fcfa70456
--- /dev/null
+++ b/gcc/timevar.h
@@ -0,0 +1,86 @@
+/* Timing variables for measuring compiler performance.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Alex Samuel <samuel@codesourcery.com>
+
+ This file is part of GNU CC.
+
+ GNU CC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Timing variables are used to measure elapsed time in various
+ portions of the compiler. Each measures elapsed user, system, and
+ wall-clock time, as appropriate to and supported by the host
+ system.
+
+ Timing variables are defined using the DEFTIMEVAR macro in
+ timevar.def. Each has an enumeral identifier, used when referring
+ to the timing variable in code, and a character string name.
+
+ Timing variables can be used in two ways:
+
+ - On the timing stack, using timevar_push and timevar_pop.
+ Timing variables may be pushed onto the stack; elapsed time is
+ attributed to the topmost timing variable on the stack. When
+ another variable is pushed on, the previous topmost variable is
+ `paused' until the pushed variable is popped back off.
+
+ - As a standalone timer, using timevar_start and timevar_stop.
+ All time elapsed between the two calls is attributed to the
+ variable.
+*/
+
+/* This structure stores the various varieties of time that can be
+ measured. Times are stored in microseconds. The time may be an
+ absolute time or a time difference; in the former case, the time
+ base is undefined, except that the difference between two times
+ produces a valid time difference. */
+
+struct timevar_time_def
+{
+ /* User time in this process. */
+ long user;
+
+ /* System time (if applicable for this host platform) in this
+ process. */
+ long sys;
+
+ /* Wall clock time. */
+ long wall;
+};
+
+/* An enumeration of timing variable indentifiers. Constructed from
+ the contents of timevar.def. */
+
+#define DEFTIMEVAR(identifier__, name__) \
+ identifier__,
+typedef enum
+{
+#include "timevar.def"
+ TIMEVAR_LAST
+}
+timevar_id_t;
+#undef DEFTIMEVAR
+
+extern void init_timevar PARAMS ((void));
+extern void timevar_push PARAMS ((timevar_id_t));
+extern void timevar_pop PARAMS ((timevar_id_t));
+extern void timevar_start PARAMS ((timevar_id_t));
+extern void timevar_stop PARAMS ((timevar_id_t));
+extern void timevar_get PARAMS ((timevar_id_t, struct timevar_time_def *));
+extern void timevar_print PARAMS ((FILE *));
+
+/* Provided for backward compatibility. */
+extern long get_run_time PARAMS ((void));
+extern void print_time PARAMS ((const char *, long));
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 65f7ee807c4..e175a40c6da 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -60,6 +60,7 @@ Boston, MA 02111-1307, USA. */
#include "graph.h"
#include "loop.h"
#include "regs.h"
+#include "timevar.h"
#ifndef ACCUMULATE_OUTGOING_ARGS
#define ACCUMULATE_OUTGOING_ARGS 0
@@ -1402,130 +1403,7 @@ read_integral_parameter (p, pname, defval)
return atoi (p);
}
-
-/* Time accumulators, to count the total time spent in various passes.
- The first three are used in other files; the latter two only here. */
-
-long gc_time;
-long parse_time;
-long varconst_time;
-
-static long integration_time;
-static long jump_time;
-static long cse_time;
-static long gcse_time;
-static long loop_time;
-static long cse2_time;
-static long branch_prob_time;
-static long flow_time;
-static long combine_time;
-static long regmove_time;
-static long sched_time;
-static long local_alloc_time;
-static long global_alloc_time;
-static long flow2_time;
-static long peephole2_time;
-static long sched2_time;
-static long dbr_sched_time;
-static long reorder_blocks_time;
-static long rename_registers_time;
-static long shorten_branch_time;
-static long stack_reg_time;
-static long to_ssa_time;
-static long from_ssa_time;
-static long final_time;
-static long symout_time;
-static long dump_time;
-static long all_time;
-/* Return time used so far, in microseconds. */
-
-long
-get_run_time ()
-{
- if (quiet_flag)
- return 0;
-
-#ifdef __BEOS__
- return 0;
-#else /* not BeOS */
-#if defined (_WIN32) && !defined (__CYGWIN__)
- if (clock() < 0)
- return 0;
- else
- return (clock() * 1000);
-#else /* not _WIN32 */
-#ifdef _SC_CLK_TCK
- {
- static int tick;
- struct tms tms;
- if (tick == 0)
- tick = 1000000 / sysconf(_SC_CLK_TCK);
- times (&tms);
- return (tms.tms_utime + tms.tms_stime) * tick;
- }
-#else
-#ifdef USG
- {
- struct tms tms;
-# if HAVE_SYSCONF && defined _SC_CLK_TCK
-# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
-# else
-# ifdef CLK_TCK
-# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
-# else
-# define TICKS_PER_SECOND HZ /* traditional UNIX */
-# endif
-# endif
- times (&tms);
- return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
- }
-#else
-#ifndef VMS
- {
- struct rusage rusage;
- getrusage (0, &rusage);
- return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
- + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
- }
-#else /* VMS */
- {
- struct
- {
- int proc_user_time;
- int proc_system_time;
- int child_user_time;
- int child_system_time;
- } vms_times;
- times ((void *) &vms_times);
- return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
- }
-#endif /* VMS */
-#endif /* USG */
-#endif /* _SC_CLK_TCK */
-#endif /* _WIN32 */
-#endif /* __BEOS__ */
-}
-
-#define TIMEVAR(VAR, BODY) \
-do { \
- long otime = get_run_time (); \
- BODY; \
- VAR += get_run_time () - otime; \
-} while (0)
-
-void
-print_time (str, total)
- const char *str;
- long total;
-{
- fprintf (stderr,
- "time in %s: %ld.%06ld (%ld%%)\n",
- str, total / 1000000, total % 1000000,
- all_time == 0 ? 0
- : (long) (((100.0 * (double) total) / (double) all_time) + .5));
-}
-
/* This is the default decl_printable_name function. */
static const char *
@@ -1824,44 +1702,42 @@ open_dump_file (index, decl)
if (! dump_file[index].enabled)
return 0;
- TIMEVAR
- (dump_time,
- {
- if (rtl_dump_file != NULL)
- fclose (rtl_dump_file);
+ timevar_push (TV_DUMP);
+ if (rtl_dump_file != NULL)
+ fclose (rtl_dump_file);
- sprintf (seq, ".%02d.", index);
+ sprintf (seq, ".%02d.", index);
- if (! dump_file[index].initialized)
- {
- /* If we've not initialized the files, do so now. */
- if (graph_dump_format != no_graph
- && dump_file[index].graph_dump_p)
- {
- dump_name = concat (seq, dump_file[index].extension, NULL);
- clean_graph_dump_file (dump_base_name, dump_name);
- free (dump_name);
- }
- dump_file[index].initialized = 1;
- open_arg = "w";
- }
- else
- open_arg = "a";
+ if (! dump_file[index].initialized)
+ {
+ /* If we've not initialized the files, do so now. */
+ if (graph_dump_format != no_graph
+ && dump_file[index].graph_dump_p)
+ {
+ dump_name = concat (seq, dump_file[index].extension, NULL);
+ clean_graph_dump_file (dump_base_name, dump_name);
+ free (dump_name);
+ }
+ dump_file[index].initialized = 1;
+ open_arg = "w";
+ }
+ else
+ open_arg = "a";
- dump_name = concat (dump_base_name, seq,
- dump_file[index].extension, NULL);
+ dump_name = concat (dump_base_name, seq,
+ dump_file[index].extension, NULL);
- rtl_dump_file = fopen (dump_name, open_arg);
- if (rtl_dump_file == NULL)
- pfatal_with_name (dump_name);
+ rtl_dump_file = fopen (dump_name, open_arg);
+ if (rtl_dump_file == NULL)
+ pfatal_with_name (dump_name);
- free (dump_name);
+ free (dump_name);
- if (decl)
- fprintf (rtl_dump_file, "\n;; Function %s\n\n",
- decl_printable_name (decl, 2));
- });
-
+ if (decl)
+ fprintf (rtl_dump_file, "\n;; Function %s\n\n",
+ decl_printable_name (decl, 2));
+
+ timevar_pop (TV_DUMP);
return 1;
}
@@ -1876,30 +1752,28 @@ close_dump_file (index, func, insns)
if (! rtl_dump_file)
return;
- TIMEVAR
- (dump_time,
- {
- if (insns
- && graph_dump_format != no_graph
- && dump_file[index].graph_dump_p)
- {
- char seq[16];
- char *suffix;
+ timevar_push (TV_DUMP);
+ if (insns
+ && graph_dump_format != no_graph
+ && dump_file[index].graph_dump_p)
+ {
+ char seq[16];
+ char *suffix;
- sprintf (seq, ".%02d.", index);
- suffix = concat (seq, dump_file[index].extension, NULL);
- print_rtl_graph_with_bb (dump_base_name, suffix, insns);
- free (suffix);
- }
+ sprintf (seq, ".%02d.", index);
+ suffix = concat (seq, dump_file[index].extension, NULL);
+ print_rtl_graph_with_bb (dump_base_name, suffix, insns);
+ free (suffix);
+ }
- if (func && insns)
- func (rtl_dump_file, insns);
+ if (func && insns)
+ func (rtl_dump_file, insns);
- fflush (rtl_dump_file);
- fclose (rtl_dump_file);
+ fflush (rtl_dump_file);
+ fclose (rtl_dump_file);
- rtl_dump_file = NULL;
- });
+ rtl_dump_file = NULL;
+ timevar_pop (TV_DUMP);
}
/* Do any final processing required for the declarations in VEC, of
@@ -2060,6 +1934,7 @@ check_global_declarations (vec, len)
&& ! TREE_USED (DECL_NAME (decl)))
warning_with_decl (decl, "`%s' defined but not used");
+ timevar_push (TV_SYMOUT);
#ifdef SDB_DEBUGGING_INFO
/* The COFF linker can move initialized global vars to the end.
And that can screw up the symbol ordering.
@@ -2069,7 +1944,7 @@ check_global_declarations (vec, len)
&& TREE_PUBLIC (decl) && DECL_INITIAL (decl)
&& ! DECL_EXTERNAL (decl)
&& DECL_RTL (decl) != 0)
- TIMEVAR (symout_time, sdbout_symbol (decl, 0));
+ sdbout_symbol (decl, 0);
/* Output COFF information for non-global
file-scope initialized variables. */
@@ -2079,7 +1954,7 @@ check_global_declarations (vec, len)
&& ! DECL_EXTERNAL (decl)
&& DECL_RTL (decl) != 0
&& GET_CODE (DECL_RTL (decl)) == MEM)
- TIMEVAR (symout_time, sdbout_toplevel_data (decl));
+ sdbout_toplevel_data (decl);
#endif /* SDB_DEBUGGING_INFO */
#ifdef DWARF_DEBUGGING_INFO
/* Output DWARF information for file-scope tentative data object
@@ -2089,7 +1964,7 @@ check_global_declarations (vec, len)
if (write_symbols == DWARF_DEBUG
&& (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
- TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
+ dwarfout_file_scope_decl (decl, 1);
#endif
#ifdef DWARF2_DEBUGGING_INFO
/* Output DWARF2 information for file-scope tentative data object
@@ -2099,8 +1974,9 @@ check_global_declarations (vec, len)
if (write_symbols == DWARF2_DEBUG
&& (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
- TIMEVAR (symout_time, dwarf2out_decl (decl));
+ dwarf2out_decl (decl);
#endif
+ timevar_pop (TV_SYMOUT);
}
}
@@ -2158,42 +2034,17 @@ compile_file (name)
char *name;
{
tree globals;
- int start_time;
int name_specified = name != 0;
if (dump_base_name == 0)
dump_base_name = name ? name : "gccdump";
- parse_time = 0;
- varconst_time = 0;
- integration_time = 0;
- jump_time = 0;
- cse_time = 0;
- gcse_time = 0;
- loop_time = 0;
- cse2_time = 0;
- branch_prob_time = 0;
- flow_time = 0;
- combine_time = 0;
- regmove_time = 0;
- sched_time = 0;
- local_alloc_time = 0;
- global_alloc_time = 0;
- flow2_time = 0;
- peephole2_time = 0;
- sched2_time = 0;
- dbr_sched_time = 0;
- reorder_blocks_time = 0;
- rename_registers_time = 0;
- shorten_branch_time = 0;
- stack_reg_time = 0;
- to_ssa_time = 0;
- from_ssa_time = 0;
- final_time = 0;
- symout_time = 0;
- dump_time = 0;
+ /* Start timing total execution time. */
+ init_timevar ();
+ timevar_start (TV_TOTAL);
+
/* Initialize data in various passes. */
init_obstacks ();
@@ -2365,19 +2216,18 @@ compile_file (name)
/* If dbx symbol table desired, initialize writing it
and output the predefined types. */
+ timevar_push (TV_SYMOUT);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
- getdecls ()));
+ dbxout_init (asm_out_file, main_input_filename, getdecls ());
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
- TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
- getdecls ()));
+ sdbout_init (asm_out_file, main_input_filename, getdecls ());
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
- TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
+ dwarfout_init (asm_out_file, main_input_filename);
#endif
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_frame ())
@@ -2385,15 +2235,16 @@ compile_file (name)
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
- TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
+ dwarf2out_init (asm_out_file, main_input_filename);
#endif
+ timevar_pop (TV_SYMOUT);
/* Initialize yet another pass. */
init_final (main_input_filename);
init_branch_prob (dump_base_name);
- start_time = get_run_time ();
+ timevar_push (TV_PARSE);
/* Call the parser, which parses the entire file
(calling rest_of_compilation for each function). */
@@ -2412,10 +2263,7 @@ compile_file (name)
/* Compilation is now finished except for writing
what's left of the symbol table output. */
- parse_time += get_run_time () - start_time;
-
- parse_time -= integration_time;
- parse_time -= varconst_time;
+ timevar_pop (TV_PARSE);
if (flag_syntax_only)
goto finish_syntax;
@@ -2465,20 +2313,15 @@ compile_file (name)
weak_finish ();
/* Do dbx symbols */
+ timevar_push (TV_SYMOUT);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- TIMEVAR (symout_time,
- {
- dbxout_finish (asm_out_file, main_input_filename);
- });
+ dbxout_finish (asm_out_file, main_input_filename);
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
- TIMEVAR (symout_time,
- {
- dwarfout_finish ();
- });
+ dwarfout_finish ();
#endif
#ifdef DWARF2_UNWIND_INFO
@@ -2488,11 +2331,9 @@ compile_file (name)
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
- TIMEVAR (symout_time,
- {
- dwarf2out_finish ();
- });
+ dwarf2out_finish ();
#endif
+ timevar_pop (TV_SYMOUT);
/* Output some stuff at end of file if nec. */
@@ -2500,11 +2341,11 @@ compile_file (name)
if (flag_test_coverage || flag_branch_probabilities)
{
+ timevar_push (TV_DUMP);
open_dump_file (DFI_bp, NULL);
-
- TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
-
+ end_branch_prob (rtl_dump_file);
close_dump_file (DFI_bp, NULL, NULL_RTX);
+ timevar_pop (TV_DUMP);
}
#ifdef ASM_FILE_END
@@ -2526,8 +2367,10 @@ compile_file (name)
if (optimize > 0 && open_dump_file (DFI_combine, NULL))
{
- TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
+ timevar_push (TV_DUMP);
+ dump_combine_total_stats (rtl_dump_file);
close_dump_file (DFI_combine, NULL, NULL_RTX);
+ timevar_pop (TV_DUMP);
}
/* Close non-debugging input and output files. Take special care to note
@@ -2561,55 +2404,13 @@ compile_file (name)
/* Free up memory for the benefit of leak detectors. */
free_reg_info ();
+ /* Stop timing total execution time. */
+ timevar_stop (TV_TOTAL);
+
/* Print the times. */
if (! quiet_flag)
- {
- all_time = get_run_time ();
-
- fprintf (stderr,"\n");
-
- print_time ("parse", parse_time);
- print_time ("integration", integration_time);
- print_time ("jump", jump_time);
- print_time ("cse", cse_time);
- print_time ("to ssa", to_ssa_time);
- print_time ("from ssa", from_ssa_time);
- print_time ("gcse", gcse_time);
- print_time ("loop", loop_time);
- print_time ("cse2", cse2_time);
- print_time ("branch-prob", branch_prob_time);
- print_time ("flow", flow_time);
- print_time ("combine", combine_time);
- print_time ("regmove", regmove_time);
-#ifdef INSN_SCHEDULING
- print_time ("sched", sched_time);
-#endif
- print_time ("local-alloc", local_alloc_time);
- print_time ("global-alloc", global_alloc_time);
- print_time ("flow2", flow2_time);
-#ifdef HAVE_peephole2
- print_time ("peephole2", peephole2_time);
-#endif
-#ifdef INSN_SCHEDULING
- print_time ("sched2", sched2_time);
-#endif
-#ifdef DELAY_SLOTS
- print_time ("dbranch", dbr_sched_time);
-#endif
- print_time ("bbro", reorder_blocks_time);
- print_time ("rnreg", rename_registers_time);
- print_time ("shorten-branch", shorten_branch_time);
-#ifdef STACK_REGS
- print_time ("stack-reg", stack_reg_time);
-#endif
- print_time ("final", final_time);
- print_time ("varconst", varconst_time);
- print_time ("symout", symout_time);
- print_time ("dump", dump_time);
- if (ggc_p)
- print_time ("gc", gc_time);
- }
+ timevar_print (stderr);
}
/* This is called from various places for FUNCTION_DECL, VAR_DECL,
@@ -2644,29 +2445,30 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
but we need to treat them as if they were. */
if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|| TREE_CODE (decl) == FUNCTION_DECL)
- TIMEVAR (varconst_time,
- {
- make_decl_rtl (decl, asmspec, top_level);
- /* Initialized extern variable exists to be replaced
- with its value, or represents something that will be
- output in another file. */
- if (! (TREE_CODE (decl) == VAR_DECL
- && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
- && DECL_INITIAL (decl) != 0
- && DECL_INITIAL (decl) != error_mark_node))
- /* Don't output anything
- when a tentative file-scope definition is seen.
- But at end of compilation, do output code for them. */
- if (! (! at_end && top_level
- && (DECL_INITIAL (decl) == 0
- || DECL_INITIAL (decl) == error_mark_node)))
- assemble_variable (decl, top_level, at_end, 0);
- if (decl == last_assemble_variable_decl)
- {
- ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
- top_level, at_end);
- }
- });
+ {
+ timevar_push (TV_VARCONST);
+ make_decl_rtl (decl, asmspec, top_level);
+ /* Initialized extern variable exists to be replaced
+ with its value, or represents something that will be
+ output in another file. */
+ if (! (TREE_CODE (decl) == VAR_DECL
+ && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
+ && DECL_INITIAL (decl) != 0
+ && DECL_INITIAL (decl) != error_mark_node))
+ /* Don't output anything
+ when a tentative file-scope definition is seen.
+ But at end of compilation, do output code for them. */
+ if (! (! at_end && top_level
+ && (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node)))
+ assemble_variable (decl, top_level, at_end, 0);
+ if (decl == last_assemble_variable_decl)
+ {
+ ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
+ top_level, at_end);
+ }
+ timevar_pop (TV_VARCONST);
+ }
else if (DECL_REGISTER (decl) && asmspec != 0)
{
if (decode_reg_name (asmspec) >= 0)
@@ -2680,12 +2482,20 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
&& TREE_CODE (decl) == TYPE_DECL)
- TIMEVAR (symout_time, dbxout_symbol (decl, 0));
+ {
+ timevar_push (TV_SYMOUT);
+ dbxout_symbol (decl, 0);
+ timevar_pop (TV_SYMOUT);
+ }
#endif
#ifdef SDB_DEBUGGING_INFO
else if (write_symbols == SDB_DEBUG && top_level
&& TREE_CODE (decl) == TYPE_DECL)
- TIMEVAR (symout_time, sdbout_symbol (decl, 0));
+ {
+ timevar_push (TV_SYMOUT);
+ sdbout_symbol (decl, 0);
+ timevar_pop (TV_SYMOUT);
+ }
#endif
}
@@ -2701,14 +2511,16 @@ rest_of_type_compilation (type, toplev)
int toplev ATTRIBUTE_UNUSED;
#endif
{
+ timevar_push (TV_SYMOUT);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
+ dbxout_symbol (TYPE_STUB_DECL (type), !toplev);
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
- TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
+ symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev);
#endif
+ timevar_pop (TV_SYMOUT);
}
/* DECL is an inline function, whose body is present, but which is not
@@ -2758,11 +2570,12 @@ rest_of_compilation (decl)
tree decl;
{
register rtx insns;
- int start_time = get_run_time ();
int tem;
int failure = 0;
int rebuild_label_notes_after_reload;
+ timevar_push (TV_REST_OF_COMPILATION);
+
/* When processing delayed functions, prepare_function_start() won't
have been run to re-initialize it. */
cse_not_expected = ! optimize;
@@ -2807,30 +2620,31 @@ rest_of_compilation (decl)
/* If requested, consider whether to make this function inline. */
if (DECL_INLINE (decl) || flag_inline_functions)
- TIMEVAR (integration_time,
- {
- lose = function_cannot_inline_p (decl);
- if (lose || ! optimize)
- {
- if (warn_inline && DECL_INLINE (decl))
- warning_with_decl (decl, lose);
- DECL_ABSTRACT_ORIGIN (decl) = 0;
- /* Don't really compile an extern inline function.
- If we can't make it inline, pretend
- it was only declared. */
- if (DECL_EXTERNAL (decl))
- {
- DECL_INITIAL (decl) = 0;
- goto exit_rest_of_compilation;
- }
- }
- else
- /* ??? Note that this has the effect of making it look
- like "inline" was specified for a function if we choose
- to inline it. This isn't quite right, but it's
- probably not worth the trouble to fix. */
- inlinable = DECL_INLINE (decl) = 1;
- });
+ {
+ timevar_push (TV_INTEGRATION);
+ lose = function_cannot_inline_p (decl);
+ timevar_pop (TV_INTEGRATION);
+ if (lose || ! optimize)
+ {
+ if (warn_inline && DECL_INLINE (decl))
+ warning_with_decl (decl, lose);
+ DECL_ABSTRACT_ORIGIN (decl) = 0;
+ /* Don't really compile an extern inline function.
+ If we can't make it inline, pretend
+ it was only declared. */
+ if (DECL_EXTERNAL (decl))
+ {
+ DECL_INITIAL (decl) = 0;
+ goto exit_rest_of_compilation;
+ }
+ }
+ else
+ /* ??? Note that this has the effect of making it look
+ like "inline" was specified for a function if we choose
+ to inline it. This isn't quite right, but it's
+ probably not worth the trouble to fix. */
+ inlinable = DECL_INLINE (decl) = 1;
+ }
insns = get_insns ();
@@ -2883,7 +2697,9 @@ rest_of_compilation (decl)
TREE_NOTHROW (current_function_decl) = 1;
note_deferral_of_defined_inline_function (decl);
- TIMEVAR (integration_time, save_for_inline_nocopy (decl));
+ timevar_push (TV_INTEGRATION);
+ save_for_inline_nocopy (decl);
+ timevar_pop (TV_INTEGRATION);
DECL_SAVED_INSNS (decl)->inlinable = inlinable;
goto exit_rest_of_compilation;
}
@@ -2922,13 +2738,15 @@ rest_of_compilation (decl)
(of possibly multiple) methods of performing the call. */
if (flag_optimize_sibling_calls)
{
+ timevar_push (TV_JUMP);
open_dump_file (DFI_sibling, decl);
- TIMEVAR (jump_time, optimize_sibling_and_tail_recursive_calls ());
+ optimize_sibling_and_tail_recursive_calls ();
close_dump_file (DFI_sibling, print_rtl, get_insns ());
+ timevar_pop (TV_JUMP);
}
-
+
#ifdef FINALIZE_PIC
/* If we are doing position-independent code generation, now
is the time to output special prologues and epilogues.
@@ -2969,16 +2787,17 @@ rest_of_compilation (decl)
/* Always do one jump optimization pass to ensure that JUMP_LABEL fields
are initialized and to compute whether control can drop off the end
of the function. */
- TIMEVAR (jump_time,
- {
- /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this
- before jump optimization switches branch directions. */
- expected_value_to_br_prob ();
- reg_scan (insns, max_reg_num (), 0);
- jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
- JUMP_AFTER_REGSCAN);
- });
+ timevar_push (TV_JUMP);
+ /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this
+ before jump optimization switches branch directions. */
+ expected_value_to_br_prob ();
+
+ reg_scan (insns, max_reg_num (), 0);
+ jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+ JUMP_AFTER_REGSCAN);
+
+ timevar_pop (TV_JUMP);
/* Now is when we stop if -fsyntax-only and -Wreturn-type. */
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
@@ -2987,23 +2806,22 @@ rest_of_compilation (decl)
goto exit_rest_of_compilation;
}
- TIMEVAR (jump_time,
- {
- /* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks)
- {
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (insns);
- delete_null_pointer_checks (insns);
- }
-
- /* Jump optimization, and the removal of NULL pointer checks,
- may have reduced the number of instructions substantially.
- CSE, and future passes, allocate arrays whose dimensions
- involve the maximum instruction UID, so if we can reduce
- the maximum UID we'll save big on memory. */
- renumber_insns (rtl_dump_file);
- });
+ timevar_push (TV_JUMP);
+ /* Try to identify useless null pointer tests and delete them. */
+ if (flag_delete_null_pointer_checks)
+ {
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (insns);
+ delete_null_pointer_checks (insns);
+ }
+
+ /* Jump optimization, and the removal of NULL pointer checks, may
+ have reduced the number of instructions substantially. CSE, and
+ future passes, allocate arrays whose dimensions involve the
+ maximum instruction UID, so if we can reduce the maximum UID
+ we'll save big on memory. */
+ renumber_insns (rtl_dump_file);
+ timevar_pop (TV_JUMP);
close_dump_file (DFI_jump, print_rtl, insns);
@@ -3018,41 +2836,52 @@ rest_of_compilation (decl)
if (optimize > 0)
{
open_dump_file (DFI_cse, decl);
+ timevar_push (TV_CSE);
- TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
+ reg_scan (insns, max_reg_num (), 1);
if (flag_thread_jumps)
- TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
+ {
+ timevar_push (TV_JUMP);
+ thread_jumps (insns, max_reg_num (), 1);
+ timevar_pop (TV_JUMP);
+ }
- TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
- 0, rtl_dump_file));
+ tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
/* If we are not running the second CSE pass, then we are no longer
expecting CSE to be run. */
cse_not_expected = !flag_rerun_cse_after_loop;
if (tem || optimize > 1)
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
+ {
+ timevar_push (TV_JUMP);
+ jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+ !JUMP_AFTER_REGSCAN);
+ timevar_pop (TV_JUMP);
+ }
/* Run this after jump optmizations remove all the unreachable code
so that unreachable code will not keep values live. */
- TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
+ delete_trivially_dead_insns (insns, max_reg_num ());
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
- TIMEVAR (jump_time,
- {
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (insns);
- delete_null_pointer_checks (insns);
- });
+ {
+ timevar_push (TV_JUMP);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+
+ cleanup_cfg (insns);
+
+ delete_null_pointer_checks (insns);
+ timevar_pop (TV_JUMP);
+ }
/* The second pass of jump optimization is likely to have
removed a bunch more instructions. */
renumber_insns (rtl_dump_file);
+ timevar_pop (TV_CSE);
close_dump_file (DFI_cse, print_rtl, insns);
}
@@ -3068,33 +2897,35 @@ rest_of_compilation (decl)
if (optimize > 0 && flag_ssa)
{
+ /* Convert to SSA form. */
+
+ timevar_push (TV_TO_SSA);
open_dump_file (DFI_ssa, decl);
- TIMEVAR (to_ssa_time,
- {
- find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
- cleanup_cfg (insns);
- convert_to_ssa ();
- });
+ find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
+ cleanup_cfg (insns);
+ convert_to_ssa ();
close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
+ timevar_pop (TV_TO_SSA);
- open_dump_file (DFI_ussa, decl);
+ /* Currently, there's nothing to do in SSA form. */
- TIMEVAR (from_ssa_time,
- {
- convert_from_ssa ();
+ /* Convert from SSA form. */
- /* New registers have been created. Rescan their usage. */
- reg_scan (insns, max_reg_num (), 1);
+ timevar_push (TV_FROM_SSA);
+ open_dump_file (DFI_ussa, decl);
- /* Life analysis used in SSA adds log_links but these
- shouldn't be there until the flow stage, so clear
- them away. */
- clear_log_links (insns);
- });
+ convert_from_ssa ();
+ /* New registers have been created. Rescan their usage. */
+ reg_scan (insns, max_reg_num (), 1);
+ /* Life analysis used in SSA adds log_links but these
+ shouldn't be there until the flow stage, so clear
+ them away. */
+ clear_log_links (insns);
close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
+ timevar_pop (TV_FROM_SSA);
if (ggc_p)
ggc_collect ();
@@ -3104,25 +2935,25 @@ rest_of_compilation (decl)
if (optimize > 0 && flag_gcse)
{
+ timevar_push (TV_GCSE);
open_dump_file (DFI_gcse, decl);
- TIMEVAR (gcse_time,
- {
- find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
- cleanup_cfg (insns);
- tem = gcse_main (insns, rtl_dump_file);
- });
+ find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
+ cleanup_cfg (insns);
+ tem = gcse_main (insns, rtl_dump_file);
/* If gcse altered any jumps, rerun jump optimizations to clean
things up. */
if (tem)
{
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
+ timevar_push (TV_JUMP);
+ jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+ !JUMP_AFTER_REGSCAN);
+ timevar_pop (TV_JUMP);
}
close_dump_file (DFI_gcse, print_rtl, insns);
+ timevar_pop (TV_GCSE);
if (ggc_p)
ggc_collect ();
@@ -3132,31 +2963,29 @@ rest_of_compilation (decl)
if (optimize > 0)
{
+ timevar_push (TV_LOOP);
open_dump_file (DFI_loop, decl);
-
- TIMEVAR
- (loop_time,
- {
- if (flag_rerun_loop_opt)
- {
- /* We only want to perform unrolling once. */
+
+ if (flag_rerun_loop_opt)
+ {
+ /* We only want to perform unrolling once. */
- loop_optimize (insns, rtl_dump_file, 0, 0);
+ loop_optimize (insns, rtl_dump_file, 0, 0);
- /* The first call to loop_optimize makes some instructions
- trivially dead. We delete those instructions now in the
- hope that doing so will make the heuristics in loop work
- better and possibly speed up compilation. */
- delete_trivially_dead_insns (insns, max_reg_num ());
+ /* The first call to loop_optimize makes some instructions
+ trivially dead. We delete those instructions now in the
+ hope that doing so will make the heuristics in loop work
+ better and possibly speed up compilation. */
+ delete_trivially_dead_insns (insns, max_reg_num ());
- /* The regscan pass is currently necessary as the alias
+ /* The regscan pass is currently necessary as the alias
analysis code depends on this information. */
- reg_scan (insns, max_reg_num (), 1);
- }
- loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
- });
+ reg_scan (insns, max_reg_num (), 1);
+ }
+ loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
close_dump_file (DFI_loop, print_rtl, insns);
+ timevar_pop (TV_LOOP);
if (ggc_p)
ggc_collect ();
@@ -3169,6 +2998,7 @@ rest_of_compilation (decl)
if (optimize > 0)
{
+ timevar_push (TV_CSE2);
open_dump_file (DFI_cse2, decl);
if (flag_rerun_cse_after_loop)
@@ -3178,38 +3008,36 @@ rest_of_compilation (decl)
the second CSE pass to do a better job. Jump_optimize can change
max_reg_num so we must rerun reg_scan afterwards.
??? Rework to not call reg_scan so often. */
- TIMEVAR (jump_time,
- {
- reg_scan (insns, max_reg_num (), 0);
- jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
- });
+ timevar_push (TV_JUMP);
+ reg_scan (insns, max_reg_num (), 0);
+ jump_optimize (insns, !JUMP_CROSS_JUMP,
+ !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
+ timevar_pop (TV_JUMP);
- TIMEVAR (cse2_time,
- {
- reg_scan (insns, max_reg_num (), 0);
- tem = cse_main (insns, max_reg_num (),
- 1, rtl_dump_file);
- });
+ reg_scan (insns, max_reg_num (), 0);
+ tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
if (tem)
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
+ {
+ timevar_push (TV_JUMP);
+ jump_optimize (insns, !JUMP_CROSS_JUMP,
+ !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
+ timevar_pop (TV_JUMP);
+ }
}
if (flag_thread_jumps)
{
/* This pass of jump threading straightens out code
that was kinked by loop optimization. */
- TIMEVAR (jump_time,
- {
- reg_scan (insns, max_reg_num (), 0);
- thread_jumps (insns, max_reg_num (), 0);
- });
+ timevar_push (TV_JUMP);
+ reg_scan (insns, max_reg_num (), 0);
+ thread_jumps (insns, max_reg_num (), 0);
+ timevar_pop (TV_JUMP);
}
close_dump_file (DFI_cse2, print_rtl, insns);
+ timevar_pop (TV_CSE2);
if (ggc_p)
ggc_collect ();
@@ -3217,14 +3045,13 @@ rest_of_compilation (decl)
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
+ timevar_push (TV_BRANCH_PROB);
open_dump_file (DFI_bp, decl);
- TIMEVAR (branch_prob_time,
- {
- branch_prob (insns, rtl_dump_file);
- });
+ branch_prob (insns, rtl_dump_file);
close_dump_file (DFI_bp, print_rtl, insns);
+ timevar_pop (TV_BRANCH_PROB);
if (ggc_p)
ggc_collect ();
@@ -3240,31 +3067,29 @@ rest_of_compilation (decl)
/* Do control and data flow analysis; wrote some of the results to
the dump file. */
- TIMEVAR
- (flow_time,
- {
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (insns);
- if (optimize)
- {
- struct loops loops;
+ timevar_push (TV_FLOW);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (insns);
+ if (optimize)
+ {
+ struct loops loops;
- /* Discover and record the loop depth at the head of each basic
- block. The loop infrastructure does the real job for us. */
- flow_loops_find (&loops);
+ /* Discover and record the loop depth at the head of each basic
+ block. The loop infrastructure does the real job for us. */
+ flow_loops_find (&loops);
- /* Estimate using heuristics if no profiling info is available. */
- if (! flag_branch_probabilities)
- estimate_probability (&loops);
+ /* Estimate using heuristics if no profiling info is available. */
+ if (! flag_branch_probabilities)
+ estimate_probability (&loops);
- if (rtl_dump_file)
- flow_loops_dump (&loops, rtl_dump_file, 0);
+ if (rtl_dump_file)
+ flow_loops_dump (&loops, rtl_dump_file, 0);
- flow_loops_free (&loops);
- }
- life_analysis (insns, rtl_dump_file, PROP_FINAL);
- mark_constant_function ();
- });
+ flow_loops_free (&loops);
+ }
+ life_analysis (insns, rtl_dump_file, PROP_FINAL);
+ mark_constant_function ();
+ timevar_pop (TV_FLOW);
if (warn_uninitialized || extra_warnings)
{
@@ -3288,23 +3113,24 @@ rest_of_compilation (decl)
{
int rebuild_jump_labels_after_combine = 0;
+ timevar_push (TV_COMBINE);
open_dump_file (DFI_combine, decl);
- TIMEVAR (combine_time,
- {
- rebuild_jump_labels_after_combine
- = combine_instructions (insns, max_reg_num ());
- });
+ rebuild_jump_labels_after_combine
+ = combine_instructions (insns, max_reg_num ());
/* Combining insns may have turned an indirect jump into a
direct jump. Rebuid the JUMP_LABEL fields of jumping
instructions. */
if (rebuild_jump_labels_after_combine)
{
- TIMEVAR (jump_time, rebuild_jump_labels (insns));
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (insns);
+ timevar_pop (TV_JUMP);
}
close_dump_file (DFI_combine, print_rtl_with_bb, insns);
+ timevar_pop (TV_COMBINE);
if (ggc_p)
ggc_collect ();
@@ -3314,12 +3140,13 @@ rest_of_compilation (decl)
necessary for two-address machines. */
if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
{
+ timevar_push (TV_REGMOVE);
open_dump_file (DFI_regmove, decl);
- TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
- rtl_dump_file));
+ regmove_optimize (insns, max_reg_num (), rtl_dump_file);
close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
+ timevar_pop (TV_REGMOVE);
if (ggc_p)
ggc_collect ();
@@ -3327,7 +3154,9 @@ rest_of_compilation (decl)
if (optimize && n_basic_blocks)
{
- TIMEVAR (gcse_time, optimize_mode_switching (NULL_PTR));
+ timevar_push (TV_GCSE);
+ optimize_mode_switching (NULL_PTR);
+ timevar_pop (TV_GCSE);
}
#ifdef INSN_SCHEDULING
@@ -3336,14 +3165,16 @@ rest_of_compilation (decl)
because doing the sched analysis makes some of the dump. */
if (optimize > 0 && flag_schedule_insns)
{
+ timevar_push (TV_SCHED);
open_dump_file (DFI_sched, decl);
/* Do control and data sched analysis,
and write some of the results to dump file. */
- TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
+ schedule_insns (rtl_dump_file);
close_dump_file (DFI_sched, print_rtl_with_bb, insns);
+ timevar_pop (TV_SCHED);
if (ggc_p)
ggc_collect ();
@@ -3355,6 +3186,7 @@ rest_of_compilation (decl)
epilogue thus changing register elimination offsets. */
current_function_is_leaf = leaf_function_p ();
+ timevar_push (TV_LOCAL_ALLOC);
open_dump_file (DFI_lreg, decl);
/* Allocate pseudo-regs that are used only within 1 basic block.
@@ -3362,45 +3194,44 @@ rest_of_compilation (decl)
RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
jump optimizer after register allocation and reloading are finished. */
- TIMEVAR (local_alloc_time,
- {
- /* We recomputed reg usage as part of updating the rest
- of life info during sched. */
- if (! flag_schedule_insns)
- recompute_reg_usage (insns, ! optimize_size);
- regclass (insns, max_reg_num (), rtl_dump_file);
- rebuild_label_notes_after_reload = local_alloc ();
- });
+ /* We recomputed reg usage as part of updating the rest
+ of life info during sched. */
+ if (! flag_schedule_insns)
+ recompute_reg_usage (insns, ! optimize_size);
+ regclass (insns, max_reg_num (), rtl_dump_file);
+ rebuild_label_notes_after_reload = local_alloc ();
+
+ timevar_pop (TV_LOCAL_ALLOC);
if (dump_file[DFI_lreg].enabled)
{
- TIMEVAR (dump_time,
- {
- dump_flow_info (rtl_dump_file);
- dump_local_alloc (rtl_dump_file);
- });
+ timevar_push (TV_DUMP);
+
+ dump_flow_info (rtl_dump_file);
+ dump_local_alloc (rtl_dump_file);
close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
}
if (ggc_p)
ggc_collect ();
+ timevar_push (TV_GLOBAL_ALLOC);
open_dump_file (DFI_greg, decl);
/* If optimizing, allocate remaining pseudo-regs. Do the reload
pass fixing up any insns that are invalid. */
- TIMEVAR (global_alloc_time,
- {
- if (optimize)
- failure = global_alloc (rtl_dump_file);
- else
- {
- build_insn_chain (insns);
- failure = reload (insns, 0, rtl_dump_file);
- }
- });
+ if (optimize)
+ failure = global_alloc (rtl_dump_file);
+ else
+ {
+ build_insn_chain (insns);
+ failure = reload (insns, 0, rtl_dump_file);
+ }
+
+ timevar_pop (TV_GLOBAL_ALLOC);
if (failure)
goto exit_rest_of_compilation;
@@ -3410,7 +3241,11 @@ rest_of_compilation (decl)
/* Do a very simple CSE pass over just the hard registers. */
if (optimize > 0)
- reload_cse_regs (insns);
+ {
+ timevar_push (TV_RELOAD_CSE_REGS);
+ reload_cse_regs (insns);
+ timevar_pop (TV_RELOAD_CSE_REGS);
+ }
/* If optimizing, then go ahead and split insns now since we are about
to recompute flow information anyway. */
@@ -3421,22 +3256,30 @@ rest_of_compilation (decl)
a direct jump. If so, we must rebuild the JUMP_LABEL fields of
jumping instructions. */
if (rebuild_label_notes_after_reload)
- TIMEVAR (jump_time, rebuild_jump_labels (insns));
+ {
+ timevar_push (TV_JUMP);
+
+ rebuild_jump_labels (insns);
+
+ timevar_pop (TV_JUMP);
+ }
if (dump_file[DFI_greg].enabled)
{
- TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
+ timevar_push (TV_DUMP);
+
+ dump_global_regs (rtl_dump_file);
+
close_dump_file (DFI_greg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
}
/* Re-create the death notes which were deleted during reload. */
+ timevar_push (TV_FLOW2);
open_dump_file (DFI_flow2, decl);
-
- TIMEVAR (flow2_time,
- {
- jump_optimize_minimal (insns);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- });
+
+ jump_optimize_minimal (insns);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
/* On some machines, the prologue and epilogue code, or parts thereof,
can be represented as RTL. Doing so lets us schedule insns between
@@ -3446,11 +3289,8 @@ rest_of_compilation (decl)
if (optimize)
{
- TIMEVAR (flow2_time,
- {
- cleanup_cfg (insns);
- life_analysis (insns, rtl_dump_file, PROP_FINAL);
- });
+ cleanup_cfg (insns);
+ life_analysis (insns, rtl_dump_file, PROP_FINAL);
/* This is kind of heruistics. We need to run combine_stack_adjustments
even for machines with possibly nonzero RETURN_POPS_ARGS
@@ -3459,7 +3299,7 @@ rest_of_compilation (decl)
#ifndef PUSH_ROUNDING
if (!ACCUMULATE_OUTGOING_ARGS)
#endif
- TIMEVAR (flow2_time, { combine_stack_adjustments (); });
+ combine_stack_adjustments ();
if (ggc_p)
ggc_collect ();
@@ -3468,29 +3308,34 @@ rest_of_compilation (decl)
flow2_completed = 1;
close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
+ timevar_pop (TV_FLOW2);
#ifdef HAVE_peephole2
if (optimize > 0 && flag_peephole2)
{
- open_dump_file (DFI_peephole2, decl);
+ timevar_push (TV_PEEPHOLE2);
- TIMEVAR (peephole2_time, peephole2_optimize (rtl_dump_file));
+ open_dump_file (DFI_peephole2, decl);
+ peephole2_optimize (rtl_dump_file);
close_dump_file (DFI_peephole2, print_rtl_with_bb, insns);
+ timevar_pop (TV_PEEPHOLE2);
}
#endif
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload)
{
+ timevar_push (TV_SCHED2);
open_dump_file (DFI_sched2, decl);
/* Do control and data sched analysis again,
and write some more of the results to dump file. */
- TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
+ schedule_insns (rtl_dump_file);
close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
+ timevar_pop (TV_SCHED2);
if (ggc_p)
ggc_collect ();
@@ -3504,20 +3349,24 @@ rest_of_compilation (decl)
if (optimize > 0 && flag_reorder_blocks)
{
+ timevar_push (TV_REORDER_BLOCKS);
open_dump_file (DFI_bbro, decl);
- TIMEVAR (reorder_blocks_time, reorder_basic_blocks ());
+ reorder_basic_blocks ();
close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
+ timevar_pop (TV_REORDER_BLOCKS);
}
if (optimize > 0 && flag_rename_registers)
{
+ timevar_push (TV_RENAME_REGISTERS);
open_dump_file (DFI_rnreg, decl);
- TIMEVAR (rename_registers_time, regrename_optimize ());
+ regrename_optimize ();
close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
+ timevar_pop (TV_RENAME_REGISTERS);
}
/* One more attempt to remove jumps to .+1 left by dead-store elimination.
@@ -3525,13 +3374,14 @@ rest_of_compilation (decl)
if (optimize > 0)
{
+ timevar_push (TV_JUMP);
open_dump_file (DFI_jump2, decl);
- TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
- JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
+ jump_optimize (insns, JUMP_CROSS_JUMP, JUMP_NOOP_MOVES,
+ !JUMP_AFTER_REGSCAN);
close_dump_file (DFI_jump2, print_rtl_with_bb, insns);
+ timevar_pop (TV_JUMP);
}
/* If a machine dependent reorganization is needed, call it. */
@@ -3552,15 +3402,13 @@ rest_of_compilation (decl)
#ifdef DELAY_SLOTS
if (optimize > 0 && flag_delayed_branch)
{
+ timevar_push (TV_DBR_SCHED);
open_dump_file (DFI_dbr, decl);
- TIMEVAR
- (dbr_sched_time,
- {
- dbr_schedule (insns, rtl_dump_file);
- });
+ dbr_schedule (insns, rtl_dump_file);
close_dump_file (DFI_dbr, print_rtl_with_bb, insns);
+ timevar_pop (TV_DBR_SCHED);
if (ggc_p)
ggc_collect ();
@@ -3571,14 +3419,18 @@ rest_of_compilation (decl)
Note this must run before reg-stack because of death note (ab)use
in the ia32 backend. */
- TIMEVAR (shorten_branch_time, shorten_branches (get_insns ()));
+ timevar_push (TV_SHORTEN_BRANCH);
+ shorten_branches (get_insns ());
+ timevar_pop (TV_SHORTEN_BRANCH);
#ifdef STACK_REGS
+ timevar_push (TV_REG_STACK);
open_dump_file (DFI_stack, decl);
- TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
+ reg_to_stack (insns, rtl_dump_file);
close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+ timevar_pop (TV_REG_STACK);
if (ggc_p)
ggc_collect ();
@@ -3592,37 +3444,38 @@ rest_of_compilation (decl)
/* Now turn the rtl into assembler code. */
- TIMEVAR (final_time,
- {
- rtx x;
- const char *fnname;
+ timevar_push (TV_FINAL);
+ {
+ rtx x;
+ const char *fnname;
- /* Get the function's name, as described by its RTL.
+ /* Get the function's name, as described by its RTL.
This may be different from the DECL_NAME name used
in the source file. */
- x = DECL_RTL (decl);
- if (GET_CODE (x) != MEM)
- abort ();
- x = XEXP (x, 0);
- if (GET_CODE (x) != SYMBOL_REF)
- abort ();
- fnname = XSTR (x, 0);
-
- assemble_start_function (decl, fnname);
- final_start_function (insns, asm_out_file, optimize);
- final (insns, asm_out_file, optimize, 0);
- final_end_function (insns, asm_out_file, optimize);
- assemble_end_function (decl, fnname);
- if (! quiet_flag)
- fflush (asm_out_file);
+ x = DECL_RTL (decl);
+ if (GET_CODE (x) != MEM)
+ abort ();
+ x = XEXP (x, 0);
+ if (GET_CODE (x) != SYMBOL_REF)
+ abort ();
+ fnname = XSTR (x, 0);
+
+ assemble_start_function (decl, fnname);
+ final_start_function (insns, asm_out_file, optimize);
+ final (insns, asm_out_file, optimize, 0);
+ final_end_function (insns, asm_out_file, optimize);
+ assemble_end_function (decl, fnname);
+ if (! quiet_flag)
+ fflush (asm_out_file);
/* Release all memory allocated by flow. */
- free_basic_block_vars (0);
+ free_basic_block_vars (0);
- /* Release all memory held by regsets now */
- regset_release_memory ();
- });
+ /* Release all memory held by regsets now */
+ regset_release_memory ();
+ }
+ timevar_pop (TV_FINAL);
if (ggc_p)
ggc_collect ();
@@ -3637,20 +3490,22 @@ rest_of_compilation (decl)
for those inline functions that need to have out-of-line copies
generated. During that call, we *will* be routed past here. */
+ timevar_push (TV_SYMOUT);
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
- TIMEVAR (symout_time, dbxout_function (decl));
+ dbxout_function (decl);
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
- TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
+ dwarfout_file_scope_decl (decl, 0);
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
- TIMEVAR (symout_time, dwarf2out_decl (decl));
+ dwarf2out_decl (decl);
#endif
+ timevar_pop (TV_SYMOUT);
exit_rest_of_compilation:
@@ -3666,24 +3521,25 @@ rest_of_compilation (decl)
flow2_completed = 0;
no_new_pseudos = 0;
- TIMEVAR (final_time,
- {
- /* Clear out the insn_length contents now that they are no
- longer valid. */
- init_insn_lengths ();
+ timevar_push (TV_FINAL);
+
+ /* Clear out the insn_length contents now that they are no
+ longer valid. */
+ init_insn_lengths ();
- /* Clear out the real_constant_chain before some of the rtx's
+ /* Clear out the real_constant_chain before some of the rtx's
it runs through become garbage. */
- clear_const_double_mem ();
+ clear_const_double_mem ();
- /* Cancel the effect of rtl_in_current_obstack. */
- resume_temporary_allocation ();
+ /* Cancel the effect of rtl_in_current_obstack. */
+ resume_temporary_allocation ();
- /* Show no temporary slots allocated. */
- init_temp_slots ();
+ /* Show no temporary slots allocated. */
+ init_temp_slots ();
- free_basic_block_vars (0);
- });
+ free_basic_block_vars (0);
+
+ timevar_pop (TV_FINAL);
/* Make sure volatile mem refs aren't considered valid operands for
arithmetic insns. We must call this here if this is a nested inline
@@ -3705,10 +3561,7 @@ rest_of_compilation (decl)
if (ggc_p)
ggc_collect ();
- /* The parsing time is all the time spent in yyparse
- *except* what is spent in this function. */
-
- parse_time -= get_run_time () - start_time;
+ timevar_pop (TV_REST_OF_COMPILATION);
}
static void
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 470b209610b..e5a06fff093 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -26,10 +26,6 @@ union tree_node;
struct rtx_def;
#endif
-extern long gc_time;
-extern long parse_time;
-extern long varconst_time;
-
extern int read_integral_parameter PARAMS ((const char *, const char *,
const int));
extern int count_error PARAMS ((int));