OSDN Git Service

2010-04-06 Kai Tietz <kai.tietz@onevision.com>
[pf3gnuchains/gcc-fork.git] / gcc / timevar.c
index 195040c..df671e4 100644 (file)
@@ -1,12 +1,12 @@
 /* Timing variables for measuring compiler performance.
 /* Timing variables for measuring compiler performance.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    Contributed by Alex Samuel <samuel@codesourcery.com>
 
 This file is part of GCC.
 
 GCC 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
    Contributed by Alex Samuel <samuel@codesourcery.com>
 
 This file is part of GCC.
 
 GCC 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
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,23 +15,18 @@ 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
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "intl.h"
-#include "rtl.h"
-
 #ifdef HAVE_SYS_TIMES_H
 # include <sys/times.h>
 #endif
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
 #ifdef HAVE_SYS_TIMES_H
 # include <sys/times.h>
 #endif
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
+#include "timevar.h"
 
 #ifndef HAVE_CLOCK_T
 typedef int clock_t;
 
 #ifndef HAVE_CLOCK_T
 typedef int clock_t;
@@ -47,16 +42,6 @@ struct tms
 };
 #endif
 
 };
 #endif
 
-#if defined HAVE_DECL_GETRUSAGE && !HAVE_DECL_GETRUSAGE
-extern int getrusage PARAMS ((int, struct rusage *));
-#endif
-#if defined HAVE_DECL_TIMES && !HAVE_DECL_TIMES
-extern clock_t times PARAMS ((struct tms *));
-#endif
-#if defined HAVE_DECL_CLOCK && !HAVE_DECL_CLOCK
-extern clock_t clock PARAMS ((void));
-#endif
-
 #ifndef RUSAGE_SELF
 # define RUSAGE_SELF 0
 #endif
 #ifndef RUSAGE_SELF
 # define RUSAGE_SELF 0
 #endif
@@ -80,17 +65,26 @@ extern clock_t clock PARAMS ((void));
 /* Prefer times to getrusage to clock (each gives successively less
    information).  */
 #ifdef HAVE_TIMES
 /* Prefer times to getrusage to clock (each gives successively less
    information).  */
 #ifdef HAVE_TIMES
+# if defined HAVE_DECL_TIMES && !HAVE_DECL_TIMES
+  extern clock_t times (struct tms *);
+# endif
 # define USE_TIMES
 # define HAVE_USER_TIME
 # define HAVE_SYS_TIME
 # define HAVE_WALL_TIME
 #else
 #ifdef HAVE_GETRUSAGE
 # define USE_TIMES
 # define HAVE_USER_TIME
 # define HAVE_SYS_TIME
 # define HAVE_WALL_TIME
 #else
 #ifdef HAVE_GETRUSAGE
+# if defined HAVE_DECL_GETRUSAGE && !HAVE_DECL_GETRUSAGE
+  extern int getrusage (int, struct rusage *);
+# endif
 # define USE_GETRUSAGE
 # define HAVE_USER_TIME
 # define HAVE_SYS_TIME
 #else
 #ifdef HAVE_CLOCK
 # define USE_GETRUSAGE
 # define HAVE_USER_TIME
 # define HAVE_SYS_TIME
 #else
 #ifdef HAVE_CLOCK
+# if defined HAVE_DECL_CLOCK && !HAVE_DECL_CLOCK
+  extern clock_t clock (void);
+# endif
 # define USE_CLOCK
 # define HAVE_USER_TIME
 #endif
 # define USE_CLOCK
 # define HAVE_USER_TIME
 #endif
@@ -111,13 +105,21 @@ static double clocks_to_msec;
 #define CLOCKS_TO_MSEC (1 / (double)CLOCKS_PER_SEC)
 #endif
 
 #define CLOCKS_TO_MSEC (1 / (double)CLOCKS_PER_SEC)
 #endif
 
