LCOV - code coverage report
Current view: top level - gcc - statistics.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.3 % 128 122
Test Date: 2024-12-14 13:15:07 Functions: 100.0 % 14 14
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Optimization statistics functions.
       2                 :             :    Copyright (C) 2008-2024 Free Software Foundation, Inc.
       3                 :             :    Contributed by Richard Guenther  <rguenther@suse.de>
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it under
       8                 :             : the terms of the GNU General Public License as published by the Free
       9                 :             : Software Foundation; either version 3, or (at your option) any later
      10                 :             : version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :             : 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                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "coretypes.h"
      24                 :             : #include "function.h"
      25                 :             : #include "tree-pass.h"
      26                 :             : #include "context.h"
      27                 :             : #include "pass_manager.h"
      28                 :             : #include "tree.h"
      29                 :             : 
      30                 :             : static int statistics_dump_nr;
      31                 :             : static dump_flags_t statistics_dump_flags;
      32                 :             : static FILE *statistics_dump_file;
      33                 :             : 
      34                 :             : /* Statistics entry.  A integer counter associated to a string ID
      35                 :             :    and value.  */
      36                 :             : 
      37                 :             : struct statistics_counter {
      38                 :             :   const char *id;
      39                 :             :   int val;
      40                 :             :   bool histogram_p;
      41                 :             :   unsigned HOST_WIDE_INT count;
      42                 :             :   unsigned HOST_WIDE_INT prev_dumped_count;
      43                 :             : };
      44                 :             : 
      45                 :             : /* Hashtable helpers.  */
      46                 :             : 
      47                 :             : struct stats_counter_hasher : pointer_hash <statistics_counter>
      48                 :             : {
      49                 :             :   static inline hashval_t hash (const statistics_counter *);
      50                 :             :   static inline bool equal (const statistics_counter *,
      51                 :             :                             const statistics_counter *);
      52                 :             :   static inline void remove (statistics_counter *);
      53                 :             : };
      54                 :             : 
      55                 :             : /* Hash a statistic counter by its string ID.  */
      56                 :             : 
      57                 :             : inline hashval_t
      58                 :      160681 : stats_counter_hasher::hash (const statistics_counter *c)
      59                 :             : {
      60                 :      160681 :   return htab_hash_string (c->id) + c->val;
      61                 :             : }
      62                 :             : 
      63                 :             : /* Compare two statistic counters by their string IDs.  */
      64                 :             : 
      65                 :             : inline bool
      66                 :      160249 : stats_counter_hasher::equal (const statistics_counter *c1,
      67                 :             :                              const statistics_counter *c2)
      68                 :             : {
      69                 :      160249 :   return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
      70                 :             : }
      71                 :             : 
      72                 :             : /* Free a statistics entry.  */
      73                 :             : 
      74                 :             : inline void
      75                 :             : stats_counter_hasher::remove (statistics_counter *v)
      76                 :             : {
      77                 :             :   free (CONST_CAST (char *, v->id));
      78                 :             :   free (v);
      79                 :             : }
      80                 :             : 
      81                 :             : typedef hash_table<stats_counter_hasher> stats_counter_table_type;
      82                 :             : 
      83                 :             : /* Array of statistic hashes, indexed by pass id.  */
      84                 :             : static stats_counter_table_type **statistics_hashes;
      85                 :             : static unsigned nr_statistics_hashes;
      86                 :             : 
      87                 :             : /* Return the current hashtable to be used for recording or printing
      88                 :             :    statistics.  */
      89                 :             : 
      90                 :             : static stats_counter_table_type *
      91                 :   544317109 : curr_statistics_hash (bool alloc = true)
      92                 :             : {
      93                 :   544317109 :   unsigned idx;
      94                 :             : 
      95                 :   544317109 :   gcc_assert (current_pass->static_pass_number >= 0);
      96                 :   544317109 :   idx = current_pass->static_pass_number;
      97                 :             : 
      98                 :   544317109 :   if (idx < nr_statistics_hashes
      99                 :      657102 :       && statistics_hashes[idx])
     100                 :             :     return statistics_hashes[idx];
     101                 :             : 
     102                 :   544184628 :   if (!alloc)
     103                 :             :     return nullptr;
     104                 :             : 
     105                 :         679 :   if (idx >= nr_statistics_hashes)
     106                 :             :     {
     107                 :         610 :       statistics_hashes = XRESIZEVEC (stats_counter_table_type *,
     108                 :             :                                       statistics_hashes, idx+1);
     109                 :         610 :       memset (statistics_hashes + nr_statistics_hashes, 0,
     110                 :         610 :               (idx + 1 - nr_statistics_hashes)
     111                 :             :               * sizeof (stats_counter_table_type *));
     112                 :         610 :       nr_statistics_hashes = idx + 1;
     113                 :             :     }
     114                 :             : 
     115                 :         679 :   statistics_hashes[idx] = new stats_counter_table_type (15);
     116                 :             : 
     117                 :         679 :   return statistics_hashes[idx];
     118                 :             : }
     119                 :             : 
     120                 :             : /* Helper function to return asmname or name of FN
     121                 :             :    depending on whether asmname option is set.  */
     122                 :             : 
     123                 :             : static const char *
     124                 :       38293 : get_function_name (struct function *fn)
     125                 :             : {
     126                 :       38293 :   if ((statistics_dump_flags & TDF_ASMNAME)
     127                 :       38293 :       && fn && DECL_ASSEMBLER_NAME_SET_P (fn->decl))
     128                 :             :     {
     129                 :           0 :       tree asmname = decl_assembler_name (fn->decl);
     130                 :           0 :       if (asmname)
     131                 :           0 :         return IDENTIFIER_POINTER (asmname);
     132                 :             :     }
     133                 :       38293 :   return function_name (fn);
     134                 :             : }
     135                 :             : 
     136                 :             : /* Helper for statistics_fini_pass.  Print the counter difference
     137                 :             :    since the last dump for the pass dump files.  */
     138                 :             : 
     139                 :             : int
     140                 :        2211 : statistics_fini_pass_1 (statistics_counter **slot,
     141                 :             :                         void *data ATTRIBUTE_UNUSED)
     142                 :             : {
     143                 :        2211 :   statistics_counter *counter = *slot;
     144                 :        2211 :   unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
     145                 :        2211 :   if (count == 0)
     146                 :             :     return 1;
     147                 :        1689 :   if (counter->histogram_p)
     148                 :         666 :     fprintf (dump_file, "%s == %d: " HOST_WIDE_INT_PRINT_DEC "\n",
     149                 :             :              counter->id, counter->val, count);
     150                 :             :   else
     151                 :        1023 :     fprintf (dump_file, "%s: " HOST_WIDE_INT_PRINT_DEC "\n",
     152                 :             :              counter->id, count);
     153                 :        1689 :   counter->prev_dumped_count = counter->count;
     154                 :        1689 :   return 1;
     155                 :             : }
     156                 :             : 
     157                 :             : /* Helper for statistics_fini_pass.  Print the counter difference
     158                 :             :    since the last dump for the statistics dump.  */
     159                 :             : 
     160                 :             : int
     161                 :      497221 : statistics_fini_pass_2 (statistics_counter **slot,
     162                 :             :                         void *data ATTRIBUTE_UNUSED)
     163                 :             : {
     164                 :      497221 :   statistics_counter *counter = *slot;
     165                 :      497221 :   unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
     166                 :      497221 :   if (count == 0)
     167                 :             :     return 1;
     168                 :       38293 :   counter->prev_dumped_count = counter->count;
     169                 :       38293 :   if (counter->histogram_p)
     170                 :       19489 :     fprintf (statistics_dump_file,
     171                 :             :              "%d %s \"%s == %d\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
     172                 :             :              current_pass->static_pass_number,
     173                 :             :              current_pass->name,
     174                 :             :              counter->id, counter->val,
     175                 :             :              get_function_name (cfun),
     176                 :             :              count);
     177                 :             :   else
     178                 :       18804 :     fprintf (statistics_dump_file,
     179                 :             :              "%d %s \"%s\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
     180                 :             :              current_pass->static_pass_number,
     181                 :             :              current_pass->name,
     182                 :             :              counter->id,
     183                 :             :              get_function_name (cfun),
     184                 :             :              count);
     185                 :       38293 :   counter->prev_dumped_count = counter->count;
     186                 :       38293 :   return 1;
     187                 :             : }
     188                 :             : 
     189                 :             : /* Helper for statistics_fini_pass, reset the counters.  */
     190                 :             : 
     191                 :             : int
     192                 :      624103 : statistics_fini_pass_3 (statistics_counter **slot,
     193                 :             :                         void *data ATTRIBUTE_UNUSED)
     194                 :             : {
     195                 :      624103 :   statistics_counter *counter = *slot;
     196                 :      624103 :   counter->prev_dumped_count = counter->count;
     197                 :      624103 :   return 1;
     198                 :             : }
     199                 :             : 
     200                 :             : /* Dump the current statistics incrementally.  */
     201                 :             : 
     202                 :             : void
     203                 :   599837680 : statistics_fini_pass (void)
     204                 :             : {
     205                 :   599837680 :   if (current_pass->static_pass_number == -1)
     206                 :             :     return;
     207                 :             : 
     208                 :   544272534 :   stats_counter_table_type *stat_hash = curr_statistics_hash (false);
     209                 :             : 
     210                 :   544272534 :   if (dump_file
     211                 :   544272534 :       && dump_flags & TDF_STATS)
     212                 :             :     {
     213                 :        1798 :       fprintf (dump_file, "\n");
     214                 :        1798 :       fprintf (dump_file, "Pass statistics of \"%s\": ", current_pass->name);
     215                 :        1798 :       fprintf (dump_file, "----------------\n");
     216                 :        1798 :       if (stat_hash)
     217                 :        2772 :         stat_hash->traverse_noresize <void *, statistics_fini_pass_1> (NULL);
     218                 :        1798 :       fprintf (dump_file, "\n");
     219                 :             :     }
     220                 :             : 
     221                 :   544272534 :   if (!stat_hash)
     222                 :             :     return;
     223                 :             : 
     224                 :       88585 :   if (statistics_dump_file
     225                 :       88585 :       && !(statistics_dump_flags & TDF_STATS
     226                 :       65229 :            || statistics_dump_flags & TDF_DETAILS))
     227                 :      562450 :     stat_hash->traverse_noresize <void *, statistics_fini_pass_2> (NULL);
     228                 :      712688 :   stat_hash->traverse_noresize <void *, statistics_fini_pass_3> (NULL);
     229                 :             : }
     230                 :             : 
     231                 :             : /* Helper for printing summary information.  */
     232                 :             : 
     233                 :             : int
     234                 :          43 : statistics_fini_1 (statistics_counter **slot, opt_pass *pass)
     235                 :             : {
     236                 :          43 :   statistics_counter *counter = *slot;
     237                 :          43 :   if (counter->count == 0)
     238                 :             :     return 1;
     239                 :          43 :   if (counter->histogram_p)
     240                 :          22 :     fprintf (statistics_dump_file,
     241                 :             :              "%d %s \"%s == %d\" " HOST_WIDE_INT_PRINT_DEC "\n",
     242                 :             :              pass->static_pass_number,
     243                 :             :              pass->name,
     244                 :             :              counter->id, counter->val,
     245                 :             :              counter->count);
     246                 :             :   else
     247                 :          21 :     fprintf (statistics_dump_file,
     248                 :             :              "%d %s \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
     249                 :             :              pass->static_pass_number,
     250                 :             :              pass->name,
     251                 :             :              counter->id,
     252                 :             :              counter->count);
     253                 :             :   return 1;
     254                 :             : }
     255                 :             : 
     256                 :             : /* Finish the statistics and dump summary information.  */
     257                 :             : 
     258                 :             : void
     259                 :      269314 : statistics_fini (void)
     260                 :             : {
     261                 :      269314 :   gcc::pass_manager *passes = g->get_passes ();
     262                 :      269314 :   if (!statistics_dump_file)
     263                 :             :     return;
     264                 :             : 
     265                 :          63 :   if (statistics_dump_flags & TDF_STATS)
     266                 :             :     {
     267                 :             :       unsigned i;
     268                 :         312 :       for (i = 0; i < nr_statistics_hashes; ++i)
     269                 :         309 :         if (statistics_hashes[i]
     270                 :         309 :             && passes->get_pass_for_id (i) != NULL)
     271                 :           7 :           statistics_hashes[i]
     272                 :             :             ->traverse_noresize <opt_pass *, statistics_fini_1>
     273                 :          50 :             (passes->get_pass_for_id (i));
     274                 :             :     }
     275                 :             : 
     276                 :          63 :   dump_end (statistics_dump_nr, statistics_dump_file);
     277                 :             : }
     278                 :             : 
     279                 :             : /* Register the statistics dump file.  */
     280                 :             : 
     281                 :             : void
     282                 :      277256 : statistics_early_init (void)
     283                 :             : {
     284                 :      277256 :   gcc::dump_manager *dumps = g->get_dumps ();
     285                 :      277256 :   statistics_dump_nr = dumps->dump_register (".statistics", "statistics",
     286                 :             :                                              "statistics", DK_tree,
     287                 :             :                                              OPTGROUP_NONE,
     288                 :             :                                              false);
     289                 :      277256 : }
     290                 :             : 
     291                 :             : /* Init the statistics.  */
     292                 :             : 
     293                 :             : void
     294                 :      270959 : statistics_init (void)
     295                 :             : {
     296                 :      270959 :   gcc::dump_manager *dumps = g->get_dumps ();
     297                 :      270959 :   statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
     298                 :      270959 :   statistics_dump_flags = dumps->get_dump_file_info (statistics_dump_nr)->pflags;
     299                 :      270959 : }
     300                 :             : 
     301                 :             : /* Lookup or add a statistics counter in the hashtable HASH with ID, VAL
     302                 :             :    and HISTOGRAM_P.  */
     303                 :             : 
     304                 :             : static statistics_counter *
     305                 :       44575 : lookup_or_add_counter (stats_counter_table_type *hash, const char *id, int val,
     306                 :             :                        bool histogram_p)
     307                 :             : {
     308                 :       44575 :   statistics_counter **counter;
     309                 :       44575 :   statistics_counter c;
     310                 :       44575 :   c.id = id;
     311                 :       44575 :   c.val = val;
     312                 :       44575 :   counter = hash->find_slot (&c, INSERT);
     313                 :       44575 :   if (!*counter)
     314                 :             :     {
     315                 :        3341 :       *counter = XNEW (statistics_counter);
     316                 :        3341 :       (*counter)->id = xstrdup (id);
     317                 :        3341 :       (*counter)->val = val;
     318                 :        3341 :       (*counter)->histogram_p = histogram_p;
     319                 :        3341 :       (*counter)->prev_dumped_count = 0;
     320                 :        3341 :       (*counter)->count = 0;
     321                 :             :     }
     322                 :       44575 :   return *counter;
     323                 :             : }
     324                 :             : 
     325                 :             : /* Add statistics information about event ID in function FN.
     326                 :             :    This will increment the counter associated with ID by INCR.
     327                 :             :    It will also dump the event to the global statistics file if requested.  */
     328                 :             : 
     329                 :             : void
     330                 :   211865198 : statistics_counter_event (struct function *fn, const char *id, int incr)
     331                 :             : {
     332                 :   211865198 :   statistics_counter *counter;
     333                 :             : 
     334                 :   211865198 :   if ((!(dump_flags & TDF_STATS)
     335                 :   211863359 :        && !statistics_dump_file)
     336                 :   212001457 :       || incr == 0)
     337                 :             :     return;
     338                 :             : 
     339                 :       20880 :   if (current_pass
     340                 :       20876 :       && current_pass->static_pass_number != -1)
     341                 :             :     {
     342                 :       20876 :       counter = lookup_or_add_counter (curr_statistics_hash (), id, 0, false);
     343                 :       20876 :       gcc_assert (!counter->histogram_p);
     344                 :       20876 :       counter->count += incr;
     345                 :             :     }
     346                 :             : 
     347                 :       20880 :   if (!statistics_dump_file
     348                 :       20880 :       || !(statistics_dump_flags & TDF_DETAILS))
     349                 :             :     return;
     350                 :             : 
     351                 :           0 :   fprintf (statistics_dump_file,
     352                 :             :            "%d %s \"%s\" \"%s\" %d\n",
     353                 :             :            current_pass ? current_pass->static_pass_number : -1,
     354                 :           0 :            current_pass ? current_pass->name : "none",
     355                 :             :            id,
     356                 :             :            get_function_name (fn),
     357                 :             :            incr);
     358                 :             : }
     359                 :             : 
     360                 :             : /* Add statistics information about event ID in function FN with the
     361                 :             :    histogram value VAL.
     362                 :             :    It will dump the event to the global statistics file if requested.  */
     363                 :             : 
     364                 :             : void
     365                 :    71451663 : statistics_histogram_event (struct function *fn, const char *id, int val)
     366                 :             : {
     367                 :    71451663 :   statistics_counter *counter;
     368                 :             : 
     369                 :    71451663 :   if (!(dump_flags & TDF_STATS)
     370                 :    71451663 :       && !statistics_dump_file)
     371                 :             :     return;
     372                 :             : 
     373                 :       23699 :   counter = lookup_or_add_counter (curr_statistics_hash (), id, val, true);
     374                 :       23699 :   gcc_assert (counter->histogram_p);
     375                 :       23699 :   counter->count += 1;
     376                 :             : 
     377                 :       23699 :   if (!statistics_dump_file
     378                 :       23699 :       || !(statistics_dump_flags & TDF_DETAILS))
     379                 :             :     return;
     380                 :             : 
     381                 :           0 :   fprintf (statistics_dump_file,
     382                 :             :            "%d %s \"%s == %d\" \"%s\" 1\n",
     383                 :             :            current_pass->static_pass_number,
     384                 :             :            current_pass->name,
     385                 :             :            id, val,
     386                 :             :            get_function_name (fn));
     387                 :             : }
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.