LCOV - code coverage report
Current view: top level - gcc - statistics.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 111 120 92.5 %
Date: 2020-04-04 11:58:09 Functions: 11 12 91.7 %
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-2020 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                 :            : 
      29                 :            : static int statistics_dump_nr;
      30                 :            : static dump_flags_t statistics_dump_flags;
      31                 :            : static FILE *statistics_dump_file;
      32                 :            : 
      33                 :            : /* Statistics entry.  A integer counter associated to a string ID
      34                 :            :    and value.  */
      35                 :            : 
      36                 :            : struct statistics_counter {
      37                 :            :   const char *id;
      38                 :            :   int val;
      39                 :            :   bool histogram_p;
      40                 :            :   unsigned HOST_WIDE_INT count;
      41                 :            :   unsigned HOST_WIDE_INT prev_dumped_count;
      42                 :            : };
      43                 :            : 
      44                 :            : /* Hashtable helpers.  */
      45                 :            : 
      46                 :            : struct stats_counter_hasher : pointer_hash <statistics_counter>
      47                 :            : {
      48                 :            :   static inline hashval_t hash (const statistics_counter *);
      49                 :            :   static inline bool equal (const statistics_counter *,
      50                 :            :                             const statistics_counter *);
      51                 :            :   static inline void remove (statistics_counter *);
      52                 :            : };
      53                 :            : 
      54                 :            : /* Hash a statistic counter by its string ID.  */
      55                 :            : 
      56                 :            : inline hashval_t
      57                 :     154671 : stats_counter_hasher::hash (const statistics_counter *c)
      58                 :            : {
      59                 :     154671 :   return htab_hash_string (c->id) + c->val;
      60                 :            : }
      61                 :            : 
      62                 :            : /* Compare two statistic counters by their string IDs.  */
      63                 :            : 
      64                 :            : inline bool
      65                 :     154454 : stats_counter_hasher::equal (const statistics_counter *c1,
      66                 :            :                              const statistics_counter *c2)
      67                 :            : {
      68                 :     154454 :   return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
      69                 :            : }
      70                 :            : 
      71                 :            : /* Free a statistics entry.  */
      72                 :            : 
      73                 :            : inline void
      74                 :            : stats_counter_hasher::remove (statistics_counter *v)
      75                 :            : {
      76                 :            :   free (CONST_CAST (char *, v->id));
      77                 :            :   free (v);
      78                 :            : }
      79                 :            : 
      80                 :            : typedef hash_table<stats_counter_hasher> stats_counter_table_type;
      81                 :            : 
      82                 :            : /* Array of statistic hashes, indexed by pass id.  */
      83                 :            : static stats_counter_table_type **statistics_hashes;
      84                 :            : static unsigned nr_statistics_hashes;
      85                 :            : 
      86                 :            : /* Return the current hashtable to be used for recording or printing
      87                 :            :    statistics.  */
      88                 :            : 
      89                 :            : static stats_counter_table_type *
      90                 :  327106000 : curr_statistics_hash (void)
      91                 :            : {
      92                 :  327106000 :   unsigned idx;
      93                 :            : 
      94                 :  327106000 :   gcc_assert (current_pass->static_pass_number >= 0);
      95                 :  327106000 :   idx = current_pass->static_pass_number;
      96                 :            : 
      97                 :  327106000 :   if (idx < nr_statistics_hashes
      98                 :  304946000 :       && statistics_hashes[idx])
      99                 :            :     return statistics_hashes[idx];
     100                 :            : 
     101                 :   22601900 :   if (idx >= nr_statistics_hashes)
     102                 :            :     {
     103                 :   22159900 :       statistics_hashes = XRESIZEVEC (stats_counter_table_type *,
     104                 :            :                                       statistics_hashes, idx+1);
     105                 :   22159900 :       memset (statistics_hashes + nr_statistics_hashes, 0,
     106                 :   22159900 :               (idx + 1 - nr_statistics_hashes)
     107                 :            :               * sizeof (stats_counter_table_type *));
     108                 :   22159900 :       nr_statistics_hashes = idx + 1;
     109                 :            :     }
     110                 :            : 
     111                 :   22601900 :   statistics_hashes[idx] = new stats_counter_table_type (15);
     112                 :            : 
     113                 :   22601900 :   return statistics_hashes[idx];
     114                 :            : }
     115                 :            : 
     116                 :            : /* Helper for statistics_fini_pass.  Print the counter difference
     117                 :            :    since the last dump for the pass dump files.  */
     118                 :            : 
     119                 :            : int
     120                 :       1837 : statistics_fini_pass_1 (statistics_counter **slot,
     121                 :            :                         void *data ATTRIBUTE_UNUSED)
     122                 :            : {
     123                 :       1837 :   statistics_counter *counter = *slot;
     124                 :       1837 :   unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
     125                 :       1837 :   if (count == 0)
     126                 :            :     return 1;
     127                 :       1344 :   if (counter->histogram_p)
     128                 :        609 :     fprintf (dump_file, "%s == %d: " HOST_WIDE_INT_PRINT_DEC "\n",
     129                 :            :              counter->id, counter->val, count);
     130                 :            :   else
     131                 :        735 :     fprintf (dump_file, "%s: " HOST_WIDE_INT_PRINT_DEC "\n",
     132                 :            :              counter->id, count);
     133                 :       1344 :   counter->prev_dumped_count = counter->count;
     134                 :       1344 :   return 1;
     135                 :            : }
     136                 :            : 
     137                 :            : /* Helper for statistics_fini_pass.  Print the counter difference
     138                 :            :    since the last dump for the statistics dump.  */
     139                 :            : 
     140                 :            : int
     141                 :     329241 : statistics_fini_pass_2 (statistics_counter **slot,
     142                 :            :                         void *data ATTRIBUTE_UNUSED)
     143                 :            : {
     144                 :     329241 :   statistics_counter *counter = *slot;
     145                 :     329241 :   unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
     146                 :     329241 :   if (count == 0)
     147                 :            :     return 1;
     148                 :      29485 :   counter->prev_dumped_count = counter->count;
     149                 :      29485 :   if (counter->histogram_p)
     150                 :      17333 :     fprintf (statistics_dump_file,
     151                 :            :              "%d %s \"%s == %d\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
     152                 :            :              current_pass->static_pass_number,
     153                 :            :              current_pass->name,
     154                 :            :              counter->id, counter->val,
     155                 :            :              current_function_name (),
     156                 :            :              count);
     157                 :            :   else
     158                 :      12152 :     fprintf (statistics_dump_file,
     159                 :            :              "%d %s \"%s\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
     160                 :            :              current_pass->static_pass_number,
     161                 :            :              current_pass->name,
     162                 :            :              counter->id,
     163                 :            :              current_function_name (),
     164                 :            :              count);
     165                 :      29485 :   counter->prev_dumped_count = counter->count;
     166                 :      29485 :   return 1;
     167                 :            : }
     168                 :            : 
     169                 :            : /* Helper for statistics_fini_pass, reset the counters.  */
     170                 :            : 
     171                 :            : int
     172                 :     425860 : statistics_fini_pass_3 (statistics_counter **slot,
     173                 :            :                         void *data ATTRIBUTE_UNUSED)
     174                 :            : {
     175                 :     425860 :   statistics_counter *counter = *slot;
     176                 :     425860 :   counter->prev_dumped_count = counter->count;
     177                 :     425860 :   return 1;
     178                 :            : }
     179                 :            : 
     180                 :            : /* Dump the current statistics incrementally.  */
     181                 :            : 
     182                 :            : void
     183                 :  364852000 : statistics_fini_pass (void)
     184                 :            : {
     185                 :  364852000 :   if (current_pass->static_pass_number == -1)
     186                 :            :     return;
     187                 :            : 
     188                 :  326840000 :   if (dump_file
     189                 :  326840000 :       && dump_flags & TDF_STATS)
     190                 :            :     {
     191                 :       1504 :       fprintf (dump_file, "\n");
     192                 :       1504 :       fprintf (dump_file, "Pass statistics of \"%s\": ", current_pass->name);
     193                 :       1504 :       fprintf (dump_file, "----------------\n");
     194                 :       1504 :       curr_statistics_hash ()
     195                 :       1504 :         ->traverse_noresize <void *, statistics_fini_pass_1> (NULL);
     196                 :       1504 :       fprintf (dump_file, "\n");
     197                 :            :     }
     198                 :  326840000 :   if (statistics_dump_file
     199                 :     229324 :       && !(statistics_dump_flags & TDF_STATS
     200                 :  327069000 :            || statistics_dump_flags & TDF_DETAILS))
     201                 :     228976 :     curr_statistics_hash ()
     202                 :     228976 :       ->traverse_noresize <void *, statistics_fini_pass_2> (NULL);
     203                 :  326840000 :   curr_statistics_hash ()
     204                 :  326840000 :     ->traverse_noresize <void *, statistics_fini_pass_3> (NULL);
     205                 :            : }
     206                 :            : 
     207                 :            : /* Helper for printing summary information.  */
     208                 :            : 
     209                 :            : int
     210                 :          0 : statistics_fini_1 (statistics_counter **slot, opt_pass *pass)
     211                 :            : {
     212                 :          0 :   statistics_counter *counter = *slot;
     213                 :          0 :   if (counter->count == 0)
     214                 :            :     return 1;
     215                 :          0 :   if (counter->histogram_p)
     216                 :          0 :     fprintf (statistics_dump_file,
     217                 :            :              "%d %s \"%s == %d\" " HOST_WIDE_INT_PRINT_DEC "\n",
     218                 :            :              pass->static_pass_number,
     219                 :            :              pass->name,
     220                 :            :              counter->id, counter->val,
     221                 :            :              counter->count);
     222                 :            :   else
     223                 :          0 :     fprintf (statistics_dump_file,
     224                 :            :              "%d %s \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
     225                 :            :              pass->static_pass_number,
     226                 :            :              pass->name,
     227                 :            :              counter->id,
     228                 :            :              counter->count);
     229                 :            :   return 1;
     230                 :            : }
     231                 :            : 
     232                 :            : /* Finish the statistics and dump summary information.  */
     233                 :            : 
     234                 :            : void
     235                 :     198377 : statistics_fini (void)
     236                 :            : {
     237                 :     198377 :   gcc::pass_manager *passes = g->get_passes ();
     238                 :     198377 :   if (!statistics_dump_file)
     239                 :            :     return;
     240                 :            : 
     241                 :         60 :   if (statistics_dump_flags & TDF_STATS)
     242                 :            :     {
     243                 :            :       unsigned i;
     244                 :        654 :       for (i = 0; i < nr_statistics_hashes; ++i)
     245                 :        652 :         if (statistics_hashes[i]
     246                 :        652 :             && passes->get_pass_for_id (i) != NULL)
     247                 :        110 :           statistics_hashes[i]
     248                 :            :             ->traverse_noresize <opt_pass *, statistics_fini_1>
     249                 :        110 :             (passes->get_pass_for_id (i));
     250                 :            :     }
     251                 :            : 
     252                 :         60 :   dump_end (statistics_dump_nr, statistics_dump_file);
     253                 :            : }
     254                 :            : 
     255                 :            : /* Register the statistics dump file.  */
     256                 :            : 
     257                 :            : void
     258                 :     200773 : statistics_early_init (void)
     259                 :            : {
     260                 :     200773 :   gcc::dump_manager *dumps = g->get_dumps ();
     261                 :     200773 :   statistics_dump_nr = dumps->dump_register (".statistics", "statistics",
     262                 :            :                                              "statistics", DK_tree,
     263                 :            :                                              OPTGROUP_NONE,
     264                 :            :                                              false);
     265                 :     200773 : }
     266                 :            : 
     267                 :            : /* Init the statistics.  */
     268                 :            : 
     269                 :            : void
     270                 :     198582 : statistics_init (void)
     271                 :            : {
     272                 :     198582 :   gcc::dump_manager *dumps = g->get_dumps ();
     273                 :     198582 :   statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
     274                 :     198582 :   statistics_dump_flags = dumps->get_dump_file_info (statistics_dump_nr)->pflags;
     275                 :     198582 : }
     276                 :            : 
     277                 :            : /* Lookup or add a statistics counter in the hashtable HASH with ID, VAL
     278                 :            :    and HISTOGRAM_P.  */
     279                 :            : 
     280                 :            : static statistics_counter *
     281                 :      35373 : lookup_or_add_counter (stats_counter_table_type *hash, const char *id, int val,
     282                 :            :                        bool histogram_p)
     283                 :            : {
     284                 :      35373 :   statistics_counter **counter;
     285                 :      35373 :   statistics_counter c;
     286                 :      35373 :   c.id = id;
     287                 :      35373 :   c.val = val;
     288                 :      35373 :   counter = hash->find_slot (&c, INSERT);
     289                 :      35373 :   if (!*counter)
     290                 :            :     {
     291                 :       2796 :       *counter = XNEW (statistics_counter);
     292                 :       2796 :       (*counter)->id = xstrdup (id);
     293                 :       2796 :       (*counter)->val = val;
     294                 :       2796 :       (*counter)->histogram_p = histogram_p;
     295                 :       2796 :       (*counter)->prev_dumped_count = 0;
     296                 :       2796 :       (*counter)->count = 0;
     297                 :            :     }
     298                 :      35373 :   return *counter;
     299                 :            : }
     300                 :            : 
     301                 :            : /* Add statistics information about event ID in function FN.
     302                 :            :    This will increment the counter associated with ID by INCR.
     303                 :            :    It will also dump the event to the global statistics file if requested.  */
     304                 :            : 
     305                 :            : void
     306                 :   92294200 : statistics_counter_event (struct function *fn, const char *id, int incr)
     307                 :            : {
     308                 :   92294200 :   statistics_counter *counter;
     309                 :            : 
     310                 :   92294200 :   if ((!(dump_flags & TDF_STATS)
     311                 :   92293000 :        && !statistics_dump_file)
     312                 :   92363000 :       || incr == 0)
     313                 :            :     return;
     314                 :            : 
     315                 :      14094 :   if (current_pass
     316                 :      14094 :       && current_pass->static_pass_number != -1)
     317                 :            :     {
     318                 :      14094 :       counter = lookup_or_add_counter (curr_statistics_hash (), id, 0, false);
     319                 :      14094 :       gcc_assert (!counter->histogram_p);
     320                 :      14094 :       counter->count += incr;
     321                 :            :     }
     322                 :            : 
     323                 :      14094 :   if (!statistics_dump_file
     324                 :      14094 :       || !(statistics_dump_flags & TDF_DETAILS))
     325                 :            :     return;
     326                 :            : 
     327                 :          0 :   fprintf (statistics_dump_file,
     328                 :            :            "%d %s \"%s\" \"%s\" %d\n",
     329                 :            :            current_pass ? current_pass->static_pass_number : -1,
     330                 :          0 :            current_pass ? current_pass->name : "none",
     331                 :            :            id,
     332                 :            :            function_name (fn),
     333                 :            :            incr);
     334                 :            : }
     335                 :            : 
     336                 :            : /* Add statistics information about event ID in function FN with the
     337                 :            :    histogram value VAL.
     338                 :            :    It will dump the event to the global statistics file if requested.  */
     339                 :            : 
     340                 :            : void
     341                 :   51395300 : statistics_histogram_event (struct function *fn, const char *id, int val)
     342                 :            : {
     343                 :   51395300 :   statistics_counter *counter;
     344                 :            : 
     345                 :   51395300 :   if (!(dump_flags & TDF_STATS)
     346                 :   51395300 :       && !statistics_dump_file)
     347                 :            :     return;
     348                 :            : 
     349                 :      21279 :   counter = lookup_or_add_counter (curr_statistics_hash (), id, val, true);
     350                 :      21279 :   gcc_assert (counter->histogram_p);
     351                 :      21279 :   counter->count += 1;
     352                 :            : 
     353                 :      21279 :   if (!statistics_dump_file
     354                 :      21279 :       || !(statistics_dump_flags & TDF_DETAILS))
     355                 :            :     return;
     356                 :            : 
     357                 :          0 :   fprintf (statistics_dump_file,
     358                 :            :            "%d %s \"%s == %d\" \"%s\" 1\n",
     359                 :            :            current_pass->static_pass_number,
     360                 :            :            current_pass->name,
     361                 :            :            id, val,
     362                 :            :            function_name (fn));
     363                 :            : }

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.