LCOV - code coverage report
Current view: top level - gcc - optinfo-emit-json.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.4 % 231 218
Test Date: 2024-12-21 13:15:12 Functions: 100.0 % 16 16
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-2024 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                 :        1288 : optrecord_json_writer::optrecord_json_writer ()
      54                 :        1288 :   : m_root_tuple (NULL), m_scopes ()
      55                 :             : {
      56                 :        1288 :   m_root_tuple = new json::array ();
      57                 :             : 
      58                 :             :   /* Populate with metadata; compare with toplev.cc: print_version.  */
      59                 :        1288 :   json::object *metadata = new json::object ();
      60                 :        1288 :   m_root_tuple->append (metadata);
      61                 :        1288 :   metadata->set_string ("format", "1");
      62                 :        1288 :   json::object *generator = new json::object ();
      63                 :        1288 :   metadata->set ("generator", generator);
      64                 :        1288 :   generator->set_string ("name", lang_hooks.name);
      65                 :        1288 :   generator->set_string ("pkgversion", pkgversion_string);
      66                 :        1288 :   generator->set_string ("version", version_string);
      67                 :             :   /* TARGET_NAME is passed in by the Makefile.  */
      68                 :        1288 :   generator->set_string ("target", TARGET_NAME);
      69                 :             : 
      70                 :             :   /* TODO: capture command-line?
      71                 :             :      see gen_producer_string in dwarf2out.cc (currently static).  */
      72                 :             : 
      73                 :             :   /* TODO: capture "any plugins?" flag (or the plugins themselves).  */
      74                 :             : 
      75                 :        1288 :   json::array *passes = new json::array ();
      76                 :        1288 :   m_root_tuple->append (passes);
      77                 :             : 
      78                 :             :   /* Call add_pass_list for all of the pass lists.  */
      79                 :        1288 :   {
      80                 :             : #define DEF_PASS_LIST(LIST) \
      81                 :             :     add_pass_list (passes, g->get_passes ()->LIST);
      82                 :        1288 :     GCC_PASS_LISTS
      83                 :             : #undef DEF_PASS_LIST
      84                 :             :   }
      85                 :             : 
      86                 :        1288 :   json::array *records = new json::array ();
      87                 :        1288 :   m_root_tuple->append (records);
      88                 :             : 
      89                 :        1288 :   m_scopes.safe_push (records);
      90                 :        1288 : }
      91                 :             : 
      92                 :             : /* optrecord_json_writer's ctor.
      93                 :             :    Delete the in-memory JSON representation.  */
      94                 :             : 
      95                 :        1288 : optrecord_json_writer::~optrecord_json_writer ()
      96                 :             : {
      97                 :        1288 :   delete m_root_tuple;
      98                 :        1288 : }
      99                 :             : 
     100                 :             : /* Choose an appropriate filename, and write the saved records to it.  */
     101                 :             : 
     102                 :             : void
     103                 :          41 : optrecord_json_writer::write () const
     104                 :             : {
     105                 :          41 :   pretty_printer pp;
     106                 :          41 :   m_root_tuple->print (&pp, false);
     107                 :             : 
     108                 :          41 :   bool emitted_error = false;
     109                 :          41 :   char *filename = concat (dump_base_name, ".opt-record.json.gz", NULL);
     110                 :          41 :   gzFile outfile = gzopen (filename, "w");
     111                 :          41 :   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                 :          41 :   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                 :          41 :  cleanup:
     127                 :          41 :   if (outfile)
     128                 :          41 :     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                 :          41 :   free (filename);
     134                 :          41 : }
     135                 :             : 
     136                 :             : /* Add a record for OPTINFO to the queue of records to be written.  */
     137                 :             : 
     138                 :             : void
     139                 :       49885 : optrecord_json_writer::add_record (const optinfo *optinfo)
     140                 :             : {
     141                 :       49885 :   json::object *obj = optinfo_to_json (optinfo);
     142                 :             : 
     143                 :       49885 :   add_record (obj);
     144                 :             : 
     145                 :             :   /* Potentially push the scope.  */
     146                 :       49885 :   if (optinfo->get_kind () == OPTINFO_KIND_SCOPE)
     147                 :             :     {
     148                 :        4177 :       json::array *children = new json::array ();
     149                 :        4177 :       obj->set ("children", children);
     150                 :        4177 :       m_scopes.safe_push (children);
     151                 :             :     }
     152                 :       49885 : }
     153                 :             : 
     154                 :             : /* Private methods of optrecord_json_writer.  */
     155                 :             : 
     156                 :             : /* Add record OBJ to the innermost scope.  */
     157                 :             : 
     158                 :             : void
     159                 :       49885 : optrecord_json_writer::add_record (json::object *obj)
     160                 :             : {
     161                 :             :   /* Add to innermost scope.  */
     162                 :       49885 :   gcc_assert (m_scopes.length () > 0);
     163                 :       49885 :   m_scopes[m_scopes.length () - 1]->append (obj);
     164                 :       49885 : }
     165                 :             : 
     166                 :             : /* Pop the innermost scope.  */
     167                 :             : 
     168                 :             : void
     169                 :        4177 : optrecord_json_writer::pop_scope ()
     170                 :             : {
     171                 :        4177 :   m_scopes.pop ();
     172                 :             : 
     173                 :             :   /* We should never pop the top-level records array.  */
     174                 :        4177 :   gcc_assert (m_scopes.length () > 0);
     175                 :        4177 : }
     176                 :             : 
     177                 :             : /* Create a JSON object representing LOC.  */
     178                 :             : 
     179                 :             : json::object *
     180                 :       49889 : optrecord_json_writer::impl_location_to_json (dump_impl_location_t loc)
     181                 :             : {
     182                 :       49889 :   json::object *obj = new json::object ();
     183                 :       49889 :   obj->set_string ("file", loc.m_file);
     184                 :       49889 :   obj->set_integer ("line", loc.m_line);
     185                 :       49889 :   if (loc.m_function)
     186                 :       49889 :     obj->set_string ("function", loc.m_function);
     187                 :       49889 :   return obj;
     188                 :             : }
     189                 :             : 
     190                 :             : /* Create a JSON object representing LOC.  */
     191                 :             : 
     192                 :             : json::object *
     193                 :       35387 : optrecord_json_writer::location_to_json (location_t loc)
     194                 :             : {
     195                 :       35387 :   gcc_assert (LOCATION_LOCUS (loc) != UNKNOWN_LOCATION);
     196                 :       35387 :   expanded_location exploc = expand_location (loc);
     197                 :       35387 :   json::object *obj = new json::object ();
     198                 :       35387 :   obj->set_string ("file", exploc.file);
     199                 :       35387 :   obj->set_integer ("line", exploc.line);
     200                 :       35387 :   obj->set_integer ("column", exploc.column);
     201                 :       35387 :   return obj;
     202                 :             : }
     203                 :             : 
     204                 :             : /* Create a JSON object representing COUNT.  */
     205                 :             : 
     206                 :             : json::object *
     207                 :       49829 : optrecord_json_writer::profile_count_to_json (profile_count count)
     208                 :             : {
     209                 :       49829 :   json::object *obj = new json::object ();
     210                 :       49829 :   obj->set_integer ("value", count.to_gcov_type ());
     211                 :       49829 :   obj->set_string ("quality", profile_quality_as_string (count.quality ()));
     212                 :       49829 :   return obj;
     213                 :             : }
     214                 :             : 
     215                 :             : /* Get a string for use when referring to PASS in the saved optimization
     216                 :             :    records.  */
     217                 :             : 
     218                 :             : json::string *
     219                 :      544525 : optrecord_json_writer::get_id_value_for_pass (opt_pass *pass)
     220                 :             : {
     221                 :      544525 :   pretty_printer pp;
     222                 :             :   /* this is host-dependent, but will be consistent for a given host.  */
     223                 :      544525 :   pp_pointer (&pp, static_cast<void *> (pass));
     224                 :      544525 :   return new json::string (pp_formatted_text (&pp));
     225                 :      544525 : }
     226                 :             : 
     227                 :             : /* Create a JSON object representing PASS.  */
     228                 :             : 
     229                 :             : json::object *
     230                 :      497168 : optrecord_json_writer::pass_to_json (opt_pass *pass)
     231                 :             : {
     232                 :      497168 :   json::object *obj = new json::object ();
     233                 :      497168 :   const char *type = NULL;
     234                 :      497168 :   switch (pass->type)
     235                 :             :     {
     236                 :           0 :     default:
     237                 :           0 :       gcc_unreachable ();
     238                 :             :     case GIMPLE_PASS:
     239                 :             :       type = "gimple";
     240                 :             :       break;
     241                 :      131376 :     case RTL_PASS:
     242                 :      131376 :       type = "rtl";
     243                 :      131376 :       break;
     244                 :       25760 :     case SIMPLE_IPA_PASS:
     245                 :       25760 :       type = "simple_ipa";
     246                 :       25760 :       break;
     247                 :       20608 :     case IPA_PASS:
     248                 :       20608 :       type = "ipa";
     249                 :       20608 :       break;
     250                 :             :     }
     251                 :      497168 :   obj->set ("id", get_id_value_for_pass (pass));
     252                 :      497168 :   obj->set_string ("type", type);
     253                 :      497168 :   obj->set_string ("name", pass->name);
     254                 :             :   /* Represent the optgroup flags as an array.  */
     255                 :      497168 :   {
     256                 :      497168 :     json::array *optgroups = new json::array ();
     257                 :      497168 :     obj->set ("optgroups", optgroups);
     258                 :     3480176 :     for (const kv_pair<optgroup_flags_t> *optgroup = optgroup_options;
     259                 :     3480176 :          optgroup->name != NULL; optgroup++)
     260                 :     2983008 :       if (optgroup->value != OPTGROUP_ALL
     261                 :     2485840 :           && (pass->optinfo_flags & optgroup->value))
     262                 :       91448 :         optgroups->append_string (optgroup->name);
     263                 :             :   }
     264                 :      497168 :   obj->set_integer ("num", pass->static_pass_number);
     265                 :      497168 :   return obj;
     266                 :             : }
     267                 :             : 
     268                 :             : /* Create a JSON array for LOC representing the chain of inlining
     269                 :             :    locations.
     270                 :             :    Compare with lhd_print_error_function and cp_print_error_function.  */
     271                 :             : 
     272                 :             : json::value *
     273                 :       29244 : optrecord_json_writer::inlining_chain_to_json (location_t loc)
     274                 :             : {
     275                 :       29244 :   json::array *array = new json::array ();
     276                 :             : 
     277                 :       29244 :   tree abstract_origin = LOCATION_BLOCK (loc);
     278                 :             : 
     279                 :       57112 :   while (abstract_origin)
     280                 :             :     {
     281                 :       27868 :       location_t *locus;
     282                 :       27868 :       tree block = abstract_origin;
     283                 :             : 
     284                 :       27868 :       locus = &BLOCK_SOURCE_LOCATION (block);
     285                 :       27868 :       tree fndecl = NULL;
     286                 :       27868 :       block = BLOCK_SUPERCONTEXT (block);
     287                 :       57003 :       while (block && TREE_CODE (block) == BLOCK
     288                 :       39787 :              && BLOCK_ABSTRACT_ORIGIN (block))
     289                 :             :         {
     290                 :        2591 :           tree ao = BLOCK_ABSTRACT_ORIGIN (block);
     291                 :        2591 :           if (TREE_CODE (ao) == FUNCTION_DECL)
     292                 :             :             {
     293                 :             :               fndecl = ao;
     294                 :             :               break;
     295                 :             :             }
     296                 :        1267 :           else if (TREE_CODE (ao) != BLOCK)
     297                 :             :             break;
     298                 :             : 
     299                 :        1267 :           block = BLOCK_SUPERCONTEXT (block);
     300                 :             :         }
     301                 :       27868 :       if (fndecl)
     302                 :             :         abstract_origin = block;
     303                 :             :       else
     304                 :             :         {
     305                 :       43876 :           while (block && TREE_CODE (block) == BLOCK)
     306                 :       17332 :             block = BLOCK_SUPERCONTEXT (block);
     307                 :             : 
     308                 :       26544 :           if (block && TREE_CODE (block) == FUNCTION_DECL)
     309                 :             :             fndecl = block;
     310                 :             :           abstract_origin = NULL;
     311                 :             :         }
     312                 :             :       if (fndecl)
     313                 :             :         {
     314                 :       27868 :           json::object *obj = new json::object ();
     315                 :       27868 :           const char *printable_name
     316                 :       27868 :             = lang_hooks.decl_printable_name (fndecl, 2);
     317                 :       27868 :           obj->set_string ("fndecl", printable_name);
     318                 :       27868 :           if (LOCATION_LOCUS (*locus) != UNKNOWN_LOCATION)
     319                 :        1324 :             obj->set ("site", location_to_json (*locus));
     320                 :       27868 :           array->append (obj);
     321                 :             :         }
     322                 :             :     }
     323                 :             : 
     324                 :       29244 :   return array;
     325                 :             : }
     326                 :             : 
     327                 :             : /* Create a JSON object representing OPTINFO.  */
     328                 :             : 
     329                 :             : json::object *
     330                 :       49889 : optrecord_json_writer::optinfo_to_json (const optinfo *optinfo)
     331                 :             : {
     332                 :       49889 :   json::object *obj = new json::object ();
     333                 :             : 
     334                 :       49889 :   obj->set ("impl_location",
     335                 :       49889 :             impl_location_to_json (optinfo->get_impl_location ()));
     336                 :             : 
     337                 :       49889 :   const char *kind_str = optinfo_kind_to_string (optinfo->get_kind ());
     338                 :       49889 :   obj->set_string ("kind", kind_str);
     339                 :       49889 :   json::array *message = new json::array ();
     340                 :       49889 :   obj->set ("message", message);
     341                 :      169514 :   for (unsigned i = 0; i < optinfo->num_items (); i++)
     342                 :             :     {
     343                 :      119625 :       const optinfo_item *item = optinfo->get_item (i);
     344                 :      119625 :       switch (item->get_kind ())
     345                 :             :         {
     346                 :           0 :         default:
     347                 :           0 :           gcc_unreachable ();
     348                 :       86814 :         case OPTINFO_ITEM_KIND_TEXT:
     349                 :       86814 :           {
     350                 :       86814 :             message->append_string (item->get_text ());
     351                 :             :           }
     352                 :       86814 :           break;
     353                 :       11150 :         case OPTINFO_ITEM_KIND_TREE:
     354                 :       11150 :           {
     355                 :       11150 :             json::object *json_item = new json::object ();
     356                 :       11150 :             json_item->set_string ("expr", item->get_text ());
     357                 :             : 
     358                 :             :             /* Capture any location for the node.  */
     359                 :       11150 :             if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
     360                 :           0 :               json_item->set ("location",
     361                 :           0 :                               location_to_json (item->get_location ()));
     362                 :             : 
     363                 :       11150 :             message->append (json_item);
     364                 :             :           }
     365                 :       11150 :           break;
     366                 :       21399 :         case OPTINFO_ITEM_KIND_GIMPLE:
     367                 :       21399 :           {
     368                 :       21399 :             json::object *json_item = new json::object ();
     369                 :       21399 :             json_item->set_string ("stmt", item->get_text ());
     370                 :             : 
     371                 :             :             /* Capture any location for the stmt.  */
     372                 :       21399 :             if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
     373                 :        5269 :               json_item->set ("location",
     374                 :        5269 :                               location_to_json (item->get_location ()));
     375                 :             : 
     376                 :       21399 :             message->append (json_item);
     377                 :             :           }
     378                 :       21399 :           break;
     379                 :         262 :         case OPTINFO_ITEM_KIND_SYMTAB_NODE:
     380                 :         262 :           {
     381                 :         262 :             json::object *json_item = new json::object ();
     382                 :         262 :             json_item->set_string ("symtab_node", item->get_text ());
     383                 :             : 
     384                 :             :             /* Capture any location for the node.  */
     385                 :         262 :             if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
     386                 :         262 :               json_item->set ("location",
     387                 :         262 :                               location_to_json (item->get_location ()));
     388                 :         262 :             message->append (json_item);
     389                 :             :           }
     390                 :         262 :           break;
     391                 :             :         }
     392                 :             :    }
     393                 :             : 
     394                 :       49889 :   if (optinfo->get_pass ())
     395                 :       47357 :     obj->set ("pass", get_id_value_for_pass (optinfo->get_pass ()));
     396                 :             : 
     397                 :       49889 :   profile_count count = optinfo->get_count ();
     398                 :       49889 :   if (count.initialized_p ())
     399                 :       49829 :     obj->set ("count", profile_count_to_json (count));
     400                 :             : 
     401                 :             :   /* Record any location, handling the case where of an UNKNOWN_LOCATION
     402                 :             :      within an inlined block.  */
     403                 :       49889 :   location_t loc = optinfo->get_location_t ();
     404                 :       49889 :   if (get_pure_location (line_table, loc) != UNKNOWN_LOCATION)
     405                 :             :     {
     406                 :             :       // TOOD: record the location (just caret for now)
     407                 :             :       // TODO: start/finish also?
     408                 :       28532 :       obj->set ("location", location_to_json (loc));
     409                 :             :     }
     410                 :             : 
     411                 :       49889 :   if (current_function_decl)
     412                 :             :     {
     413                 :       47275 :       const char *fnname
     414                 :       47275 :         = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
     415                 :       47275 :       obj->set_string ("function", fnname);
     416                 :             :     }
     417                 :             : 
     418                 :       49889 :   if (loc != UNKNOWN_LOCATION)
     419                 :       29244 :     obj->set ("inlining_chain", inlining_chain_to_json (loc));
     420                 :             : 
     421                 :       49889 :   return obj;
     422                 :             : }
     423                 :             : 
     424                 :             : /* Add a json description of PASS and its siblings to ARR, recursing into
     425                 :             :    child passes (adding their descriptions within a "children" array).  */
     426                 :             : 
     427                 :             : void
     428                 :       32200 : optrecord_json_writer::add_pass_list (json::array *arr, opt_pass *pass)
     429                 :             : {
     430                 :      497168 :   do
     431                 :             :     {
     432                 :      497168 :       json::object *pass_obj = pass_to_json (pass);
     433                 :      497168 :       arr->append (pass_obj);
     434                 :      497168 :       if (pass->sub)
     435                 :             :         {
     436                 :       25760 :           json::array *sub = new json::array ();
     437                 :       25760 :           pass_obj->set ("children", sub);
     438                 :       25760 :           add_pass_list (sub, pass->sub);
     439                 :             :         }
     440                 :      497168 :       pass = pass->next;
     441                 :             :     }
     442                 :      497168 :   while (pass);
     443                 :       32200 : }
     444                 :             : 
     445                 :             : #if CHECKING_P
     446                 :             : 
     447                 :             : namespace selftest {
     448                 :             : 
     449                 :             : /* Verify that we can build a JSON optimization record from dump_*
     450                 :             :    calls.  */
     451                 :             : 
     452                 :             : static void
     453                 :           4 : test_building_json_from_dump_calls ()
     454                 :             : {
     455                 :           4 :   temp_dump_context tmp (true, true, MSG_NOTE);
     456                 :           4 :   dump_user_location_t loc;
     457                 :           4 :   dump_printf_loc (MSG_NOTE, loc, "test of tree: ");
     458                 :           4 :   dump_generic_expr (MSG_NOTE, TDF_SLIM, integer_zero_node);
     459                 :           4 :   optinfo *info = tmp.get_pending_optinfo ();
     460                 :           4 :   ASSERT_TRUE (info != NULL);
     461                 :           4 :   ASSERT_EQ (info->num_items (), 2);
     462                 :             : 
     463                 :           4 :   optrecord_json_writer writer;
     464                 :           4 :   json::object *json_obj = writer.optinfo_to_json (info);
     465                 :           4 :   ASSERT_TRUE (json_obj != NULL);
     466                 :             : 
     467                 :             :   /* Verify that the json is sane.  */
     468                 :           4 :   pretty_printer pp;
     469                 :           4 :   json_obj->print (&pp, false);
     470                 :           4 :   const char *json_str = pp_formatted_text (&pp);
     471                 :           4 :   ASSERT_STR_CONTAINS (json_str, "impl_location");
     472                 :           4 :   ASSERT_STR_CONTAINS (json_str, "\"kind\": \"note\"");
     473                 :           4 :   ASSERT_STR_CONTAINS (json_str,
     474                 :             :                        "\"message\": [\"test of tree: \", {\"expr\": \"0\"}]");
     475                 :           4 :   delete json_obj;
     476                 :           4 : }
     477                 :             : 
     478                 :             : /* Run all of the selftests within this file.  */
     479                 :             : 
     480                 :             : void
     481                 :           4 : optinfo_emit_json_cc_tests ()
     482                 :             : {
     483                 :           4 :   test_building_json_from_dump_calls ();
     484                 :           4 : }
     485                 :             : 
     486                 :             : } // namespace selftest
     487                 :             : 
     488                 :             : #endif /* CHECKING_P */
        

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.