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