-#include "flags.h"
-#include "timevar.h"
+/* True if timevars should be used.  In GCC, this happens with
+   the -ftime-report flag.  */
 
 
-/* See timevar.h for an explanation of timing variables.  */
+bool timevar_enable;
 
 
-/* This macro evaluates to nonzero if timing variables are enabled.  */
-#define TIMEVAR_ENABLE (time_report)
+/* Total amount of memory allocated by garbage collector.  */
+
+size_t timevar_ggc_mem_total;
+
+/* The amount of memory that will cause us to report the timevar even
+   if the time spent is not significant.  */
+
+#define GGC_MEM_BOUND (1 << 20)
+
+/* See timevar.h for an explanation of timing variables.  */
 
 /* A timing variable.  */
 
 
 /* A timing variable.  */
 
@@ -170,25 +172,24 @@ static struct timevar_stack_def *unused_stack_instances;
    element.  */
 static struct timevar_time_def start_time;
 
    element.  */
 static struct timevar_time_def start_time;
 
-static void get_time
-  PARAMS ((struct timevar_time_def *));
-static void timevar_accumulate
-  PARAMS ((struct timevar_time_def *, struct timevar_time_def *,
-          struct timevar_time_def *));
+static void get_time (struct timevar_time_def *);
+static void timevar_accumulate (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
    HAVE_WALL_TIME macros.  */
 
 static void
 
 /* 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
    HAVE_WALL_TIME macros.  */
 
 static void
-get_time (now)
-     struct timevar_time_def *now;
+get_time (struct timevar_time_def *now)
 {
   now->user = 0;
   now->sys  = 0;
   now->wall = 0;
 {
   now->user = 0;
   now->sys  = 0;
   now->wall = 0;
+  now->ggc_mem = timevar_ggc_mem_total;
 
 
-  if (!TIMEVAR_ENABLE)
+  if (!timevar_enable)
     return;
 
   {
     return;
 
   {
@@ -213,26 +214,25 @@ get_time (now)
 /* Add the difference between STOP_TIME and START_TIME to TIMER.  */
 
 static void
 /* 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;
+timevar_accumulate (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;
 {
   timer->user += stop_time->user - start_time->user;
   timer->sys += stop_time->sys - start_time->sys;
   timer->wall += stop_time->wall - start_time->wall;
+  timer->ggc_mem += stop_time->ggc_mem - start_time->ggc_mem;
 }
 
 /* Initialize timing variables.  */
 
 void
 }
 
 /* Initialize timing variables.  */
 
 void
-init_timevar ()
+timevar_init (void)
 {
 {
-  if (!TIMEVAR_ENABLE)
-    return;
+  timevar_enable = true;
 
   /* Zero all elapsed times.  */
 
   /* Zero all elapsed times.  */
-  memset ((void *) timevars, 0, sizeof (timevars));
+  memset (timevars, 0, sizeof (timevars));
 
   /* Initialize the names of timing variables.  */
 #define DEFTIMEVAR(identifier__, name__) \
 
   /* Initialize the names of timing variables.  */
 #define DEFTIMEVAR(identifier__, name__) \
@@ -256,22 +256,17 @@ init_timevar ()
    TIMEVAR cannot be running as a standalone timer.  */
 
 void
    TIMEVAR cannot be running as a standalone timer.  */
 
 void
-timevar_push (timevar)
-     timevar_id_t timevar;
+timevar_push_1 (timevar_id_t timevar)
 {
   struct timevar_def *tv = &timevars[timevar];
   struct timevar_stack_def *context;
   struct timevar_time_def now;
 
 {
   struct timevar_def *tv = &timevars[timevar];
   struct timevar_stack_def *context;
   struct timevar_time_def now;
 
-  if (!TIMEVAR_ENABLE)
-    return;
-
   /* Mark this timing variable as used.  */
   tv->used = 1;
 
   /* Can't push a standalone timer.  */
   /* Mark this timing variable as used.  */
   tv->used = 1;
 
   /* Can't push a standalone timer.  */
-  if (tv->standalone)
-    abort ();
+  gcc_assert (!tv->standalone);
 
   /* What time is it?  */
   get_time (&now);
 
   /* What time is it?  */
   get_time (&now);
@@ -293,8 +288,7 @@ timevar_push (timevar)
       unused_stack_instances = unused_stack_instances->next;
     }
   else
       unused_stack_instances = unused_stack_instances->next;
     }
   else
-    context = (struct timevar_stack_def *)
-      xmalloc (sizeof (struct timevar_stack_def));
+    context = XNEW (struct timevar_stack_def);
 
   /* Fill it in and put it on the stack.  */
   context->timevar = tv;
 
   /* Fill it in and put it on the stack.  */
   context->timevar = tv;
@@ -309,21 +303,12 @@ timevar_push (timevar)
    timing variable.  */
 
 void
    timing variable.  */
 
 void
-timevar_pop (timevar)
-     timevar_id_t timevar;
+timevar_pop_1 (timevar_id_t timevar)
 {
   struct timevar_time_def now;
   struct timevar_stack_def *popped = stack;
 
 {
   struct timevar_time_def now;
   struct timevar_stack_def *popped = stack;
 
-  if (!TIMEVAR_ENABLE)
-    return;
-
-  if (&timevars[timevar] != stack->timevar)
-    {
-      sorry ("cannot timevar_pop '%s' when top of timevars stack is '%s'",
-             timevars[timevar].name, stack->timevar->name);
-      abort ();
-    }
+  gcc_assert (&timevars[timevar] == stack->timevar);
 
   /* What time is it?  */
   get_time (&now);
 
   /* What time is it?  */
   get_time (&now);
@@ -349,12 +334,11 @@ timevar_pop (timevar)
    attributed to TIMEVAR.  */
 
 void
    attributed to TIMEVAR.  */
 
 void
-timevar_start (timevar)
-     timevar_id_t timevar;
+timevar_start (timevar_id_t timevar)
 {
   struct timevar_def *tv = &timevars[timevar];
 
 {
   struct timevar_def *tv = &timevars[timevar];
 
-  if (!TIMEVAR_ENABLE)
+  if (!timevar_enable)
     return;
 
   /* Mark this timing variable as used.  */
     return;
 
   /* Mark this timing variable as used.  */
@@ -362,8 +346,7 @@ timevar_start (timevar)
 
   /* Don't allow the same timing variable to be started more than
      once.  */
 
   /* Don't allow the same timing variable to be started more than
      once.  */
-  if (tv->standalone)
-    abort ();
+  gcc_assert (!tv->standalone);
   tv->standalone = 1;
 
   get_time (&tv->start_time);
   tv->standalone = 1;
 
   get_time (&tv->start_time);
@@ -373,57 +356,27 @@ timevar_start (timevar)
    is attributed to it.  */
 
 void
    is attributed to it.  */
 
 void
-timevar_stop (timevar)
-     timevar_id_t timevar;
+timevar_stop (timevar_id_t timevar)
 {
   struct timevar_def *tv = &timevars[timevar];
   struct timevar_time_def now;
 
 {
   struct timevar_def *tv = &timevars[timevar];
   struct timevar_time_def now;
 
-  if (!TIMEVAR_ENABLE)
+  if (!timevar_enable)
     return;
 
   /* TIMEVAR must have been started via timevar_start.  */
     return;
 
   /* TIMEVAR must have been started via timevar_start.  */
-  if (!tv->standalone)
-    abort ();
+  gcc_assert (tv->standalone);
 
   get_time (&now);
   timevar_accumulate (&tv->elapsed, &tv->start_time, &now);
 }
 
 
   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];
-  struct timevar_time_def now;
-
-  *elapsed = tv->elapsed;
-
-  /* Is TIMEVAR currently running as a standalone timer?  */
-  if (tv->standalone)
-    {
-      get_time (&now);
-      timevar_accumulate (elapsed, &tv->start_time, &now);
-    }
-  /* Or is TIMEVAR at the top of the timer stack?  */
-  else if (stack->timevar == tv)
-    {
-      get_time (&now);
-      timevar_accumulate (elapsed, &start_time, &now);
-    }
-}
-
 /* 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
 /* 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;
+timevar_print (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)
 {
   /* Only print stuff if we have some sort of time information.  */
 #if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME)
@@ -431,7 +384,7 @@ timevar_print (fp)
   struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed;
   struct timevar_time_def now;
 
   struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed;
   struct timevar_time_def now;
 
-  if (!TIMEVAR_ENABLE)
+  if (!timevar_enable)
     return;
 
   /* Update timing information in case we're calling this from GDB.  */
     return;
 
   /* Update timing information in case we're calling this from GDB.  */
@@ -451,7 +404,7 @@ timevar_print (fp)
      TIMEVAR.  */
   start_time = now;
 
      TIMEVAR.  */
   start_time = now;
 
-  fputs (_("\nExecution times (seconds)\n"), fp);
+  fputs ("\nExecution times (seconds)\n", fp);
   for (id = 0; id < (unsigned int) TIMEVAR_LAST; ++id)
     {
       struct timevar_def *tv = &timevars[(timevar_id_t) id];
   for (id = 0; id < (unsigned int) TIMEVAR_LAST; ++id)
     {
       struct timevar_def *tv = &timevars[(timevar_id_t) id];
@@ -470,7 +423,8 @@ timevar_print (fp)
          zeroes.  */
       if (tv->elapsed.user < tiny
          && tv->elapsed.sys < tiny
          zeroes.  */
       if (tv->elapsed.user < tiny
          && tv->elapsed.sys < tiny
-         && tv->elapsed.wall < tiny)
+         && tv->elapsed.wall < tiny
+         && tv->elapsed.ggc_mem < GGC_MEM_BOUND)
        continue;
 
       /* The timing variable name.  */
        continue;
 
       /* The timing variable name.  */
@@ -497,11 +451,18 @@ timevar_print (fp)
               (total->wall == 0 ? 0 : tv->elapsed.wall / total->wall) * 100);
 #endif /* HAVE_WALL_TIME */
 
               (total->wall == 0 ? 0 : tv->elapsed.wall / total->wall) * 100);
 #endif /* HAVE_WALL_TIME */
 
+      /* Print the amount of ggc memory allocated.  */
+      fprintf (fp, "%8u kB (%2.0f%%) ggc",
+              (unsigned) (tv->elapsed.ggc_mem >> 10),
+              (total->ggc_mem == 0
+               ? 0
+               : (float) tv->elapsed.ggc_mem / total->ggc_mem) * 100);
+
       putc ('\n', fp);
     }
 
   /* Print total time.  */
       putc ('\n', fp);
     }
 
   /* Print total time.  */
-  fputs (_(" TOTAL                 :"), fp);
+  fputs (" TOTAL                 :", fp);
 #ifdef HAVE_USER_TIME
   fprintf (fp, "%7.2f          ", total->user);
 #endif
 #ifdef HAVE_USER_TIME
   fprintf (fp, "%7.2f          ", total->user);
 #endif
@@ -509,35 +470,32 @@ timevar_print (fp)
   fprintf (fp, "%7.2f          ", total->sys);
 #endif
 #ifdef HAVE_WALL_TIME
   fprintf (fp, "%7.2f          ", total->sys);
 #endif
 #ifdef HAVE_WALL_TIME
-  fprintf (fp, "%7.2f\n", total->wall);
+  fprintf (fp, "%7.2f           ", total->wall);
+#endif
+  fprintf (fp, "%8u kB\n", (unsigned) (total->ggc_mem >> 10));
+
+#ifdef ENABLE_CHECKING
+  fprintf (fp, "Extra diagnostic checks enabled; compiler may run slowly.\n");
+  fprintf (fp, "Configure with --enable-checking=release to disable checks.\n");
+#endif
+#ifndef ENABLE_ASSERT_CHECKING
+  fprintf (fp, "Internal checks disabled; compiler is not suited for release.\n");
+  fprintf (fp, "Configure with --enable-checking=release to enable checks.\n");
 #endif
 
 #endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
          || defined (HAVE_WALL_TIME) */
 }
 
 #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
 /* 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;
+print_time (const char *str, long total)
 {
   long all_time = get_run_time ();
   fprintf (stderr,
 {
   long all_time = get_run_time ();
   fprintf (stderr,
-          _("time in %s: %ld.%06ld (%ld%%)\n"),
+          "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));
           str, total / 1000000, total % 1000000,
           all_time == 0 ? 0
           : (long) (((100.0 * (double) total) / (double) all_time) + .5));