LCOV - code coverage report
Current view: top level - gcc - optinfo-emit-json.cc (source / functions) Hit Total Coverage
Test: gcc.info Lines: 220 233 94.4 %
Date: 2020-04-04 11:58:09 Functions: 16 16 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Emit optimization information as JSON files.
       2                 :            :    Copyright (C) 2018-2020 Free Software Foundation, Inc.
       3                 :            :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       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                 :            : 
      25                 :            : #include "backend.h"
      26                 :            : #include "tree.h"
      27                 :            : #include "gimple.h"
      28                 :            : #include "diagnostic-core.h"
      29                 :            : 
      30                 :            : #include "profile.h"
      31                 :            : #include "output.h"
      32                 :            : #include "tree-pass.h"
      33                 :            : 
      34                 :            : #include "optinfo.h"
      35                 :            : #include "optinfo-emit-json.h"
      36                 :            : #include "json.h"
      37                 :            : #include "pretty-print.h"
      38                 :            : #include "tree-pretty-print.h"
      39                 :            : #include "gimple-pretty-print.h"
      40                 :            : #include "cgraph.h"
      41                 :            : 
      42                 :            : #include "langhooks.h"
      43                 :            : #include "version.h"
      44                 :            : #include "context.h"
      45                 :            : #include "pass_manager.h"
      46                 :            : #include "selftest.h"
      47                 :            : #include "dump-context.h"
      48                 :            : #include <zlib.h>
      49                 :            : 
      50                 :            : /* optrecord_json_writer's ctor.  Populate the top-level parts of the
      51                 :            :    in-memory JSON representation.  */
      52                 :            : 
      53                 :        692 : optrecord_json_writer::optrecord_json_writer ()
      54                 :        692 :   : m_root_tuple (NULL), m_scopes ()
      55                 :            : {
      56                 :        692 :   m_root_tuple = new json::array ();
      57                 :            : 
      58                 :            :   /* Populate with metadata; compare with toplev.c: print_version.  */
      59                 :        692 :   json::object *metadata = new json::object ();
      60                 :        692 :   m_root_tuple->append (metadata);
      61                 :        692 :   metadata->set ("format", new json::string ("1"));
      62                 :        692 :   json::object *generator = new json::object ();
      63                 :        692 :   metadata->set ("generator", generator);
      64                 :        692 :   generator->set ("name", new json::string (lang_hooks.name));
      65                 :        692 :   generator->set ("pkgversion", new json::string (pkgversion_string));
      66                 :        692 :   generator->set ("version", new json::string (version_string));
      67                 :            :   /* TARGET_NAME is passed in by the Makefile.  */
      68                 :        692 :   generator->set ("target", new json::string (TARGET_NAME));
      69                 :            : 
      70                 :            :   /* TODO: capture command-line?
      71                 :            :      see gen_producer_string in dwarf2out.c (currently static).  */
      72                 :            : 
      73                 :            :   /* TODO: capture "any plugins?" flag (or the plugins themselves).  */
      74                 :            : 
      75                 :        692 :   json::array *passes = new json::array ();
      76                 :        692 :   m_root_tuple->append (passes);
      77                 :            : 
      78                 :            :   /* Call add_pass_list for all of the pass lists.  */
      79                 :        692 :   {
      80                 :            : #define DEF_PASS_LIST(LIST) \
      81                 :            :     add_pass_list (passes, g->get_passes ()->LIST);
      82                 :        692 :     GCC_PASS_LISTS
      83                 :            : #undef DEF_PASS_LIST
      84                 :            :   }
      85                 :            : 
      86                 :        692 :   json::array *records = new json::array ();
      87                 :        692 :   m_root_tuple->append (records);
      88                 :            : 
      89                 :        692 :   m_scopes.safe_push (records);
      90                 :        692 : }
      91                 :            : 
      92                 :            : /* optrecord_json_writer's ctor.
      93                 :            :    Delete the in-memory JSON representation.  */
      94                 :            : 
      95                 :        692 : optrecord_json_writer::~optrecord_json_writer ()
      96                 :            : {
      97                 :        692 :   delete m_root_tuple;
      98                 :        692 : }
      99                 :            : 
     100                 :            : /* Choose an appropriate filename, and write the saved records to it.  */
     101                 :            : 
     102                 :            : void
     103                 :         40 : optrecord_json_writer::write () const
     104                 :            : {
     105                 :         40 :   pretty_printer pp;
     106                 :         40 :   m_root_tuple->print (&pp);
     107                 :            : 
     108                 :         40 :   bool emitted_error = false;
     109                 :         40 :   char *filename = concat (dump_base_name, ".opt-record.json.gz", NULL);
     110                 :         40 :   gzFile outfile = gzopen (filename, "w");
     111                 :         40 :   if (outfile == NULL)
     112                 :            :     {
     113                 :          0 :       error_at (UNKNOWN_LOCATION, "cannot open file %qs for writing optimization records",
     114                 :            :                 filename); // FIXME: more info?
     115                 :          0 :       goto cleanup;
     116                 :            :     }
     117                 :            : 
     118                 :         40 :   if (gzputs (outfile, pp_formatted_text (&pp)) <= 0)
     119                 :            :     {
     120                 :          0 :       int tmp;
     121                 :          0 :       error_at (UNKNOWN_LOCATION, "error writing optimization records to %qs: %s",
     122                 :            :                 filename, gzerror (outfile, &tmp));
     123                 :          0 :       emitted_error = true;
     124                 :            :     }
     125                 :            : 
     126                 :         40 :  cleanup:
     127                 :         40 :   if (outfile)
     128                 :         40 :     if (gzclose (outfile) != Z_OK)
     129                 :          0 :       if (!emitted_error)
     130                 :          0 :         error_at (UNKNOWN_LOCATION, "error closing optimization records %qs",
     131                 :            :                   filename);
     132                 :            : 
     133                 :         40 :   free (filename);
     134                 :         40 : }
     135                 :            : 
     136                 :            : /* Add a record for OPTINFO to the queue of records to be written.  */
     137                 :            : 
     138                 :            : void
     139                 :      12294 : optrecord_json_writer::add_record (const optinfo *optinfo)
     140                 :            : {
     141                 :      12294 :   json::object *obj = optinfo_to_json (optinfo);
     142                 :            : 
     143                 :      12294 :   add_record (obj);
     144                 :            : 
     145                 :            :   /* Potentially push the scope.  */
     146                 :      12294 :   if (optinfo->get_kind () == OPTINFO_KIND_SCOPE)
     147                 :            :     {
     148                 :       2505 :       json::array *children = new json::array ();
     149                 :       2505 :       obj->set ("children", children);
     150                 :       2505 :       m_scopes.safe_push (children);
     151                 :            :     }
     152                 :      12294 : }
     153                 :            : 
     154                 :            : /* Private methods of optrecord_json_writer.  */
     155                 :            : 
     156                 :            : /* Add record OBJ to the innermost scope.  */
     157                 :            : 
     158                 :            : void
     159                 :      12294 : optrecord_json_writer::add_record (json::object *obj)
     160                 :            : {
     161                 :            :   /* Add to innermost scope.  */
     162                 :      12294 :   gcc_assert (m_scopes.length () > 0);
     163                 :      12294 :   m_scopes[m_scopes.length () - 1]->append (obj);
     164                 :      12294 : }
     165                 :            : 
     166                 :            : /* Pop the innermost scope.  */
     167                 :            : 
     168                 :            : void
     169                 :       2505 : optrecord_json_writer::pop_scope ()
     170                 :            : {
     171                 :       2505 :   m_scopes.pop ();
     172                 :            : 
     173                 :            :   /* We should never pop the top-level records array.  */
     174                 :       2505 :   gcc_assert (m_scopes.length () > 0);
     175                 :       2505 : }
     176                 :            : 
     177                 :            : /* Create a JSON object representing LOC.  */
     178                 :            : 
     179                 :            : json::object *
     180                 :      12296 : optrecord_json_writer::impl_location_to_json (dump_impl_location_t loc)
     181                 :            : {
     182                 :      12296 :   json::object *obj = new json::object ();
     183                 :      12296 :   obj->set ("file", new json::string (loc.m_file));
     184                 :      12296 :   obj->set ("line", new json::integer_number (loc.m_line));
     185                 :      12296 :   if (loc.m_function)
     186                 :      12296 :     obj->set ("function", new json::string (loc.m_function));
     187                 :      12296 :   return obj;
     188                 :            : }
     189                 :            : 
     190                 :            : /* Create a JSON object representing LOC.  */
     191                 :            : 
     192                 :            : json::object *
     193                 :      12353 : optrecord_json_writer::location_to_json (location_t loc)
     194                 :            : {
     195                 :      12353 :   gcc_assert (LOCATION_LOCUS (loc) != UNKNOWN_LOCATION);
     196                 :      12353 :   expanded_location exploc = expand_location (loc);
     197                 :      12353 :   json::object *obj = new json::object ();
     198                 :      12353 :   obj->set ("file", new json::string (exploc.file));
     199                 :      12353 :   obj->set ("line", new json::integer_number (exploc.line));
     200                 :      12353 :   obj->set ("column", new json::integer_number (exploc.column));
     201                 :      12353 :   return obj;
     202                 :            : }
     203                 :            : 
     204                 :            : /* Create a JSON object representing COUNT.  */
     205                 :            : 
     206                 :            : json::object *
     207                 :      12236 : optrecord_json_writer::profile_count_to_json (profile_count count)
     208                 :            : {
     209                 :      12236 :   json::object *obj = new json::object ();
     210                 :      12236 :   obj->set ("value", new json::integer_number (count.to_gcov_type ()));
     211                 :      24472 :   obj->set ("quality",
     212                 :      12236 :             new json::string (profile_quality_as_string (count.quality ())));
     213                 :      12236 :   return obj;
     214                 :            : }
     215                 :            : 
     216                 :            : /* Get a string for use when referring to PASS in the saved optimization
     217                 :            :    records.  */
     218                 :            : 
     219                 :            : json::string *
     220                 :     248966 : optrecord_json_writer::get_id_value_for_pass (opt_pass *pass)
     221                 :            : {
     222                 :     497932 :   pretty_printer pp;
     223                 :            :   /* this is host-dependent, but will be consistent for a given host.  */
     224                 :     248966 :   pp_pointer (&pp, static_cast<void *> (pass));
     225                 :     248966 :   return new json::string (pp_formatted_text (&pp));
     226                 :            : }
     227                 :            : 
     228                 :            : /* Create a JSON object representing PASS.  */
     229                 :            : 
     230                 :            : json::object *
     231                 :     238048 : optrecord_json_writer::pass_to_json (opt_pass *pass)
     232                 :            : {
     233                 :     238048 :   json::object *obj = new json::object ();
     234                 :     238048 :   const char *type = NULL;
     235                 :     238048 :   switch (pass->type)
     236                 :            :     {
     237                 :          0 :     default:
     238                 :          0 :       gcc_unreachable ();
     239                 :            :     case GIMPLE_PASS:
     240                 :            :       type = "gimple";
     241                 :            :       break;
     242                 :      64356 :     case RTL_PASS:
     243                 :      64356 :       type = "rtl";
     244                 :      64356 :       break;
     245                 :      13148 :     case SIMPLE_IPA_PASS:
     246                 :      13148 :       type = "simple_ipa";
     247                 :      13148 :       break;
     248                 :      10380 :     case IPA_PASS:
     249                 :      10380 :       type = "ipa";
     250                 :      10380 :       break;
     251                 :            :     }
     252                 :     238048 :   obj->set ("id", get_id_value_for_pass (pass));
     253                 :     238048 :   obj->set ("type", new json::string (type));
     254                 :     238048 :   obj->set ("name", new json::string (pass->name));
     255                 :            :   /* Represent the optgroup flags as an array.  */
     256                 :     238048 :   {
     257                 :     238048 :     json::array *optgroups = new json::array ();
     258                 :     238048 :     obj->set ("optgroups", optgroups);
     259                 :    1666340 :     for (const kv_pair<optgroup_flags_t> *optgroup = optgroup_options;
     260                 :    1666340 :          optgroup->name != NULL; optgroup++)
     261                 :    1428290 :       if (optgroup->value != OPTGROUP_ALL
     262                 :    1190240 :           && (pass->optinfo_flags & optgroup->value))
     263                 :      44980 :         optgroups->append (new json::string (optgroup->name));
     264                 :            :   }
     265                 :     238048 :   obj->set ("num", new json::integer_number (pass->static_pass_number));
     266                 :     238048 :   return obj;
     267                 :            : }
     268                 :            : 
     269                 :            : /* Create a JSON array for LOC representing the chain of inlining
     270                 :            :    locations.
     271                 :            :    Compare with lhd_print_error_function and cp_print_error_function.  */
     272                 :            : 
     273                 :            : json::value *
     274                 :      10951 : optrecord_json_writer::inlining_chain_to_json (location_t loc)
     275                 :            : {
     276                 :      10951 :   json::array *array = new json::array ();
     277                 :            : 
     278                 :      10951 :   tree abstract_origin = LOCATION_BLOCK (loc);
     279                 :            : 
     280                 :      20953 :   while (abstract_origin)
     281                 :            :     {
     282                 :      10002 :       location_t *locus;
     283                 :      10002 :       tree block = abstract_origin;
     284                 :            : 
     285                 :      10002 :       locus = &BLOCK_SOURCE_LOCATION (block);
     286                 :      10002 :       tree fndecl = NULL;
     287                 :      10002 :       block = BLOCK_SUPERCONTEXT (block);
     288                 :      10464 :       while (block && TREE_CODE (block) == BLOCK
     289                 :      13065 :              && BLOCK_ABSTRACT_ORIGIN (block))
     290                 :            :         {
     291                 :        971 :           tree ao = BLOCK_ABSTRACT_ORIGIN (block);
     292                 :        971 :           if (TREE_CODE (ao) == FUNCTION_DECL)
     293                 :            :             {
     294                 :            :               fndecl = ao;
     295                 :            :               break;
     296                 :            :             }
     297                 :        462 :           else if (TREE_CODE (ao) != BLOCK)
     298                 :            :             break;
     299                 :            : 
     300                 :        462 :           block = BLOCK_SUPERCONTEXT (block);
     301                 :            :         }
     302                 :      10002 :       if (fndecl)
     303                 :            :         abstract_origin = block;
     304                 :            :       else
     305                 :            :         {
     306                 :      11608 :           while (block && TREE_CODE (block) == BLOCK)
     307                 :       2115 :             block = BLOCK_SUPERCONTEXT (block);
     308                 :            : 
     309                 :       9493 :           if (block && TREE_CODE (block) == FUNCTION_DECL)
     310                 :       9493 :             fndecl = block;
     311                 :            :           abstract_origin = NULL;
     312                 :            :         }
     313                 :      10002 :       if (fndecl)
     314                 :            :         {
     315                 :      10002 :           json::object *obj = new json::object ();
     316                 :      10002 :           const char *printable_name
     317                 :      10002 :             = lang_hooks.decl_printable_name (fndecl, 2);
     318                 :      10002 :           obj->set ("fndecl", new json::string (printable_name));
     319                 :      10002 :           if (LOCATION_LOCUS (*locus) != UNKNOWN_LOCATION)
     320                 :        509 :             obj->set ("site", location_to_json (*locus));
     321                 :      10002 :           array->append (obj);
     322                 :            :         }
     323                 :            :     }
     324                 :            : 
     325                 :      10951 :   return array;
     326                 :            : }
     327                 :            : 
     328                 :            : /* Create a JSON object representing OPTINFO.  */
     329                 :            : 
     330                 :            : json::object *
     331                 :      12296 : optrecord_json_writer::optinfo_to_json (const optinfo *optinfo)
     332                 :            : {
     333                 :      12296 :   json::object *obj = new json::object ();
     334                 :            : 
     335                 :      12296 :   obj->set ("impl_location",
     336                 :      12296 :             impl_location_to_json (optinfo->get_impl_location ()));
     337                 :            : 
     338                 :      12296 :   const char *kind_str = optinfo_kind_to_string (optinfo->get_kind ());
     339                 :      12296 :   obj->set ("kind", new json::string (kind_str));
     340                 :      12296 :   json::array *message = new json::array ();
     341                 :      12296 :   obj->set ("message", message);
     342                 :     212593 :   for (unsigned i = 0; i < optinfo->num_items (); i++)
     343                 :            :     {
     344                 :      94128 :       const optinfo_item *item = optinfo->get_item (i);
     345                 :      94128 :       switch (item->get_kind ())
     346                 :            :         {
     347                 :          0 :         default:
     348                 :          0 :           gcc_unreachable ();
     349                 :      57302 :         case OPTINFO_ITEM_KIND_TEXT:
     350                 :      57302 :           {
     351                 :      57302 :             message->append (new json::string (item->get_text ()));
     352                 :            :           }
     353                 :      57302 :           break;
     354                 :      33206 :         case OPTINFO_ITEM_KIND_TREE:
     355                 :      33206 :           {
     356                 :      33206 :             json::object *json_item = new json::object ();
     357                 :      33206 :             json_item->set ("expr", new json::string (item->get_text ()));
     358                 :            : 
     359                 :            :             /* Capture any location for the node.  */
     360                 :      33206 :             if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
     361                 :          0 :               json_item->set ("location",
     362                 :          0 :                               location_to_json (item->get_location ()));
     363                 :            : 
     364                 :      33206 :             message->append (json_item);
     365                 :            :           }
     366                 :      33206 :           break;
     367                 :       3298 :         case OPTINFO_ITEM_KIND_GIMPLE:
     368                 :       3298 :           {
     369                 :       3298 :             json::object *json_item = new json::object ();
     370                 :       3298 :             json_item->set ("stmt", new json::string (item->get_text ()));
     371                 :            : 
     372                 :            :             /* Capture any location for the stmt.  */
     373                 :       3298 :             if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
     374                 :        659 :               json_item->set ("location",
     375                 :        659 :                               location_to_json (item->get_location ()));
     376                 :            : 
     377                 :       3298 :             message->append (json_item);
     378                 :            :           }
     379                 :       3298 :           break;
     380                 :        322 :         case OPTINFO_ITEM_KIND_SYMTAB_NODE:
     381                 :        322 :           {
     382                 :        322 :             json::object *json_item = new json::object ();
     383                 :        322 :             json_item->set ("symtab_node", new json::string (item->get_text ()));
     384                 :            : 
     385                 :            :             /* Capture any location for the node.  */
     386                 :        322 :             if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
     387                 :        322 :               json_item->set ("location",
     388                 :        322 :                               location_to_json (item->get_location ()));
     389                 :        322 :             message->append (json_item);
     390                 :            :           }
     391                 :        322 :           break;
     392                 :            :         }
     393                 :            :    }
     394                 :            : 
     395                 :      12296 :   if (optinfo->get_pass ())
     396                 :      10918 :     obj->set ("pass", get_id_value_for_pass (optinfo->get_pass ()));
     397                 :            : 
     398                 :      12296 :   profile_count count = optinfo->get_count ();
     399                 :      12296 :   if (count.initialized_p ())
     400                 :      12236 :     obj->set ("count", profile_count_to_json (count));
     401                 :            : 
     402                 :            :   /* Record any location, handling the case where of an UNKNOWN_LOCATION
     403                 :            :      within an inlined block.  */
     404                 :      12296 :   location_t loc = optinfo->get_location_t ();
     405                 :      12296 :   if (get_pure_location (line_table, loc) != UNKNOWN_LOCATION)
     406                 :            :     {
     407                 :            :       // TOOD: record the location (just caret for now)
     408                 :            :       // TODO: start/finish also?
     409                 :      10863 :       obj->set ("location", location_to_json (loc));
     410                 :            :     }
     411                 :            : 
     412                 :      12296 :   if (current_function_decl)
     413                 :            :     {
     414                 :      10823 :       const char *fnname
     415                 :      10823 :         = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
     416                 :      10823 :       obj->set ("function", new json::string (fnname));
     417                 :            :     }
     418                 :            : 
     419                 :      12296 :   if (loc != UNKNOWN_LOCATION)
     420                 :      10951 :     obj->set ("inlining_chain", inlining_chain_to_json (loc));
     421                 :            : 
     422                 :      12296 :   return obj;
     423                 :            : }
     424                 :            : 
     425                 :            : /* Add a json description of PASS and its siblings to ARR, recursing into
     426                 :            :    child passes (adding their descriptions within a "children" array).  */
     427                 :            : 
     428                 :            : void
     429                 :      16608 : optrecord_json_writer::add_pass_list (json::array *arr, opt_pass *pass)
     430                 :            : {
     431                 :     238048 :   do
     432                 :            :     {
     433                 :     238048 :       json::object *pass_obj = pass_to_json (pass);
     434                 :     238048 :       arr->append (pass_obj);
     435                 :     238048 :       if (pass->sub)
     436                 :            :         {
     437                 :      13148 :           json::array *sub = new json::array ();
     438                 :      13148 :           pass_obj->set ("children", sub);
     439                 :      13148 :           add_pass_list (sub, pass->sub);
     440                 :            :         }
     441                 :     238048 :       pass = pass->next;
     442                 :            :     }
     443                 :     238048 :   while (pass);
     444                 :      16608 : }
     445                 :            : 
     446                 :            : #if CHECKING_P
     447                 :            : 
     448                 :            : namespace selftest {
     449                 :            : 
     450                 :            : /* Verify that we can build a JSON optimization record from dump_*
     451                 :            :    calls.  */
     452                 :            : 
     453                 :            : static void
     454                 :          2 : test_building_json_from_dump_calls ()
     455                 :            : {
     456                 :          4 :   temp_dump_context tmp (true, true, MSG_NOTE);
     457                 :          2 :   dump_user_location_t loc;
     458                 :          2 :   dump_printf_loc (MSG_NOTE, loc, "test of tree: ");
     459                 :          2 :   dump_generic_expr (MSG_NOTE, TDF_SLIM, integer_zero_node);
     460                 :          2 :   optinfo *info = tmp.get_pending_optinfo ();
     461                 :          2 :   ASSERT_TRUE (info != NULL);
     462                 :          2 :   ASSERT_EQ (info->num_items (), 2);
     463                 :            : 
     464                 :          4 :   optrecord_json_writer writer;
     465                 :          2 :   json::object *json_obj = writer.optinfo_to_json (info);
     466                 :          2 :   ASSERT_TRUE (json_obj != NULL);
     467                 :            : 
     468                 :            :   /* Verify that the json is sane.  */
     469                 :          4 :   pretty_printer pp;
     470                 :          2 :   json_obj->print (&pp);
     471                 :          2 :   const char *json_str = pp_formatted_text (&pp);
     472                 :          2 :   ASSERT_STR_CONTAINS (json_str, "impl_location");
     473                 :          2 :   ASSERT_STR_CONTAINS (json_str, "\"kind\": \"note\"");
     474                 :          2 :   ASSERT_STR_CONTAINS (json_str,
     475                 :            :                        "\"message\": [\"test of tree: \", {\"expr\": \"0\"}]");
     476                 :          2 :   delete json_obj;
     477                 :          2 : }
     478                 :            : 
     479                 :            : /* Run all of the selftests within this file.  */
     480                 :            : 
     481                 :            : void
     482                 :          2 : optinfo_emit_json_cc_tests ()
     483                 :            : {
     484                 :          2 :   test_building_json_from_dump_calls ();
     485                 :          2 : }
     486                 :            : 
     487                 :            : } // namespace selftest
     488                 :            : 
     489                 :            : #endif /* CHECKING_P */

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.