LCOV - code coverage report
Current view: top level - gcc - dumpfile.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.3 % 1195 1115
Test Date: 2025-06-21 16:26:05 Functions: 88.3 % 120 106
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Dump infrastructure for optimizations and intermediate representation.
       2                 :             :    Copyright (C) 2012-2025 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : #include "config.h"
      21                 :             : #include "system.h"
      22                 :             : #include "coretypes.h"
      23                 :             : #include "options.h"
      24                 :             : #include "tree.h"
      25                 :             : #include "gimple-pretty-print.h"
      26                 :             : #include "diagnostic-core.h"
      27                 :             : #include "dumpfile.h"
      28                 :             : #include "context.h"
      29                 :             : #include "profile-count.h"
      30                 :             : #include "tree-cfg.h"
      31                 :             : #include "langhooks.h"
      32                 :             : #include "backend.h" /* for gimple.h.  */
      33                 :             : #include "gimple.h" /* for dump_user_location_t ctor.  */
      34                 :             : #include "rtl.h" /* for dump_user_location_t ctor.  */
      35                 :             : #include "selftest.h"
      36                 :             : #include "optinfo.h"
      37                 :             : #include "dump-context.h"
      38                 :             : #include "cgraph.h"
      39                 :             : #include "tree-pass.h" /* for "current_pass".  */
      40                 :             : #include "optinfo-emit-json.h"
      41                 :             : #include "stringpool.h" /* for get_identifier.  */
      42                 :             : #include "spellcheck.h"
      43                 :             : #include "pretty-print-format-impl.h"
      44                 :             : 
      45                 :             : /* If non-NULL, return one past-the-end of the matching SUBPART of
      46                 :             :    the WHOLE string.  */
      47                 :             : #define skip_leading_substring(whole,  part) \
      48                 :             :    (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
      49                 :             : 
      50                 :             : static dump_flags_t pflags;                   /* current dump_flags */
      51                 :             : 
      52                 :             : static void dump_loc (dump_flags_t, FILE *, location_t);
      53                 :             : 
      54                 :             : /* Current -fopt-info output stream, if any, and flags.  */
      55                 :             : static FILE *alt_dump_file = NULL;
      56                 :             : static dump_flags_t alt_flags;
      57                 :             : 
      58                 :             : static FILE *dump_open_alternate_stream (struct dump_file_info *);
      59                 :             : 
      60                 :             : /* These are currently used for communicating between passes.
      61                 :             :    However, instead of accessing them directly, the passes can use
      62                 :             :    dump_printf () for dumps.  */
      63                 :             : FILE *dump_file = NULL;
      64                 :             : const char *dump_file_name;
      65                 :             : dump_flags_t dump_flags;
      66                 :             : bool dumps_are_enabled = false;
      67                 :             : 
      68                 :             : 
      69                 :             : /* Set global "dump_file" to NEW_DUMP_FILE, refreshing the "dumps_are_enabled"
      70                 :             :    global.  */
      71                 :             : 
      72                 :             : void
      73                 :   289543739 : set_dump_file (FILE *new_dump_file)
      74                 :             : {
      75                 :   289543739 :   dumpfile_ensure_any_optinfo_are_flushed ();
      76                 :   289543739 :   dump_file = new_dump_file;
      77                 :   289543739 :   dump_context::get ().refresh_dumps_are_enabled ();
      78                 :   289543739 : }
      79                 :             : 
      80                 :             : /* Set "alt_dump_file" to NEW_ALT_DUMP_FILE, refreshing the "dumps_are_enabled"
      81                 :             :    global.  */
      82                 :             : 
      83                 :             : static void
      84                 :   288532684 : set_alt_dump_file (FILE *new_alt_dump_file)
      85                 :             : {
      86                 :   288532684 :   dumpfile_ensure_any_optinfo_are_flushed ();
      87                 :   288532684 :   alt_dump_file = new_alt_dump_file;
      88                 :   288532684 :   dump_context::get ().refresh_dumps_are_enabled ();
      89                 :   288532684 : }
      90                 :             : 
      91                 :             : #define DUMP_FILE_INFO(suffix, swtch, dkind, num) \
      92                 :             :   {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, TDF_NONE, TDF_NONE, \
      93                 :             :    OPTGROUP_NONE, 0, 0, num, false, false}
      94                 :             : 
      95                 :             : /* Table of tree dump switches. This must be consistent with the
      96                 :             :    TREE_DUMP_INDEX enumeration in dumpfile.h.  */
      97                 :             : static struct dump_file_info dump_files[TDI_end] =
      98                 :             : {
      99                 :             :   DUMP_FILE_INFO (NULL, NULL, DK_none, 0),
     100                 :             :   DUMP_FILE_INFO (".cgraph", "ipa-cgraph", DK_ipa, 0),
     101                 :             :   DUMP_FILE_INFO (".type-inheritance", "ipa-type-inheritance", DK_ipa, 0),
     102                 :             :   DUMP_FILE_INFO (".ipa-clones", "ipa-clones", DK_ipa, 0),
     103                 :             :   DUMP_FILE_INFO (".original", "tree-original", DK_tree, 0),
     104                 :             :   DUMP_FILE_INFO (".gimple", "tree-gimple", DK_tree, 0),
     105                 :             :   DUMP_FILE_INFO (".nested", "tree-nested", DK_tree, 0),
     106                 :             :   DUMP_FILE_INFO (".lto-stream-out", "ipa-lto-stream-out", DK_ipa, 0),
     107                 :             :   DUMP_FILE_INFO (".profile-report", "profile-report", DK_ipa, 0),
     108                 :             : #define FIRST_AUTO_NUMBERED_DUMP 1
     109                 :             : #define FIRST_ME_AUTO_NUMBERED_DUMP 6
     110                 :             : 
     111                 :             :   DUMP_FILE_INFO (NULL, "lang-all", DK_lang, 0),
     112                 :             :   DUMP_FILE_INFO (NULL, "tree-all", DK_tree, 0),
     113                 :             :   DUMP_FILE_INFO (NULL, "rtl-all", DK_rtl, 0),
     114                 :             :   DUMP_FILE_INFO (NULL, "ipa-all", DK_ipa, 0),
     115                 :             : };
     116                 :             : 
     117                 :             : /* Table of dump options. This must be consistent with the TDF_* flags
     118                 :             :    in dumpfile.h and opt_info_options below. */
     119                 :             : static const kv_pair<dump_flags_t> dump_options[] =
     120                 :             : {
     121                 :             :   {"none", TDF_NONE},
     122                 :             :   {"address", TDF_ADDRESS},
     123                 :             :   {"asmname", TDF_ASMNAME},
     124                 :             :   {"slim", TDF_SLIM},
     125                 :             :   {"raw", TDF_RAW},
     126                 :             :   {"graph", TDF_GRAPH},
     127                 :             :   {"details", (TDF_DETAILS | MSG_OPTIMIZED_LOCATIONS
     128                 :             :                | MSG_MISSED_OPTIMIZATION
     129                 :             :                | MSG_NOTE)},
     130                 :             :   {"cselib", TDF_CSELIB},
     131                 :             :   {"stats", TDF_STATS},
     132                 :             :   {"blocks", TDF_BLOCKS},
     133                 :             :   {"vops", TDF_VOPS},
     134                 :             :   {"lineno", TDF_LINENO},
     135                 :             :   {"uid", TDF_UID},
     136                 :             :   {"stmtaddr", TDF_STMTADDR},
     137                 :             :   {"memsyms", TDF_MEMSYMS},
     138                 :             :   {"eh", TDF_EH},
     139                 :             :   {"alias", TDF_ALIAS},
     140                 :             :   {"nouid", TDF_NOUID},
     141                 :             :   {"enumerate_locals", TDF_ENUMERATE_LOCALS},
     142                 :             :   {"scev", TDF_SCEV},
     143                 :             :   {"gimple", TDF_GIMPLE},
     144                 :             :   {"folding", TDF_FOLDING},
     145                 :             :   {"optimized", MSG_OPTIMIZED_LOCATIONS},
     146                 :             :   {"missed", MSG_MISSED_OPTIMIZATION},
     147                 :             :   {"note", MSG_NOTE},
     148                 :             :   {"optall", MSG_ALL_KINDS},
     149                 :             :   {"all", dump_flags_t (TDF_ALL_VALUES
     150                 :             :                         & ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_GRAPH
     151                 :             :                             | TDF_STMTADDR | TDF_RHS_ONLY | TDF_NOUID
     152                 :             :                             | TDF_ENUMERATE_LOCALS | TDF_SCEV | TDF_GIMPLE))},
     153                 :             :   {NULL, TDF_NONE}
     154                 :             : };
     155                 :             : 
     156                 :             : /* A subset of the dump_options table which is used for -fopt-info
     157                 :             :    types. This must be consistent with the MSG_* flags in dumpfile.h.
     158                 :             :  */
     159                 :             : static const kv_pair<dump_flags_t> optinfo_verbosity_options[] =
     160                 :             : {
     161                 :             :   {"optimized", MSG_OPTIMIZED_LOCATIONS},
     162                 :             :   {"missed", MSG_MISSED_OPTIMIZATION},
     163                 :             :   {"note", MSG_NOTE},
     164                 :             :   {"all", MSG_ALL_KINDS},
     165                 :             :   {"internals", MSG_PRIORITY_INTERNALS},
     166                 :             :   {NULL, TDF_NONE}
     167                 :             : };
     168                 :             : 
     169                 :             : /* Flags used for -fopt-info groups.  */
     170                 :             : const kv_pair<optgroup_flags_t> optgroup_options[] =
     171                 :             : {
     172                 :             :   {"ipa", OPTGROUP_IPA},
     173                 :             :   {"loop", OPTGROUP_LOOP},
     174                 :             :   {"inline", OPTGROUP_INLINE},
     175                 :             :   {"omp", OPTGROUP_OMP},
     176                 :             :   {"vec", OPTGROUP_VEC},
     177                 :             :   {"optall", OPTGROUP_ALL},
     178                 :             :   {NULL, OPTGROUP_NONE}
     179                 :             : };
     180                 :             : 
     181                 :      285081 : gcc::dump_manager::dump_manager ():
     182                 :      285081 :   m_next_dump (FIRST_AUTO_NUMBERED_DUMP),
     183                 :      285081 :   m_extra_dump_files (NULL),
     184                 :      285081 :   m_extra_dump_files_in_use (0),
     185                 :      285081 :   m_extra_dump_files_alloced (0),
     186                 :      285081 :   m_optgroup_flags (OPTGROUP_NONE),
     187                 :      285081 :   m_optinfo_flags (TDF_NONE),
     188                 :      285081 :   m_optinfo_filename (NULL)
     189                 :             : {
     190                 :      285081 : }
     191                 :             : 
     192                 :      256374 : gcc::dump_manager::~dump_manager ()
     193                 :             : {
     194                 :      256374 :   free (m_optinfo_filename);
     195                 :    93511049 :   for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
     196                 :             :     {
     197                 :    93254675 :       dump_file_info *dfi = &m_extra_dump_files[i];
     198                 :             :       /* suffix, swtch, glob are statically allocated for the entries
     199                 :             :          in dump_files, and for statistics, but are dynamically allocated
     200                 :             :          for those for passes.  */
     201                 :    93254675 :       if (dfi->owns_strings)
     202                 :             :         {
     203                 :    92038322 :           XDELETEVEC (const_cast <char *> (dfi->suffix));
     204                 :    92038322 :           XDELETEVEC (const_cast <char *> (dfi->swtch));
     205                 :    92038322 :           XDELETEVEC (const_cast <char *> (dfi->glob));
     206                 :             :         }
     207                 :             :       /* These, if non-NULL, are always dynamically allocated.  */
     208                 :    93254675 :       XDELETEVEC (const_cast <char *> (dfi->pfilename));
     209                 :    93254675 :       XDELETEVEC (const_cast <char *> (dfi->alt_filename));
     210                 :             :     }
     211                 :      256374 :   XDELETEVEC (m_extra_dump_files);
     212                 :      256374 : }
     213                 :             : 
     214                 :             : unsigned int
     215                 :   103740759 : gcc::dump_manager::
     216                 :             : dump_register (const char *suffix, const char *swtch, const char *glob,
     217                 :             :                dump_kind dkind, optgroup_flags_t optgroup_flags,
     218                 :             :                bool take_ownership)
     219                 :             : {
     220                 :   103740759 :   int num = m_next_dump++;
     221                 :             : 
     222                 :   103740759 :   size_t count = m_extra_dump_files_in_use++;
     223                 :             : 
     224                 :   103740759 :   if (count >= m_extra_dump_files_alloced)
     225                 :             :     {
     226                 :      285081 :       if (m_extra_dump_files_alloced == 0)
     227                 :      285081 :         m_extra_dump_files_alloced = 512;
     228                 :             :       else
     229                 :           0 :         m_extra_dump_files_alloced *= 2;
     230                 :      285081 :       m_extra_dump_files = XRESIZEVEC (struct dump_file_info,
     231                 :             :                                        m_extra_dump_files,
     232                 :             :                                        m_extra_dump_files_alloced);
     233                 :             : 
     234                 :             :       /* Construct a new object in the space allocated above.  */
     235                 :      285081 :       new (m_extra_dump_files + count) dump_file_info ();
     236                 :             :     }
     237                 :             :   else
     238                 :             :     {
     239                 :             :       /* Zero out the already constructed object.  */
     240                 :   103455678 :       m_extra_dump_files[count] = dump_file_info ();
     241                 :             :     }
     242                 :             : 
     243                 :   103740759 :   m_extra_dump_files[count].suffix = suffix;
     244                 :   103740759 :   m_extra_dump_files[count].swtch = swtch;
     245                 :   103740759 :   m_extra_dump_files[count].glob = glob;
     246                 :   103740759 :   m_extra_dump_files[count].dkind = dkind;
     247                 :   103740759 :   m_extra_dump_files[count].optgroup_flags = optgroup_flags;
     248                 :   103740759 :   m_extra_dump_files[count].num = num;
     249                 :   103740759 :   m_extra_dump_files[count].owns_strings = take_ownership;
     250                 :             : 
     251                 :   103740759 :   return count + TDI_end;
     252                 :             : }
     253                 :             : 
     254                 :             : 
     255                 :             : /* Allow languages and middle-end to register their dumps before the
     256                 :             :    optimization passes.  */
     257                 :             : 
     258                 :             : void
     259                 :      285081 : gcc::dump_manager::
     260                 :             : register_dumps ()
     261                 :             : {
     262                 :      285081 :   lang_hooks.register_dumps (this);
     263                 :             :   /* If this assert fails, some FE registered more than
     264                 :             :      FIRST_ME_AUTO_NUMBERED_DUMP - FIRST_AUTO_NUMBERED_DUMP
     265                 :             :      dump files.  Bump FIRST_ME_AUTO_NUMBERED_DUMP accordingly.  */
     266                 :      285081 :   gcc_assert (m_next_dump <= FIRST_ME_AUTO_NUMBERED_DUMP);
     267                 :      285081 :   m_next_dump = FIRST_ME_AUTO_NUMBERED_DUMP;
     268                 :      285081 :   dump_files[TDI_original].num = m_next_dump++;
     269                 :      285081 :   dump_files[TDI_gimple].num = m_next_dump++;
     270                 :      285081 :   dump_files[TDI_nested].num = m_next_dump++;
     271                 :      285081 : }
     272                 :             : 
     273                 :             : 
     274                 :             : /* Return the dump_file_info for the given phase.  */
     275                 :             : 
     276                 :             : struct dump_file_info *
     277                 :  1989779053 : gcc::dump_manager::
     278                 :             : get_dump_file_info (int phase) const
     279                 :             : {
     280                 :  1989779053 :   if (phase < TDI_end)
     281                 :    96995062 :     return &dump_files[phase];
     282                 :  1892783991 :   else if ((size_t) (phase - TDI_end) >= m_extra_dump_files_in_use)
     283                 :             :     return NULL;
     284                 :             :   else
     285                 :  1892507078 :     return m_extra_dump_files + (phase - TDI_end);
     286                 :             : }
     287                 :             : 
     288                 :             : /* Locate the dump_file_info with swtch equal to SWTCH,
     289                 :             :    or return NULL if no such dump_file_info exists.  */
     290                 :             : 
     291                 :             : struct dump_file_info *
     292                 :          50 : gcc::dump_manager::
     293                 :             : get_dump_file_info_by_switch (const char *swtch) const
     294                 :             : {
     295                 :       11835 :   for (unsigned i = 0; i < m_extra_dump_files_in_use; i++)
     296                 :       11830 :     if (strcmp (m_extra_dump_files[i].swtch, swtch) == 0)
     297                 :             :       return &m_extra_dump_files[i];
     298                 :             : 
     299                 :             :   /* Not found.  */
     300                 :             :   return NULL;
     301                 :             : }
     302                 :             : 
     303                 :             : 
     304                 :             : /* Return the name of the dump file for the given phase.
     305                 :             :    The caller is responsible for calling free on the returned
     306                 :             :    buffer.
     307                 :             :    If the dump is not enabled, returns NULL.  */
     308                 :             : 
     309                 :             : char *
     310                 :   288143928 : gcc::dump_manager::
     311                 :             : get_dump_file_name (int phase, int part) const
     312                 :             : {
     313                 :   288143928 :   struct dump_file_info *dfi;
     314                 :             : 
     315                 :   288143928 :   if (phase == TDI_none)
     316                 :             :     return NULL;
     317                 :             : 
     318                 :   280342713 :   dfi = get_dump_file_info (phase);
     319                 :             : 
     320                 :   280342713 :   return get_dump_file_name (dfi, part);
     321                 :             : }
     322                 :             : 
     323                 :             : /* Return the name of the dump file for the given dump_file_info.
     324                 :             :    The caller is responsible for calling free on the returned
     325                 :             :    buffer.
     326                 :             :    If the dump is not enabled, returns NULL.  */
     327                 :             : 
     328                 :             : char *
     329                 :   280342918 : gcc::dump_manager::
     330                 :             : get_dump_file_name (struct dump_file_info *dfi, int part) const
     331                 :             : {
     332                 :   280342918 :   char dump_id[10];
     333                 :             : 
     334                 :   280342918 :   gcc_assert (dfi);
     335                 :             : 
     336                 :   280342918 :   if (dfi->pstate == 0)
     337                 :             :     return NULL;
     338                 :             : 
     339                 :             :   /* If available, use the command line dump filename. */
     340                 :      120591 :   if (dfi->pfilename)
     341                 :           4 :     return xstrdup (dfi->pfilename);
     342                 :             : 
     343                 :      120587 :   if (dfi->num < 0)
     344                 :           0 :     dump_id[0] = '\0';
     345                 :             :   else
     346                 :             :     {
     347                 :             :       /* (null), LANG, TREE, RTL, IPA.  */
     348                 :      120587 :       char suffix = " ltri"[dfi->dkind];
     349                 :             : 
     350                 :      120587 :       if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
     351                 :           0 :         dump_id[0] = '\0';
     352                 :             :     }
     353                 :             : 
     354                 :      120587 :   if (part != -1)
     355                 :             :     {
     356                 :           0 :        char part_id[8];
     357                 :           0 :        snprintf (part_id, sizeof (part_id), ".%i", part);
     358                 :           0 :        return concat (dump_base_name, dump_id, part_id, dfi->suffix, NULL);
     359                 :             :     }
     360                 :             :   else
     361                 :      120587 :     return concat (dump_base_name, dump_id, dfi->suffix, NULL);
     362                 :             : }
     363                 :             : 
     364                 :             : /* Open a dump file called FILENAME.  Some filenames are special and
     365                 :             :    refer to the standard streams.  TRUNC indicates whether this is the
     366                 :             :    first open (so the file should be truncated, rather than appended).
     367                 :             :    An error message is emitted in the event of failure.  */
     368                 :             : 
     369                 :             : static FILE *
     370                 :       84154 : dump_open (const char *filename, bool trunc)
     371                 :             : {
     372                 :       84154 :   if (strcmp ("stderr", filename) == 0)
     373                 :       15704 :     return stderr;
     374                 :             : 
     375                 :       68450 :   if (strcmp ("stdout", filename) == 0
     376                 :       68450 :       || strcmp ("-", filename) == 0)
     377                 :           0 :     return stdout;
     378                 :             : 
     379                 :      112175 :   FILE *stream = fopen (filename, trunc ? "w" : "a");
     380                 :             : 
     381                 :       68450 :   if (!stream)
     382                 :           0 :     error ("could not open dump file %qs: %m", filename);
     383                 :             :   return stream;
     384                 :             : }
     385                 :             : 
     386                 :             : /* For a given DFI, open an alternate dump filename (which could also
     387                 :             :    be a standard stream such as stdout/stderr). If the alternate dump
     388                 :             :    file cannot be opened, return NULL.  */
     389                 :             : 
     390                 :             : static FILE *
     391                 :       68118 : dump_open_alternate_stream (struct dump_file_info *dfi)
     392                 :             : {
     393                 :       68118 :   if (!dfi->alt_filename)
     394                 :             :     return NULL;
     395                 :             : 
     396                 :       15702 :   if (dfi->alt_stream)
     397                 :             :     return dfi->alt_stream;
     398                 :             : 
     399                 :       15702 :   FILE *stream = dump_open (dfi->alt_filename, dfi->alt_state < 0);
     400                 :             : 
     401                 :       15702 :   if (stream)
     402                 :       15702 :     dfi->alt_state = 1;
     403                 :             : 
     404                 :             :   return stream;
     405                 :             : }
     406                 :             : 
     407                 :             : /* Construct a dump_user_location_t from STMT (using its location and
     408                 :             :    hotness).  */
     409                 :             : 
     410                 :    43591389 : dump_user_location_t::dump_user_location_t (const gimple *stmt)
     411                 :    43591389 : : m_count (), m_loc (UNKNOWN_LOCATION)
     412                 :             : {
     413                 :    43591389 :   if (stmt)
     414                 :             :     {
     415                 :    43591360 :       if (stmt->bb)
     416                 :    43584760 :         m_count = stmt->bb->count;
     417                 :    43591360 :       m_loc = gimple_location (stmt);
     418                 :             :     }
     419                 :    43591389 : }
     420                 :             : 
     421                 :             : /* Construct a dump_user_location_t from an RTL instruction (using its
     422                 :             :    location and hotness).  */
     423                 :             : 
     424                 :      567273 : dump_user_location_t::dump_user_location_t (const rtx_insn *insn)
     425                 :      567273 : : m_count (), m_loc (UNKNOWN_LOCATION)
     426                 :             : {
     427                 :      567273 :   if (insn)
     428                 :             :     {
     429                 :      567269 :       basic_block bb = BLOCK_FOR_INSN (insn);
     430                 :      567269 :       if (bb)
     431                 :      567269 :         m_count = bb->count;
     432                 :      567269 :       m_loc = INSN_LOCATION (insn);
     433                 :             :     }
     434                 :      567273 : }
     435                 :             : 
     436                 :             : /* Construct from a function declaration.  This one requires spelling out
     437                 :             :    to avoid accidentally constructing from other kinds of tree.  */
     438                 :             : 
     439                 :             : dump_user_location_t
     440                 :     1047466 : dump_user_location_t::from_function_decl (tree fndecl)
     441                 :             : {
     442                 :     1047466 :   gcc_assert (fndecl);
     443                 :             : 
     444                 :             :   // FIXME: profile count for function?
     445                 :     1047466 :   return dump_user_location_t (profile_count (),
     446                 :     1047466 :                                DECL_SOURCE_LOCATION (fndecl));
     447                 :             : }
     448                 :             : 
     449                 :             : /* Extract the MSG_* component from DUMP_KIND and return a string for use
     450                 :             :    as a prefix to dump messages.
     451                 :             :    These match the strings in optinfo_verbosity_options and thus the
     452                 :             :    "OPTIONS" within "-fopt-info-OPTIONS".  */
     453                 :             : 
     454                 :             : static const char *
     455                 :     8369211 : kind_as_string (dump_flags_t dump_kind)
     456                 :             : {
     457                 :     8369211 :   switch (dump_kind & MSG_ALL_KINDS)
     458                 :             :     {
     459                 :           0 :     default:
     460                 :           0 :       gcc_unreachable ();
     461                 :             :     case MSG_OPTIMIZED_LOCATIONS:
     462                 :             :       return "optimized";
     463                 :      157246 :     case MSG_MISSED_OPTIMIZATION:
     464                 :      157246 :       return "missed";
     465                 :     8197427 :     case MSG_NOTE:
     466                 :     8197427 :       return "note";
     467                 :             :     }
     468                 :             : }
     469                 :             : 
     470                 :             : /* Print source location on DFILE if enabled.  */
     471                 :             : 
     472                 :             : static void
     473                 :     8366747 : dump_loc (dump_flags_t dump_kind, FILE *dfile, location_t loc)
     474                 :             : {
     475                 :     8366747 :   if (dump_kind)
     476                 :             :     {
     477                 :     8366747 :       if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
     478                 :     8301477 :         fprintf (dfile, "%s:%d:%d: ", LOCATION_FILE (loc),
     479                 :    16602954 :                  LOCATION_LINE (loc), LOCATION_COLUMN (loc));
     480                 :       65270 :       else if (current_function_decl)
     481                 :       65257 :         fprintf (dfile, "%s:%d:%d: ",
     482                 :       65257 :                  DECL_SOURCE_FILE (current_function_decl),
     483                 :       65257 :                  DECL_SOURCE_LINE (current_function_decl),
     484                 :      130514 :                  DECL_SOURCE_COLUMN (current_function_decl));
     485                 :     8366747 :       fprintf (dfile, "%s: ", kind_as_string (dump_kind));
     486                 :             :       /* Indentation based on scope depth.  */
     487                 :     8366747 :       fprintf (dfile, "%*s", get_dump_scope_depth (), "");
     488                 :             :     }
     489                 :     8366747 : }
     490                 :             : 
     491                 :             : /* Print source location to PP if enabled.  */
     492                 :             : 
     493                 :             : static void
     494                 :        2464 : dump_loc (dump_flags_t dump_kind, pretty_printer *pp, location_t loc)
     495                 :             : {
     496                 :             :   /* Disable warnings about missing quoting in GCC diagnostics for
     497                 :             :      the pp_printf calls.  Their format strings aren't used to format
     498                 :             :      diagnostics so don't need to follow GCC diagnostic conventions.  */
     499                 :             : #if __GNUC__ >= 10
     500                 :        2464 : #  pragma GCC diagnostic push
     501                 :        2464 : #  pragma GCC diagnostic ignored "-Wformat-diag"
     502                 :             : #endif
     503                 :             : 
     504                 :        2464 :   if (dump_kind)
     505                 :             :     {
     506                 :        2464 :       if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
     507                 :        2464 :         pp_printf (pp, "%s:%d:%d: ", LOCATION_FILE (loc),
     508                 :        4928 :                    LOCATION_LINE (loc), LOCATION_COLUMN (loc));
     509                 :           0 :       else if (current_function_decl)
     510                 :           0 :         pp_printf (pp, "%s:%d:%d: ",
     511                 :           0 :                    DECL_SOURCE_FILE (current_function_decl),
     512                 :           0 :                    DECL_SOURCE_LINE (current_function_decl),
     513                 :           0 :                    DECL_SOURCE_COLUMN (current_function_decl));
     514                 :        2464 :       pp_printf (pp, "%s: ", kind_as_string (dump_kind));
     515                 :             :       /* Indentation based on scope depth.  */
     516                 :        5068 :       for (unsigned i = 0; i < get_dump_scope_depth (); i++)
     517                 :        2604 :         pp_character (pp, ' ');
     518                 :             :     }
     519                 :             : 
     520                 :             : #if __GNUC__ >= 10
     521                 :        2464 : #  pragma GCC diagnostic pop
     522                 :             : #endif
     523                 :        2464 : }
     524                 :             : 
     525                 :             : /* Implementation of dump_context member functions.  */
     526                 :             : 
     527                 :             : /* dump_context's dtor.  */
     528                 :             : 
     529                 :      286442 : dump_context::~dump_context ()
     530                 :             : {
     531                 :      286442 :   delete m_pending;
     532                 :      286442 : }
     533                 :             : 
     534                 :             : void
     535                 :        3706 : dump_context::set_json_writer (optrecord_json_writer *writer)
     536                 :             : {
     537                 :        3706 :   delete m_json_writer;
     538                 :        3706 :   m_json_writer = writer;
     539                 :        3706 : }
     540                 :             : 
     541                 :             : /* Perform cleanup activity for -fsave-optimization-record.
     542                 :             :    Currently, the file is written out here in one go, before cleaning
     543                 :             :    up.  */
     544                 :             : 
     545                 :             : void
     546                 :      267532 : dump_context::finish_any_json_writer ()
     547                 :             : {
     548                 :      267532 :   if (!m_json_writer)
     549                 :             :     return;
     550                 :             : 
     551                 :          41 :   m_json_writer->write ();
     552                 :          41 :   delete m_json_writer;
     553                 :          41 :   m_json_writer = NULL;
     554                 :             : }
     555                 :             : 
     556                 :             : /* Update the "dumps_are_enabled" global; to be called whenever dump_file
     557                 :             :    or alt_dump_file change, or when changing dump_context in selftests.  */
     558                 :             : 
     559                 :             : void
     560                 :   578081267 : dump_context::refresh_dumps_are_enabled ()
     561                 :             : {
     562                 :   578028369 :   dumps_are_enabled = (dump_file || alt_dump_file || optinfo_enabled_p ()
     563                 :  1156006311 :                        || m_test_pp);
     564                 :   578081267 : }
     565                 :             : 
     566                 :             : /* Determine if a message of kind DUMP_KIND and at the current scope depth
     567                 :             :    should be printed.
     568                 :             : 
     569                 :             :    Only show messages that match FILTER both on their kind *and*
     570                 :             :    their priority.  */
     571                 :             : 
     572                 :             : bool
     573                 :    28606172 : dump_context::apply_dump_filter_p (dump_flags_t dump_kind,
     574                 :             :                                    dump_flags_t filter) const
     575                 :             : {
     576                 :             :   /* Few messages, if any, have an explicit MSG_PRIORITY.
     577                 :             :      If DUMP_KIND does, we'll use it.
     578                 :             :      Otherwise, generate an implicit priority value for the message based
     579                 :             :      on the current scope depth.
     580                 :             :      Messages at the top-level scope are MSG_PRIORITY_USER_FACING,
     581                 :             :      whereas those in nested scopes are MSG_PRIORITY_INTERNALS.  */
     582                 :    28606172 :   if (!(dump_kind & MSG_ALL_PRIORITIES))
     583                 :             :     {
     584                 :      489942 :       dump_flags_t implicit_priority
     585                 :    28566237 :         =  (m_scope_depth > 0
     586                 :    28566237 :             ? MSG_PRIORITY_INTERNALS
     587                 :             :             : MSG_PRIORITY_USER_FACING);
     588                 :    28566237 :       dump_kind |= implicit_priority;
     589                 :             :     }
     590                 :             : 
     591                 :    28606172 :   return (dump_kind & (filter & MSG_ALL_KINDS)
     592                 :    28606172 :           && dump_kind & (filter & MSG_ALL_PRIORITIES));
     593                 :             : }
     594                 :             : 
     595                 :             : /* Print LOC to the appropriate dump destinations, given DUMP_KIND.
     596                 :             :    If optinfos are enabled, begin a new optinfo.  */
     597                 :             : 
     598                 :             : void
     599                 :     7943429 : dump_context::dump_loc (const dump_metadata_t &metadata,
     600                 :             :                         const dump_user_location_t &loc)
     601                 :             : {
     602                 :     7943429 :   end_any_optinfo ();
     603                 :             : 
     604                 :     7943429 :   dump_loc_immediate (metadata.get_dump_flags (), loc);
     605                 :             : 
     606                 :     7943429 :   if (optinfo_enabled_p ())
     607                 :       47143 :     begin_next_optinfo (metadata, loc);
     608                 :     7943429 : }
     609                 :             : 
     610                 :             : /* As dump_loc above, but without starting a new optinfo. */
     611                 :             : 
     612                 :             : void
     613                 :     7949027 : dump_context::dump_loc_immediate (dump_flags_t dump_kind,
     614                 :             :                                   const dump_user_location_t &loc)
     615                 :             : {
     616                 :     7949027 :   location_t srcloc = loc.get_location_t ();
     617                 :             : 
     618                 :     7949027 :   if (dump_file && apply_dump_filter_p (dump_kind, pflags))
     619                 :     7837610 :     ::dump_loc (dump_kind, dump_file, srcloc);
     620                 :             : 
     621                 :     7949027 :   if (alt_dump_file && apply_dump_filter_p (dump_kind, alt_flags))
     622                 :       22709 :     ::dump_loc (dump_kind, alt_dump_file, srcloc);
     623                 :             : 
     624                 :             :   /* Support for temp_dump_context in selftests.  */
     625                 :     7949027 :   if (m_test_pp && apply_dump_filter_p (dump_kind, m_test_pp_flags))
     626                 :        1960 :     ::dump_loc (dump_kind, m_test_pp, srcloc);
     627                 :     7949027 : }
     628                 :             : 
     629                 :             : /* Make an item for the given dump call, equivalent to print_gimple_stmt.  */
     630                 :             : 
     631                 :             : static std::unique_ptr<optinfo_item>
     632                 :     3174785 : make_item_for_dump_gimple_stmt (gimple *stmt, int spc, dump_flags_t dump_flags)
     633                 :             : {
     634                 :     3174785 :   pretty_printer pp;
     635                 :     3174785 :   pp_needs_newline (&pp) = true;
     636                 :     3174785 :   pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);
     637                 :     3174785 :   pp_newline (&pp);
     638                 :             : 
     639                 :     3174785 :   std::unique_ptr<optinfo_item> item
     640                 :     6349570 :     = std::make_unique<optinfo_item> (OPTINFO_ITEM_KIND_GIMPLE,
     641                 :     3174785 :                                       gimple_location (stmt),
     642                 :     3174785 :                                       xstrdup (pp_formatted_text (&pp)));
     643                 :     6349570 :   return item;
     644                 :     3174785 : }
     645                 :             : 
     646                 :             : /* Dump gimple statement GS with SPC indentation spaces and
     647                 :             :    EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.  */
     648                 :             : 
     649                 :             : void
     650                 :         224 : dump_context::dump_gimple_stmt (const dump_metadata_t &metadata,
     651                 :             :                                 dump_flags_t extra_dump_flags,
     652                 :             :                                 gimple *gs, int spc)
     653                 :             : {
     654                 :         224 :   auto item
     655                 :         224 :     = make_item_for_dump_gimple_stmt (gs, spc, dump_flags | extra_dump_flags);
     656                 :         224 :   emit_item (*item.get (), metadata.get_dump_flags ());
     657                 :             : 
     658                 :         224 :   if (optinfo_enabled_p ())
     659                 :             :     {
     660                 :         112 :       optinfo &info = ensure_pending_optinfo (metadata);
     661                 :         112 :       info.add_item (std::move (item));
     662                 :             :     }
     663                 :         224 : }
     664                 :             : 
     665                 :             : /* Similar to dump_gimple_stmt, except additionally print source location.  */
     666                 :             : 
     667                 :             : void
     668                 :         112 : dump_context::dump_gimple_stmt_loc (const dump_metadata_t &metadata,
     669                 :             :                                     const dump_user_location_t &loc,
     670                 :             :                                     dump_flags_t extra_dump_flags,
     671                 :             :                                     gimple *gs, int spc)
     672                 :             : {
     673                 :         112 :   dump_loc (metadata, loc);
     674                 :         112 :   dump_gimple_stmt (metadata, extra_dump_flags, gs, spc);
     675                 :         112 : }
     676                 :             : 
     677                 :             : /* Make an item for the given dump call, equivalent to print_gimple_expr.  */
     678                 :             : 
     679                 :             : static std::unique_ptr<optinfo_item>
     680                 :      730114 : make_item_for_dump_gimple_expr (gimple *stmt, int spc, dump_flags_t dump_flags)
     681                 :             : {
     682                 :      730114 :   dump_flags |= TDF_RHS_ONLY;
     683                 :      730114 :   pretty_printer pp;
     684                 :      730114 :   pp_needs_newline (&pp) = true;
     685                 :      730114 :   pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);
     686                 :             : 
     687                 :      730114 :   std::unique_ptr<optinfo_item> item
     688                 :     1460228 :     = std::make_unique<optinfo_item> (OPTINFO_ITEM_KIND_GIMPLE,
     689                 :      730114 :                                       gimple_location (stmt),
     690                 :      730114 :                                       xstrdup (pp_formatted_text (&pp)));
     691                 :     1460228 :   return item;
     692                 :      730114 : }
     693                 :             : 
     694                 :             : /* Dump gimple statement GS with SPC indentation spaces and
     695                 :             :    EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.
     696                 :             :    Do not terminate with a newline or semicolon.  */
     697                 :             : 
     698                 :             : void
     699                 :      729778 : dump_context::dump_gimple_expr (const dump_metadata_t &metadata,
     700                 :             :                                 dump_flags_t extra_dump_flags,
     701                 :             :                                 gimple *gs, int spc)
     702                 :             : {
     703                 :      729778 :   std::unique_ptr<optinfo_item> item
     704                 :      729778 :     = make_item_for_dump_gimple_expr (gs, spc, dump_flags | extra_dump_flags);
     705                 :      729778 :   emit_item (*item.get (), metadata.get_dump_flags ());
     706                 :             : 
     707                 :      729778 :   if (optinfo_enabled_p ())
     708                 :             :     {
     709                 :        6750 :       optinfo &info = ensure_pending_optinfo (metadata);
     710                 :        6750 :       info.add_item (std::move (item));
     711                 :             :     }
     712                 :      729778 : }
     713                 :             : 
     714                 :             : /* Similar to dump_gimple_expr, except additionally print source location.  */
     715                 :             : 
     716                 :             : void
     717                 :         112 : dump_context::dump_gimple_expr_loc (const dump_metadata_t &metadata,
     718                 :             :                                     const dump_user_location_t &loc,
     719                 :             :                                     dump_flags_t extra_dump_flags,
     720                 :             :                                     gimple *gs,
     721                 :             :                                     int spc)
     722                 :             : {
     723                 :         112 :   dump_loc (metadata, loc);
     724                 :         112 :   dump_gimple_expr (metadata, extra_dump_flags, gs, spc);
     725                 :         112 : }
     726                 :             : 
     727                 :             : /* Make an item for the given dump call, equivalent to print_generic_expr.  */
     728                 :             : 
     729                 :             : static std::unique_ptr<optinfo_item>
     730                 :     1714792 : make_item_for_dump_generic_expr (tree node, dump_flags_t dump_flags)
     731                 :             : {
     732                 :     1714792 :   pretty_printer pp;
     733                 :     1714792 :   pp_needs_newline (&pp) = true;
     734                 :     1714792 :   pp_translate_identifiers (&pp) = false;
     735                 :     1714792 :   dump_generic_node (&pp, node, 0, dump_flags, false);
     736                 :             : 
     737                 :     1714792 :   location_t loc = UNKNOWN_LOCATION;
     738                 :     1714792 :   if (EXPR_HAS_LOCATION (node))
     739                 :      148610 :     loc = EXPR_LOCATION (node);
     740                 :             : 
     741                 :     1714792 :   std::unique_ptr<optinfo_item> item
     742                 :     3429584 :     = std::make_unique<optinfo_item> (OPTINFO_ITEM_KIND_TREE, loc,
     743                 :     1714792 :                                       xstrdup (pp_formatted_text (&pp)));
     744                 :     3429584 :   return item;
     745                 :     1714792 : }
     746                 :             : 
     747                 :             : /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
     748                 :             :    DUMP_KIND is enabled.  */
     749                 :             : 
     750                 :             : void
     751                 :      235618 : dump_context::dump_generic_expr (const dump_metadata_t &metadata,
     752                 :             :                                  dump_flags_t extra_dump_flags,
     753                 :             :                                  tree t)
     754                 :             : {
     755                 :      235618 :   std::unique_ptr<optinfo_item> item
     756                 :      235618 :     = make_item_for_dump_generic_expr (t, dump_flags | extra_dump_flags);
     757                 :      235618 :   emit_item (*item.get (), metadata.get_dump_flags ());
     758                 :             : 
     759                 :      235618 :   if (optinfo_enabled_p ())
     760                 :             :     {
     761                 :        4379 :       optinfo &info = ensure_pending_optinfo (metadata);
     762                 :        4379 :       info.add_item (std::move (item));
     763                 :             :     }
     764                 :      235618 : }
     765                 :             : 
     766                 :             : 
     767                 :             : /* Similar to dump_generic_expr, except additionally print the source
     768                 :             :    location.  */
     769                 :             : 
     770                 :             : void
     771                 :      157985 : dump_context::dump_generic_expr_loc (const dump_metadata_t &metadata,
     772                 :             :                                      const dump_user_location_t &loc,
     773                 :             :                                      dump_flags_t extra_dump_flags,
     774                 :             :                                      tree t)
     775                 :             : {
     776                 :      157985 :   dump_loc (metadata, loc);
     777                 :      157985 :   dump_generic_expr (metadata, extra_dump_flags, t);
     778                 :      157985 : }
     779                 :             : 
     780                 :             : /* Make an item for the given dump call.  */
     781                 :             : 
     782                 :             : static std::unique_ptr<optinfo_item>
     783                 :        7691 : make_item_for_dump_symtab_node (symtab_node *node)
     784                 :             : {
     785                 :        7691 :   location_t loc = DECL_SOURCE_LOCATION (node->decl);
     786                 :        7691 :   std::unique_ptr<optinfo_item> item
     787                 :       15382 :     = std::make_unique<optinfo_item> (OPTINFO_ITEM_KIND_SYMTAB_NODE, loc,
     788                 :        7691 :                                       xstrdup (node->dump_name ()));
     789                 :        7691 :   return item;
     790                 :             : }
     791                 :             : 
     792                 :             : struct wrapped_optinfo_item : public pp_token_custom_data::value
     793                 :             : {
     794                 :     4661648 :   wrapped_optinfo_item (std::unique_ptr<optinfo_item> item)
     795                 :     4661648 :   : m_optinfo_item (std::move (item))
     796                 :             :   {
     797                 :     4661648 :     gcc_assert (m_optinfo_item.get ());
     798                 :     4661648 :   }
     799                 :             : 
     800                 :           0 :   void dump (FILE *out) const final override
     801                 :             :   {
     802                 :           0 :     fprintf (out, "OPTINFO(\"%s\")", m_optinfo_item->get_text ());
     803                 :           0 :   }
     804                 :             : 
     805                 :     4661648 :   bool as_standard_tokens (pp_token_list &) final override
     806                 :             :   {
     807                 :             :     /* Keep as a custom token.  */
     808                 :     4661648 :     return false;
     809                 :             :   }
     810                 :             : 
     811                 :             :   std::unique_ptr<optinfo_item> m_optinfo_item;
     812                 :             : };
     813                 :             : 
     814                 :             : /* dump_pretty_printer's ctor.  */
     815                 :             : 
     816                 :    12590790 : dump_pretty_printer::dump_pretty_printer (dump_context *context,
     817                 :    12590790 :                                           dump_flags_t dump_kind)
     818                 :             : : pretty_printer (),
     819                 :    12590790 :   m_context (context),
     820                 :    12590790 :   m_dump_kind (dump_kind),
     821                 :    12590790 :   m_token_printer (*this)
     822                 :             : {
     823                 :    12590790 :   pp_format_decoder (this) = format_decoder_cb;
     824                 :    12590790 :   set_token_printer (&m_token_printer);
     825                 :    12590790 : }
     826                 :             : 
     827                 :             : /* Emit ITEM and take ownership of it.  If DEST is non-NULL, add ITEM
     828                 :             :    to DEST; otherwise delete ITEM.  */
     829                 :             : 
     830                 :             : void
     831                 :    18165300 : dump_pretty_printer::emit_item (std::unique_ptr<optinfo_item> item,
     832                 :             :                                 optinfo *dest)
     833                 :             : {
     834                 :    18165300 :   m_context->emit_item (*item.get (), m_dump_kind);
     835                 :    18165300 :   if (dest)
     836                 :      152321 :     dest->add_item (std::move (item));
     837                 :    18165300 : }
     838                 :             : 
     839                 :             : /* Append a custom pp_token for ITEM (generated in phase 2 of formatting)
     840                 :             :    into FORMATTTED_TOK_LIST, so that it can be emitted in phase 2.  */
     841                 :             : 
     842                 :             : void
     843                 :     4661648 : dump_pretty_printer::stash_item (pp_token_list &formatted_tok_list,
     844                 :             :                                  std::unique_ptr<optinfo_item> item)
     845                 :             : {
     846                 :     4661648 :   gcc_assert (item.get ());
     847                 :             : 
     848                 :     4661648 :   auto custom_data
     849                 :     4661648 :     = std::make_unique<wrapped_optinfo_item> (std::move (item));
     850                 :     4661648 :   formatted_tok_list.push_back<pp_token_custom_data> (std::move (custom_data));
     851                 :     4661648 : }
     852                 :             : 
     853                 :             : /* pp_format_decoder callback for dump_pretty_printer, and thus for
     854                 :             :    dump_printf and dump_printf_loc.
     855                 :             : 
     856                 :             :    A wrapper around decode_format, for type-safety.  */
     857                 :             : 
     858                 :             : bool
     859                 :     4661648 : dump_pretty_printer::format_decoder_cb (pretty_printer *pp, text_info *text,
     860                 :             :                                         const char *spec, int /*precision*/,
     861                 :             :                                         bool /*wide*/, bool /*set_locus*/,
     862                 :             :                                         bool /*verbose*/, bool */*quoted*/,
     863                 :             :                                         pp_token_list &formatted_tok_list)
     864                 :             : {
     865                 :     4661648 :   dump_pretty_printer *opp = static_cast <dump_pretty_printer *> (pp);
     866                 :     4661648 :   return opp->decode_format (text, spec, formatted_tok_list);
     867                 :             : }
     868                 :             : 
     869                 :             : /* Format decoder for dump_pretty_printer, and thus for dump_printf and
     870                 :             :    dump_printf_loc.
     871                 :             : 
     872                 :             :    Supported format codes (in addition to the standard pretty_printer ones)
     873                 :             :    are:
     874                 :             : 
     875                 :             :    %C: cgraph_node *:
     876                 :             :        Equivalent to: dump_symtab_node (MSG_*, node)
     877                 :             :    %E: gimple *:
     878                 :             :        Equivalent to: dump_gimple_expr (MSG_*, TDF_SLIM, stmt, 0)
     879                 :             :    %G: gimple *:
     880                 :             :        Equivalent to: dump_gimple_stmt (MSG_*, TDF_SLIM, stmt, 0)
     881                 :             :    %T: tree:
     882                 :             :        Equivalent to: dump_generic_expr (MSG_*, arg, TDF_SLIM).
     883                 :             : 
     884                 :             :    TODO: add a format code that can handle (symtab_node*) *and* both
     885                 :             :    subclasses (presumably means teaching -Wformat about non-virtual
     886                 :             :    subclasses).
     887                 :             : 
     888                 :             :    These format codes build optinfo_item instances, thus capturing metadata
     889                 :             :    about the arguments being dumped, as well as the textual output.  */
     890                 :             : 
     891                 :             : bool
     892                 :     4661648 : dump_pretty_printer::decode_format (text_info *text, const char *spec,
     893                 :             :                                     pp_token_list &formatted_tok_list)
     894                 :             : {
     895                 :             :   /* Various format codes that imply making an optinfo_item and stashed it
     896                 :             :      for later use (to capture metadata, rather than plain text).  */
     897                 :     4661648 :   switch (*spec)
     898                 :             :     {
     899                 :        7577 :     case 'C':
     900                 :        7577 :       {
     901                 :        7577 :         cgraph_node *node = va_arg (*text->m_args_ptr, cgraph_node *);
     902                 :             : 
     903                 :             :         /* Make an item for the node, and stash it.  */
     904                 :        7577 :         auto item = make_item_for_dump_symtab_node (node);
     905                 :        7577 :         stash_item (formatted_tok_list, std::move (item));
     906                 :        7577 :         return true;
     907                 :        7577 :       }
     908                 :             : 
     909                 :         336 :     case 'E':
     910                 :         336 :       {
     911                 :         336 :         gimple *stmt = va_arg (*text->m_args_ptr, gimple *);
     912                 :             : 
     913                 :             :         /* Make an item for the stmt, and stash it.  */
     914                 :         336 :         auto item = make_item_for_dump_gimple_expr (stmt, 0, TDF_SLIM);
     915                 :         336 :         stash_item (formatted_tok_list, std::move (item));
     916                 :         336 :         return true;
     917                 :         336 :       }
     918                 :             : 
     919                 :     3174561 :     case 'G':
     920                 :     3174561 :       {
     921                 :     3174561 :         gimple *stmt = va_arg (*text->m_args_ptr, gimple *);
     922                 :             : 
     923                 :             :         /* Make an item for the stmt, and stash it.  */
     924                 :     3174561 :         auto item = make_item_for_dump_gimple_stmt (stmt, 0, TDF_SLIM);
     925                 :     3174561 :         stash_item (formatted_tok_list, std::move (item));
     926                 :     3174561 :         return true;
     927                 :     3174561 :       }
     928                 :             : 
     929                 :     1479174 :     case 'T':
     930                 :     1479174 :       {
     931                 :     1479174 :         tree t = va_arg (*text->m_args_ptr, tree);
     932                 :             : 
     933                 :             :         /* Make an item for the tree, and stash it.  */
     934                 :     1479174 :         auto item = make_item_for_dump_generic_expr (t, TDF_SLIM);
     935                 :     1479174 :         stash_item (formatted_tok_list, std::move (item));
     936                 :     1479174 :         return true;
     937                 :     1479174 :       }
     938                 :             : 
     939                 :             :     default:
     940                 :             :       return false;
     941                 :             :     }
     942                 :             : }
     943                 :             : 
     944                 :             : void
     945                 :    12590790 : dump_pretty_printer::custom_token_printer::
     946                 :             : print_tokens (pretty_printer *pp,
     947                 :             :               const pp_token_list &tokens)
     948                 :             : {
     949                 :             :   /* Accumulate text whilst emitting items.  */
     950                 :    30857880 :   for (auto iter = tokens.m_first; iter; iter = iter->m_next)
     951                 :    18267090 :     switch (iter->m_kind)
     952                 :             :       {
     953                 :           0 :       default:
     954                 :           0 :         gcc_unreachable ();
     955                 :             : 
     956                 :    13534228 :       case pp_token::kind::text:
     957                 :    13534228 :         {
     958                 :    13534228 :           pp_token_text *sub = as_a <pp_token_text *> (iter);
     959                 :    13534228 :           gcc_assert (sub->m_value.get ());
     960                 :    13534228 :           pp_string (pp, sub->m_value.get ());
     961                 :             :         }
     962                 :    13534228 :         break;
     963                 :             : 
     964                 :             :       case pp_token::kind::begin_color:
     965                 :             :       case pp_token::kind::end_color:
     966                 :             :         /* No-op for dumpfiles.  */
     967                 :             :         break;
     968                 :             : 
     969                 :       26641 :       case pp_token::kind::begin_quote:
     970                 :       26641 :         pp_begin_quote (pp, pp_show_color (pp));
     971                 :       26641 :         break;
     972                 :       44573 :       case pp_token::kind::end_quote:
     973                 :       44573 :         pp_end_quote (pp, pp_show_color (pp));
     974                 :       44573 :         break;
     975                 :             : 
     976                 :             :       case pp_token::kind::begin_url:
     977                 :             :       case pp_token::kind::end_url:
     978                 :             :         /* No-op for dumpfiles.  */
     979                 :             :         break;
     980                 :             : 
     981                 :     4661648 :       case pp_token::kind::custom_data:
     982                 :     4661648 :         {
     983                 :     4661648 :           emit_any_pending_textual_chunks ();
     984                 :     4661648 :           pp_token_custom_data *sub = as_a <pp_token_custom_data *> (iter);
     985                 :     4661648 :           gcc_assert (sub->m_value.get ());
     986                 :     4661648 :           wrapped_optinfo_item *custom_data
     987                 :     4661648 :             = static_cast<wrapped_optinfo_item *> (sub->m_value.get ());
     988                 :     4661648 :           m_dump_pp.emit_item (std::move (custom_data->m_optinfo_item),
     989                 :             :                                m_optinfo);
     990                 :             :         }
     991                 :     4661648 :         break;
     992                 :             :       }
     993                 :             : 
     994                 :    12590790 :   emit_any_pending_textual_chunks ();
     995                 :    12590790 : }
     996                 :             : 
     997                 :             : /* Subroutine of dump_pretty_printer::custom_token_printer::print_tokens
     998                 :             :    for consolidating multiple adjacent pure-text chunks into single
     999                 :             :    optinfo_items (in phase 3).  */
    1000                 :             : 
    1001                 :             : void
    1002                 :    17252438 : dump_pretty_printer::custom_token_printer::
    1003                 :             : emit_any_pending_textual_chunks ()
    1004                 :             : {
    1005                 :    17252438 :   dump_pretty_printer *pp = &m_dump_pp;
    1006                 :    17252438 :   output_buffer *const buffer = pp_buffer (pp);
    1007                 :    17252438 :   gcc_assert (buffer->m_obstack == &buffer->m_formatted_obstack);
    1008                 :             : 
    1009                 :             :   /* Don't emit an item if the pending text is empty.  */
    1010                 :    17252438 :   if (output_buffer_last_position_in_text (buffer) == nullptr)
    1011                 :     3748786 :     return;
    1012                 :             : 
    1013                 :    13503652 :   char *formatted_text = xstrdup (pp_formatted_text (pp));
    1014                 :    13503652 :   std::unique_ptr<optinfo_item> item
    1015                 :    27007304 :     = std::make_unique<optinfo_item> (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
    1016                 :    13503652 :                                       formatted_text);
    1017                 :    13503652 :   pp->emit_item (std::move (item), m_optinfo);
    1018                 :             : 
    1019                 :             :   /* Clear the pending text by unwinding formatted_text back to the start
    1020                 :             :      of the buffer (without deallocating).  */
    1021                 :    13503652 :   obstack_free (&buffer->m_formatted_obstack,
    1022                 :             :                 buffer->m_formatted_obstack.object_base);
    1023                 :    13503652 : }
    1024                 :             : 
    1025                 :             : /* Output a formatted message using FORMAT on appropriate dump streams.  */
    1026                 :             : 
    1027                 :             : void
    1028                 :    12561653 : dump_context::dump_printf_va (const dump_metadata_t &metadata,
    1029                 :             :                               const char *format,
    1030                 :             :                               va_list *ap)
    1031                 :             : {
    1032                 :    12561653 :   dump_pretty_printer pp (this, metadata.get_dump_flags ());
    1033                 :             : 
    1034                 :    12561653 :   text_info text (format, ap, errno);
    1035                 :             : 
    1036                 :             :   /* Phases 1 and 2, using pp_format.  */
    1037                 :    12561653 :   pp_format (&pp, &text);
    1038                 :             : 
    1039                 :             :   /* Phase 3: update the custom token_printer with any active optinfo.  */
    1040                 :    12561653 :   if (optinfo_enabled_p ())
    1041                 :             :     {
    1042                 :       79298 :       optinfo &info = ensure_pending_optinfo (metadata);
    1043                 :       79298 :       pp.set_optinfo (&info);
    1044                 :             :     }
    1045                 :             :   else
    1046                 :    12482355 :     pp.set_optinfo (nullptr);
    1047                 :             : 
    1048                 :    12561653 :   pp_output_formatted_text (&pp, nullptr);
    1049                 :    12561653 : }
    1050                 :             : 
    1051                 :             : /* Similar to dump_printf, except source location is also printed, and
    1052                 :             :    dump location captured.  */
    1053                 :             : 
    1054                 :             : void
    1055                 :     7756083 : dump_context::dump_printf_loc_va (const dump_metadata_t &metadata,
    1056                 :             :                                   const dump_user_location_t &loc,
    1057                 :             :                                   const char *format, va_list *ap)
    1058                 :             : {
    1059                 :     7756083 :   dump_loc (metadata, loc);
    1060                 :     7756083 :   dump_printf_va (metadata, format, ap);
    1061                 :     7756083 : }
    1062                 :             : 
    1063                 :             : /* Make an item for the given dump call, equivalent to print_dec.  */
    1064                 :             : 
    1065                 :             : template<unsigned int N, typename C>
    1066                 :             : static std::unique_ptr<optinfo_item>
    1067                 :      465843 : make_item_for_dump_dec (const poly_int<N, C> &value)
    1068                 :             : {
    1069                 :             :   STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
    1070                 :      465843 :   signop sgn = poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED;
    1071                 :             : 
    1072                 :      465843 :   pretty_printer pp;
    1073                 :             : 
    1074                 :             :   if (value.is_constant ())
    1075                 :      465843 :     pp_wide_int (&pp, value.coeffs[0], sgn);
    1076                 :             :   else
    1077                 :             :     {
    1078                 :             :       pp_character (&pp, '[');
    1079                 :             :       for (unsigned int i = 0; i < N; ++i)
    1080                 :             :         {
    1081                 :             :           pp_wide_int (&pp, value.coeffs[i], sgn);
    1082                 :             :           pp_character (&pp, i == N - 1 ? ']' : ',');
    1083                 :             :         }
    1084                 :             :     }
    1085                 :             : 
    1086                 :      465843 :   auto item
    1087                 :      931686 :     = std::make_unique<optinfo_item> (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
    1088                 :      465843 :                                       xstrdup (pp_formatted_text (&pp)));
    1089                 :      465843 :   return item;
    1090                 :      465843 : }
    1091                 :             : 
    1092                 :             : /* Output VALUE in decimal to appropriate dump streams.  */
    1093                 :             : 
    1094                 :             : template<unsigned int N, typename C>
    1095                 :             : void
    1096                 :      465843 : dump_context::dump_dec (const dump_metadata_t &metadata,
    1097                 :             :                         const poly_int<N, C> &value)
    1098                 :             : {
    1099                 :      465843 :   auto item = make_item_for_dump_dec (value);
    1100                 :      465843 :   emit_item (*item.get (), metadata.get_dump_flags ());
    1101                 :             : 
    1102                 :      465843 :   if (optinfo_enabled_p ())
    1103                 :             :     {
    1104                 :        1834 :       optinfo &info = ensure_pending_optinfo (metadata);
    1105                 :        1834 :       info.add_item (std::move (item));
    1106                 :             :     }
    1107                 :      465843 : }
    1108                 :             : 
    1109                 :             : /* Output the name of NODE on appropriate dump streams.  */
    1110                 :             : 
    1111                 :             : void
    1112                 :         114 : dump_context::dump_symtab_node (const dump_metadata_t &metadata,
    1113                 :             :                                 symtab_node *node)
    1114                 :             : {
    1115                 :         114 :   auto item = make_item_for_dump_symtab_node (node);
    1116                 :         114 :   emit_item (*item.get (), metadata.get_dump_flags ());
    1117                 :             : 
    1118                 :         114 :   if (optinfo_enabled_p ())
    1119                 :             :     {
    1120                 :          56 :       optinfo &info = ensure_pending_optinfo (metadata);
    1121                 :          56 :       info.add_item (std::move (item));
    1122                 :             :     }
    1123                 :         114 : }
    1124                 :             : 
    1125                 :             : /* Get the current dump scope-nesting depth.
    1126                 :             :    For use by -fopt-info (for showing nesting via indentation).  */
    1127                 :             : 
    1128                 :             : unsigned int
    1129                 :     8371815 : dump_context::get_scope_depth () const
    1130                 :             : {
    1131                 :     8371815 :   return m_scope_depth;
    1132                 :             : }
    1133                 :             : 
    1134                 :             : /* Push a nested dump scope.
    1135                 :             :    Increment the scope depth.
    1136                 :             :    Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
    1137                 :             :    destination, if any.
    1138                 :             :    Emit a "scope" optinfo if optinfos are enabled.  */
    1139                 :             : 
    1140                 :             : void
    1141                 :      514109 : dump_context::begin_scope (const char *name,
    1142                 :             :                            const dump_user_location_t &user_location,
    1143                 :             :                            const dump_impl_location_t &impl_location)
    1144                 :             : {
    1145                 :      514109 :   m_scope_depth++;
    1146                 :             : 
    1147                 :      514109 :   location_t src_loc = user_location.get_location_t ();
    1148                 :             : 
    1149                 :      514109 :   if (dump_file && apply_dump_filter_p (MSG_NOTE, pflags))
    1150                 :      506425 :     ::dump_loc (MSG_NOTE, dump_file, src_loc);
    1151                 :             : 
    1152                 :      514109 :   if (alt_dump_file && apply_dump_filter_p (MSG_NOTE, alt_flags))
    1153                 :           3 :     ::dump_loc (MSG_NOTE, alt_dump_file, src_loc);
    1154                 :             : 
    1155                 :             :   /* Support for temp_dump_context in selftests.  */
    1156                 :      514109 :   if (m_test_pp && apply_dump_filter_p (MSG_NOTE, m_test_pp_flags))
    1157                 :         504 :     ::dump_loc (MSG_NOTE, m_test_pp, src_loc);
    1158                 :             : 
    1159                 :             :   /* Format multiple consecutive punctuation characters via %s to
    1160                 :             :      avoid -Wformat-diag in the pp_printf call below whose output
    1161                 :             :      isn't used for diagnostic output.  */
    1162                 :      514109 :   pretty_printer pp;
    1163                 :      514109 :   pp_printf (&pp, "%s %s %s", "===", name, "===");
    1164                 :      514109 :   pp_newline (&pp);
    1165                 :      514109 :   std::unique_ptr<optinfo_item> item
    1166                 :     1028218 :     = std::make_unique<optinfo_item> (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
    1167                 :      514109 :                                       xstrdup (pp_formatted_text (&pp)));
    1168                 :      514109 :   emit_item (*item.get (), MSG_NOTE);
    1169                 :             : 
    1170                 :      514109 :   if (optinfo_enabled_p ())
    1171                 :             :     {
    1172                 :        4306 :       optinfo &info
    1173                 :        4306 :         = begin_next_optinfo (dump_metadata_t (MSG_NOTE, impl_location),
    1174                 :             :                               user_location);
    1175                 :        4306 :       info.m_kind = OPTINFO_KIND_SCOPE;
    1176                 :        4306 :       info.add_item (std::move (item));
    1177                 :        4306 :       end_any_optinfo ();
    1178                 :             :     }
    1179                 :      514109 : }
    1180                 :             : 
    1181                 :             : /* Pop a nested dump scope.  */
    1182                 :             : 
    1183                 :             : void
    1184                 :      514109 : dump_context::end_scope ()
    1185                 :             : {
    1186                 :      514109 :   end_any_optinfo ();
    1187                 :      514109 :   m_scope_depth--;
    1188                 :             : 
    1189                 :      514109 :   if (m_json_writer)
    1190                 :        4306 :     m_json_writer->pop_scope ();
    1191                 :      514109 : }
    1192                 :             : 
    1193                 :             : /* Should optinfo instances be created?
    1194                 :             :    All creation of optinfos should be guarded by this predicate.
    1195                 :             :    Return true if any optinfo destinations are active.  */
    1196                 :             : 
    1197                 :             : bool
    1198                 :   600447907 : dump_context::optinfo_enabled_p () const
    1199                 :             : {
    1200                 :   600447907 :   return (optimization_records_enabled_p ());
    1201                 :             : }
    1202                 :             : 
    1203                 :             : /* Return the optinfo currently being accumulated, creating one if
    1204                 :             :    necessary.  */
    1205                 :             : 
    1206                 :             : optinfo &
    1207                 :       92429 : dump_context::ensure_pending_optinfo (const dump_metadata_t &metadata)
    1208                 :             : {
    1209                 :       92429 :   if (!m_pending)
    1210                 :         848 :     return begin_next_optinfo (metadata, dump_user_location_t ());
    1211                 :             :   return *m_pending;
    1212                 :             : }
    1213                 :             : 
    1214                 :             : /* Start a new optinfo and return it, ending any optinfo that was already
    1215                 :             :    accumulated.  */
    1216                 :             : 
    1217                 :             : optinfo &
    1218                 :       52297 : dump_context::begin_next_optinfo (const dump_metadata_t &metadata,
    1219                 :             :                                   const dump_user_location_t &user_loc)
    1220                 :             : {
    1221                 :       52297 :   end_any_optinfo ();
    1222                 :       52297 :   gcc_assert (m_pending == NULL);
    1223                 :       52297 :   dump_location_t loc (user_loc, metadata.get_impl_location ());
    1224                 :       52297 :   m_pending = new optinfo (loc, OPTINFO_KIND_NOTE, current_pass);
    1225                 :       52297 :   m_pending->handle_dump_file_kind (metadata.get_dump_flags ());
    1226                 :       52297 :   return *m_pending;
    1227                 :             : }
    1228                 :             : 
    1229                 :             : /* End any optinfo that has been accumulated within this context; emitting
    1230                 :             :    it to any destinations as appropriate, such as optimization records.  */
    1231                 :             : 
    1232                 :             : void
    1233                 :   586590564 : dump_context::end_any_optinfo ()
    1234                 :             : {
    1235                 :   586590564 :   if (m_pending)
    1236                 :       51061 :     emit_optinfo (m_pending);
    1237                 :   586590564 :   delete m_pending;
    1238                 :   586590564 :   m_pending = NULL;
    1239                 :   586590564 : }
    1240                 :             : 
    1241                 :             : /* Emit the optinfo to all of the "non-immediate" destinations
    1242                 :             :    (emission to "immediate" destinations is done by
    1243                 :             :    dump_context::emit_item).  */
    1244                 :             : 
    1245                 :             : void
    1246                 :       56659 : dump_context::emit_optinfo (const optinfo *info)
    1247                 :             : {
    1248                 :             :   /* -fsave-optimization-record.  */
    1249                 :       56659 :   if (m_json_writer)
    1250                 :       51292 :     m_json_writer->add_record (info);
    1251                 :       56659 : }
    1252                 :             : 
    1253                 :             : /* Emit ITEM to all item destinations (those that don't require
    1254                 :             :    consolidation into optinfo instances).  */
    1255                 :             : 
    1256                 :             : void
    1257                 :    20120826 : dump_context::emit_item (const optinfo_item &item, dump_flags_t dump_kind)
    1258                 :             : {
    1259                 :    20120826 :   if (dump_file && apply_dump_filter_p (dump_kind, pflags))
    1260                 :    19791794 :     fprintf (dump_file, "%s", item.get_text ());
    1261                 :             : 
    1262                 :    20120826 :   if (alt_dump_file && apply_dump_filter_p (dump_kind, alt_flags))
    1263                 :       99550 :     fprintf (alt_dump_file, "%s", item.get_text ());
    1264                 :             : 
    1265                 :             :   /* Support for temp_dump_context in selftests.  */
    1266                 :    20120826 :   if (m_test_pp && apply_dump_filter_p (dump_kind, m_test_pp_flags))
    1267                 :        5320 :     pp_string (m_test_pp, item.get_text ());
    1268                 :    20120826 : }
    1269                 :             : 
    1270                 :             : /* The current singleton dump_context, and its default.  */
    1271                 :             : 
    1272                 :             : dump_context *dump_context::s_current = &dump_context::s_default;
    1273                 :             : dump_context dump_context::s_default;
    1274                 :             : 
    1275                 :             : /* Implementation of dump_* API calls, calling into dump_context
    1276                 :             :    member functions.  */
    1277                 :             : 
    1278                 :             : /* Calls to the dump_* functions do non-trivial work, so they ought
    1279                 :             :    to be guarded by:
    1280                 :             :      if (dump_enabled_p ())
    1281                 :             :    Assert that they are guarded, and, if assertions are disabled,
    1282                 :             :    bail out if the calls weren't properly guarded.  */
    1283                 :             : 
    1284                 :             : #define VERIFY_DUMP_ENABLED_P \
    1285                 :             :   do {                                  \
    1286                 :             :     gcc_assert (dump_enabled_p ());     \
    1287                 :             :     if (!dump_enabled_p ())             \
    1288                 :             :       return;                           \
    1289                 :             :   } while (0)
    1290                 :             : 
    1291                 :             : /* Dump gimple statement GS with SPC indentation spaces and
    1292                 :             :    EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.  */
    1293                 :             : 
    1294                 :             : void
    1295                 :         112 : dump_gimple_stmt (const dump_metadata_t &metadata, dump_flags_t extra_dump_flags,
    1296                 :             :                   gimple *gs, int spc)
    1297                 :             : {
    1298                 :         112 :   VERIFY_DUMP_ENABLED_P;
    1299                 :         112 :   dump_context::get ().dump_gimple_stmt (metadata, extra_dump_flags, gs, spc);
    1300                 :             : }
    1301                 :             : 
    1302                 :             : /* Similar to dump_gimple_stmt, except additionally print source location.  */
    1303                 :             : 
    1304                 :             : void
    1305                 :         112 : dump_gimple_stmt_loc (const dump_metadata_t &metadata,
    1306                 :             :                       const dump_user_location_t &loc,
    1307                 :             :                       dump_flags_t extra_dump_flags, gimple *gs, int spc)
    1308                 :             : {
    1309                 :         112 :   VERIFY_DUMP_ENABLED_P;
    1310                 :         112 :   dump_context::get ().dump_gimple_stmt_loc (metadata, loc, extra_dump_flags,
    1311                 :             :                                              gs, spc);
    1312                 :             : }
    1313                 :             : 
    1314                 :             : /* Dump gimple statement GS with SPC indentation spaces and
    1315                 :             :    EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.
    1316                 :             :    Do not terminate with a newline or semicolon.  */
    1317                 :             : 
    1318                 :             : void
    1319                 :      729666 : dump_gimple_expr (const dump_metadata_t &metadata,
    1320                 :             :                   dump_flags_t extra_dump_flags,
    1321                 :             :                   gimple *gs, int spc)
    1322                 :             : {
    1323                 :      729666 :   VERIFY_DUMP_ENABLED_P;
    1324                 :      729666 :   dump_context::get ().dump_gimple_expr (metadata, extra_dump_flags, gs, spc);
    1325                 :             : }
    1326                 :             : 
    1327                 :             : /* Similar to dump_gimple_expr, except additionally print source location.  */
    1328                 :             : 
    1329                 :             : void
    1330                 :         112 : dump_gimple_expr_loc (const dump_metadata_t &metadata,
    1331                 :             :                       const dump_user_location_t &loc,
    1332                 :             :                       dump_flags_t extra_dump_flags, gimple *gs, int spc)
    1333                 :             : {
    1334                 :         112 :   VERIFY_DUMP_ENABLED_P;
    1335                 :         112 :   dump_context::get ().dump_gimple_expr_loc (metadata, loc, extra_dump_flags,
    1336                 :             :                                              gs, spc);
    1337                 :             : }
    1338                 :             : 
    1339                 :             : /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
    1340                 :             :    DUMP_KIND is enabled.  */
    1341                 :             : 
    1342                 :             : void
    1343                 :       77633 : dump_generic_expr (const dump_metadata_t &metadata, dump_flags_t extra_dump_flags,
    1344                 :             :                    tree t)
    1345                 :             : {
    1346                 :       77633 :   VERIFY_DUMP_ENABLED_P;
    1347                 :       77633 :   dump_context::get ().dump_generic_expr (metadata, extra_dump_flags, t);
    1348                 :             : }
    1349                 :             : 
    1350                 :             : /* Similar to dump_generic_expr, except additionally print the source
    1351                 :             :    location.  */
    1352                 :             : 
    1353                 :             : void
    1354                 :      157985 : dump_generic_expr_loc (const dump_metadata_t &metadata,
    1355                 :             :                        const dump_user_location_t &loc,
    1356                 :             :                        dump_flags_t extra_dump_flags, tree t)
    1357                 :             : {
    1358                 :      157985 :   VERIFY_DUMP_ENABLED_P;
    1359                 :      157985 :   dump_context::get ().dump_generic_expr_loc (metadata, loc, extra_dump_flags,
    1360                 :             :                                               t);
    1361                 :             : }
    1362                 :             : 
    1363                 :             : /* Output a formatted message using FORMAT on appropriate dump streams.  */
    1364                 :             : 
    1365                 :             : void
    1366                 :     4805570 : dump_printf (const dump_metadata_t &metadata, const char *format, ...)
    1367                 :             : {
    1368                 :     4805570 :   VERIFY_DUMP_ENABLED_P;
    1369                 :     4805570 :   va_list ap;
    1370                 :     4805570 :   va_start (ap, format);
    1371                 :     4805570 :   dump_context::get ().dump_printf_va (metadata, format, &ap);
    1372                 :     4805570 :   va_end (ap);
    1373                 :             : }
    1374                 :             : 
    1375                 :             : /* Similar to dump_printf, except source location is also printed, and
    1376                 :             :    dump location captured.  */
    1377                 :             : 
    1378                 :             : void
    1379                 :     7756083 : dump_printf_loc (const dump_metadata_t &metadata,
    1380                 :             :                  const dump_user_location_t &loc,
    1381                 :             :                  const char *format, ...)
    1382                 :             : {
    1383                 :     7756083 :   VERIFY_DUMP_ENABLED_P;
    1384                 :     7756083 :   va_list ap;
    1385                 :     7756083 :   va_start (ap, format);
    1386                 :     7756083 :   dump_context::get ().dump_printf_loc_va (metadata, loc, format, &ap);
    1387                 :     7756083 :   va_end (ap);
    1388                 :             : }
    1389                 :             : 
    1390                 :             : /* Output VALUE in decimal to appropriate dump streams.  */
    1391                 :             : 
    1392                 :             : template<unsigned int N, typename C>
    1393                 :             : void
    1394                 :      465843 : dump_dec (const dump_metadata_t &metadata, const poly_int<N, C> &value)
    1395                 :             : {
    1396                 :      465843 :   VERIFY_DUMP_ENABLED_P;
    1397                 :      465843 :   dump_context::get ().dump_dec (metadata, value);
    1398                 :             : }
    1399                 :             : 
    1400                 :             : template void dump_dec (const dump_metadata_t &metadata, const poly_uint16 &);
    1401                 :             : template void dump_dec (const dump_metadata_t &metadata, const poly_int64 &);
    1402                 :             : template void dump_dec (const dump_metadata_t &metadata, const poly_uint64 &);
    1403                 :             : template void dump_dec (const dump_metadata_t &metadata, const poly_offset_int &);
    1404                 :             : template void dump_dec (const dump_metadata_t &metadata, const poly_widest_int &);
    1405                 :             : 
    1406                 :             : void
    1407                 :           0 : dump_dec (dump_flags_t dump_kind, const poly_wide_int &value, signop sgn)
    1408                 :             : {
    1409                 :           0 :   VERIFY_DUMP_ENABLED_P;
    1410                 :           0 :   if (dump_file
    1411                 :           0 :       && dump_context::get ().apply_dump_filter_p (dump_kind, pflags))
    1412                 :           0 :     print_dec (value, dump_file, sgn);
    1413                 :             : 
    1414                 :           0 :   if (alt_dump_file
    1415                 :           0 :       && dump_context::get ().apply_dump_filter_p (dump_kind, alt_flags))
    1416                 :           0 :     print_dec (value, alt_dump_file, sgn);
    1417                 :             : }
    1418                 :             : 
    1419                 :             : /* Output VALUE in hexadecimal to appropriate dump streams.  */
    1420                 :             : 
    1421                 :             : void
    1422                 :      145372 : dump_hex (dump_flags_t dump_kind, const poly_wide_int &value)
    1423                 :             : {
    1424                 :      145372 :   VERIFY_DUMP_ENABLED_P;
    1425                 :      145372 :   if (dump_file
    1426                 :      145372 :       && dump_context::get ().apply_dump_filter_p (dump_kind, pflags))
    1427                 :      143166 :     print_hex (value, dump_file);
    1428                 :             : 
    1429                 :      145372 :   if (alt_dump_file
    1430                 :      145372 :       && dump_context::get ().apply_dump_filter_p (dump_kind, alt_flags))
    1431                 :           0 :     print_hex (value, alt_dump_file);
    1432                 :             : }
    1433                 :             : 
    1434                 :             : /* Emit and delete the currently pending optinfo, if there is one,
    1435                 :             :    without the caller needing to know about class dump_context.  */
    1436                 :             : 
    1437                 :             : void
    1438                 :   578076423 : dumpfile_ensure_any_optinfo_are_flushed ()
    1439                 :             : {
    1440                 :   578076423 :   dump_context::get().end_any_optinfo ();
    1441                 :   578076423 : }
    1442                 :             : 
    1443                 :             : /* Output the name of NODE on appropriate dump streams.  */
    1444                 :             : 
    1445                 :             : void
    1446                 :         114 : dump_symtab_node (const dump_metadata_t &metadata, symtab_node *node)
    1447                 :             : {
    1448                 :         114 :   VERIFY_DUMP_ENABLED_P;
    1449                 :         114 :   dump_context::get ().dump_symtab_node (metadata, node);
    1450                 :             : }
    1451                 :             : 
    1452                 :             : /* Get the current dump scope-nesting depth.
    1453                 :             :    For use by -fopt-info (for showing nesting via indentation).  */
    1454                 :             : 
    1455                 :             : unsigned int
    1456                 :     8371815 : get_dump_scope_depth ()
    1457                 :             : {
    1458                 :     8371815 :   return dump_context::get ().get_scope_depth ();
    1459                 :             : }
    1460                 :             : 
    1461                 :             : /* Push a nested dump scope.
    1462                 :             :    Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
    1463                 :             :    destination, if any.
    1464                 :             :    Emit a "scope" opinfo if optinfos are enabled.
    1465                 :             :    Increment the scope depth.  */
    1466                 :             : 
    1467                 :             : void
    1468                 :      514109 : dump_begin_scope (const char *name,
    1469                 :             :                   const dump_user_location_t &user_location,
    1470                 :             :                   const dump_impl_location_t &impl_location)
    1471                 :             : {
    1472                 :      514109 :   dump_context::get ().begin_scope (name, user_location, impl_location);
    1473                 :      514109 : }
    1474                 :             : 
    1475                 :             : /* Pop a nested dump scope.  */
    1476                 :             : 
    1477                 :             : void
    1478                 :      514109 : dump_end_scope ()
    1479                 :             : {
    1480                 :      514109 :   dump_context::get ().end_scope ();
    1481                 :      514109 : }
    1482                 :             : 
    1483                 :             : /* Start a dump for PHASE. Store user-supplied dump flags in
    1484                 :             :    *FLAG_PTR.  Return the number of streams opened.  Set globals
    1485                 :             :    DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
    1486                 :             :    set dump_flags appropriately for both pass dump stream and
    1487                 :             :    -fopt-info stream. */
    1488                 :             : 
    1489                 :             : int
    1490                 :   288517292 : gcc::dump_manager::
    1491                 :             : dump_start (int phase, dump_flags_t *flag_ptr)
    1492                 :             : {
    1493                 :   288517292 :   int count = 0;
    1494                 :   288517292 :   char *name;
    1495                 :   288517292 :   struct dump_file_info *dfi;
    1496                 :   288517292 :   FILE *stream;
    1497                 :   288517292 :   if (phase == TDI_none || !dump_phase_enabled_p (phase))
    1498                 :   288449174 :     return 0;
    1499                 :             : 
    1500                 :       68118 :   dfi = get_dump_file_info (phase);
    1501                 :       68118 :   name = get_dump_file_name (phase);
    1502                 :       68118 :   if (name)
    1503                 :             :     {
    1504                 :       52580 :       stream = dump_open (name, dfi->pstate < 0);
    1505                 :       52580 :       if (stream)
    1506                 :             :         {
    1507                 :       52580 :           dfi->pstate = 1;
    1508                 :       52580 :           count++;
    1509                 :             :         }
    1510                 :       52580 :       free (name);
    1511                 :       52580 :       dfi->pstream = stream;
    1512                 :       52580 :       set_dump_file (dfi->pstream);
    1513                 :             :       /* Initialize current dump flags. */
    1514                 :       52580 :       pflags = dfi->pflags;
    1515                 :             :     }
    1516                 :             : 
    1517                 :       68118 :   stream = dump_open_alternate_stream (dfi);
    1518                 :       68118 :   if (stream)
    1519                 :             :     {
    1520                 :       15702 :       dfi->alt_stream = stream;
    1521                 :       15702 :       count++;
    1522                 :       15702 :       set_alt_dump_file (dfi->alt_stream);
    1523                 :             :       /* Initialize current -fopt-info flags. */
    1524                 :       15702 :       alt_flags = dfi->alt_flags;
    1525                 :             :     }
    1526                 :             : 
    1527                 :       68118 :   if (flag_ptr)
    1528                 :       68002 :     *flag_ptr = dfi->pflags;
    1529                 :             : 
    1530                 :             :   return count;
    1531                 :             : }
    1532                 :             : 
    1533                 :             : /* Finish a tree dump for PHASE and close associated dump streams.  Also
    1534                 :             :    reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS.  */
    1535                 :             : 
    1536                 :             : void
    1537                 :   317883067 : gcc::dump_manager::
    1538                 :             : dump_finish (int phase)
    1539                 :             : {
    1540                 :   317883067 :   struct dump_file_info *dfi;
    1541                 :             : 
    1542                 :   317883067 :   if (phase < 0)
    1543                 :             :     return;
    1544                 :   288516982 :   dfi = get_dump_file_info (phase);
    1545                 :   288516982 :   if (dfi->pstream && dfi->pstream != stdout && dfi->pstream != stderr)
    1546                 :       52578 :     fclose (dfi->pstream);
    1547                 :             : 
    1548                 :   288516982 :   if (dfi->alt_stream && dfi->alt_stream != stdout && dfi->alt_stream != stderr)
    1549                 :           0 :     fclose (dfi->alt_stream);
    1550                 :             : 
    1551                 :   288516982 :   dfi->alt_stream = NULL;
    1552                 :   288516982 :   dfi->pstream = NULL;
    1553                 :   288516982 :   set_dump_file (NULL);
    1554                 :   288516982 :   set_alt_dump_file (NULL);
    1555                 :   288516982 :   dump_flags = TDF_NONE;
    1556                 :   288516982 :   alt_flags = TDF_NONE;
    1557                 :   288516982 :   pflags = TDF_NONE;
    1558                 :             : }
    1559                 :             : 
    1560                 :             : /* Begin a tree dump for PHASE. Stores any user supplied flag in
    1561                 :             :    *FLAG_PTR and returns a stream to write to. If the dump is not
    1562                 :             :    enabled, returns NULL.
    1563                 :             :    PART can be used for dump files which should be split to multiple
    1564                 :             :    parts. PART == -1 indicates dump file with no parts.
    1565                 :             :    If PART is -1, multiple calls will reopen and append to the dump file.  */
    1566                 :             : 
    1567                 :             : FILE *
    1568                 :   673363056 : dump_begin (int phase, dump_flags_t *flag_ptr, int part)
    1569                 :             : {
    1570                 :   673363056 :   return g->get_dumps ()->dump_begin (phase, flag_ptr, part);
    1571                 :             : }
    1572                 :             : 
    1573                 :             : FILE *
    1574                 :   673363056 : gcc::dump_manager::
    1575                 :             : dump_begin (int phase, dump_flags_t *flag_ptr, int part)
    1576                 :             : {
    1577                 :   673363056 :   if (phase == TDI_none || !dump_phase_enabled_p (phase))
    1578                 :   673347184 :     return NULL;
    1579                 :             : 
    1580                 :       15872 :   char *name = get_dump_file_name (phase, part);
    1581                 :       15872 :   if (!name)
    1582                 :             :     return NULL;
    1583                 :       15872 :   struct dump_file_info *dfi = get_dump_file_info (phase);
    1584                 :             : 
    1585                 :             :   /* We do not support re-opening of dump files with parts.  This would require
    1586                 :             :      tracking pstate per part of the dump file.  */
    1587                 :       19247 :   FILE *stream = dump_open (name, part != -1 || dfi->pstate < 0);
    1588                 :       15872 :   if (stream)
    1589                 :       15872 :     dfi->pstate = 1;
    1590                 :       15872 :   free (name);
    1591                 :             : 
    1592                 :       15872 :   if (flag_ptr)
    1593                 :       15584 :     *flag_ptr = dfi->pflags;
    1594                 :             : 
    1595                 :             :   /* Initialize current flags */
    1596                 :       15872 :   pflags = dfi->pflags;
    1597                 :       15872 :   return stream;
    1598                 :             : }
    1599                 :             : 
    1600                 :             : /* Returns nonzero if dump PHASE is enabled for at least one stream.
    1601                 :             :    If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
    1602                 :             :    any phase.  */
    1603                 :             : 
    1604                 :             : int
    1605                 :   954079133 : gcc::dump_manager::
    1606                 :             : dump_phase_enabled_p (int phase) const
    1607                 :             : {
    1608                 :   954079133 :   if (phase == TDI_tree_all)
    1609                 :             :     {
    1610                 :             :       size_t i;
    1611                 :           0 :       for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
    1612                 :           0 :         if (dump_files[i].pstate || dump_files[i].alt_state)
    1613                 :             :           return 1;
    1614                 :           0 :       for (i = 0; i < m_extra_dump_files_in_use; i++)
    1615                 :           0 :         if (m_extra_dump_files[i].pstate || m_extra_dump_files[i].alt_state)
    1616                 :             :           return 1;
    1617                 :             :       return 0;
    1618                 :             :     }
    1619                 :             :   else
    1620                 :             :     {
    1621                 :   954079133 :       struct dump_file_info *dfi = get_dump_file_info (phase);
    1622                 :   954163123 :       return dfi->pstate || dfi->alt_state;
    1623                 :             :     }
    1624                 :             : }
    1625                 :             : 
    1626                 :             : /* Returns nonzero if tree dump PHASE has been initialized.  */
    1627                 :             : 
    1628                 :             : int
    1629                 :   288059938 : gcc::dump_manager::
    1630                 :             : dump_initialized_p (int phase) const
    1631                 :             : {
    1632                 :   288059938 :   struct dump_file_info *dfi = get_dump_file_info (phase);
    1633                 :   288059938 :   return dfi->pstate > 0 || dfi->alt_state > 0;
    1634                 :             : }
    1635                 :             : 
    1636                 :             : /* Returns the switch name of PHASE.  */
    1637                 :             : 
    1638                 :             : const char *
    1639                 :        5582 : dump_flag_name (int phase)
    1640                 :             : {
    1641                 :        5582 :   return g->get_dumps ()->dump_flag_name (phase);
    1642                 :             : }
    1643                 :             : 
    1644                 :             : const char *
    1645                 :        5582 : gcc::dump_manager::
    1646                 :             : dump_flag_name (int phase) const
    1647                 :             : {
    1648                 :        5582 :   struct dump_file_info *dfi = get_dump_file_info (phase);
    1649                 :        5582 :   return dfi->swtch;
    1650                 :             : }
    1651                 :             : 
    1652                 :             : /* Handle -fdump-* and -fopt-info for a pass added after
    1653                 :             :    command-line options are parsed (those from plugins and
    1654                 :             :    those from backends).
    1655                 :             : 
    1656                 :             :    Because the registration of plugin/backend passes happens after the
    1657                 :             :    command-line options are parsed, the options that specify single
    1658                 :             :    pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new
    1659                 :             :    passes. Therefore we currently can only enable dumping of
    1660                 :             :    new passes when the 'dump-all' flags (e.g. -fdump-tree-all)
    1661                 :             :    are specified.  This is done here.
    1662                 :             : 
    1663                 :             :    Similarly, the saved -fopt-info options are wired up to the new pass.  */
    1664                 :             : 
    1665                 :             : void
    1666                 :         166 : gcc::dump_manager::register_pass (opt_pass *pass)
    1667                 :             : {
    1668                 :         166 :   gcc_assert (pass);
    1669                 :             : 
    1670                 :         166 :   register_one_dump_file (pass);
    1671                 :             : 
    1672                 :         166 :   dump_file_info *pass_dfi = get_dump_file_info (pass->static_pass_number);
    1673                 :         166 :   gcc_assert (pass_dfi);
    1674                 :             : 
    1675                 :         166 :   enum tree_dump_index tdi;
    1676                 :         166 :   if (pass->type == SIMPLE_IPA_PASS
    1677                 :         166 :       || pass->type == IPA_PASS)
    1678                 :             :     tdi = TDI_ipa_all;
    1679                 :         152 :   else if (pass->type == GIMPLE_PASS)
    1680                 :             :     tdi = TDI_tree_all;
    1681                 :             :   else
    1682                 :           0 :     tdi = TDI_rtl_all;
    1683                 :         166 :   const dump_file_info *tdi_dfi = get_dump_file_info (tdi);
    1684                 :         166 :   gcc_assert (tdi_dfi);
    1685                 :             : 
    1686                 :             :   /* Check if dump-all flag is specified.  */
    1687                 :         166 :   if (tdi_dfi->pstate)
    1688                 :             :     {
    1689                 :           0 :       pass_dfi->pstate = tdi_dfi->pstate;
    1690                 :           0 :       pass_dfi->pflags = tdi_dfi->pflags;
    1691                 :             :     }
    1692                 :             : 
    1693                 :         166 :   update_dfi_for_opt_info (pass_dfi);
    1694                 :         166 : }
    1695                 :             : 
    1696                 :             : /* Finish a tree dump for PHASE. STREAM is the stream created by
    1697                 :             :    dump_begin.  */
    1698                 :             : 
    1699                 :             : void
    1700                 :       15743 : dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
    1701                 :             : {
    1702                 :       15743 :   if (stream != stderr && stream != stdout)
    1703                 :       15743 :     fclose (stream);
    1704                 :       15743 : }
    1705                 :             : 
    1706                 :             : /* Enable all tree dumps with FLAGS on FILENAME.  Return number of
    1707                 :             :    enabled tree dumps.  */
    1708                 :             : 
    1709                 :             : int
    1710                 :         177 : gcc::dump_manager::
    1711                 :             : dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename)
    1712                 :             : {
    1713                 :         177 :   int n = 0;
    1714                 :         177 :   size_t i;
    1715                 :             : 
    1716                 :        2301 :   for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
    1717                 :             :     {
    1718                 :        2124 :       if (dump_files[i].dkind == dkind)
    1719                 :             :         {
    1720                 :         565 :           const char *old_filename = dump_files[i].pfilename;
    1721                 :         565 :           dump_files[i].pstate = -1;
    1722                 :         565 :           dump_files[i].pflags |= flags;
    1723                 :         565 :           n++;
    1724                 :             :           /* Override the existing filename.  */
    1725                 :         565 :           if (filename)
    1726                 :             :             {
    1727                 :           0 :               dump_files[i].pfilename = xstrdup (filename);
    1728                 :             :               /* Since it is a command-line provided file, which is
    1729                 :             :                  common to all the phases, use it in append mode.  */
    1730                 :           0 :               dump_files[i].pstate = 1;
    1731                 :             :             }
    1732                 :         565 :           if (old_filename && filename != old_filename)
    1733                 :           0 :             free (CONST_CAST (char *, old_filename));
    1734                 :             :         }
    1735                 :             :     }
    1736                 :             : 
    1737                 :       64296 :   for (i = 0; i < m_extra_dump_files_in_use; i++)
    1738                 :             :     {
    1739                 :       64119 :       if (m_extra_dump_files[i].dkind == dkind)
    1740                 :             :         {
    1741                 :       17291 :           const char *old_filename = m_extra_dump_files[i].pfilename;
    1742                 :       17291 :           m_extra_dump_files[i].pstate = -1;
    1743                 :       17291 :           m_extra_dump_files[i].pflags |= flags;
    1744                 :       17291 :           n++;
    1745                 :             :           /* Override the existing filename.  */
    1746                 :       17291 :           if (filename)
    1747                 :             :             {
    1748                 :           0 :               m_extra_dump_files[i].pfilename = xstrdup (filename);
    1749                 :             :               /* Since it is a command-line provided file, which is
    1750                 :             :                  common to all the phases, use it in append mode.  */
    1751                 :           0 :               m_extra_dump_files[i].pstate = 1;
    1752                 :             :             }
    1753                 :       17291 :           if (old_filename && filename != old_filename)
    1754                 :           0 :             free (CONST_CAST (char *, old_filename));
    1755                 :             :         }
    1756                 :             :     }
    1757                 :             : 
    1758                 :         177 :   return n;
    1759                 :             : }
    1760                 :             : 
    1761                 :             : /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
    1762                 :             :    Enable dumps with FLAGS on FILENAME.  Return the number of enabled
    1763                 :             :    dumps.  */
    1764                 :             : 
    1765                 :             : int
    1766                 :         687 : gcc::dump_manager::
    1767                 :             : opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags,
    1768                 :             :                         const char *filename)
    1769                 :             : {
    1770                 :         687 :   int n = 0;
    1771                 :             : 
    1772                 :         687 :   m_optgroup_flags = optgroup_flags;
    1773                 :         687 :   m_optinfo_flags = flags;
    1774                 :         687 :   m_optinfo_filename = xstrdup (filename);
    1775                 :             : 
    1776                 :        8931 :   for (size_t i = TDI_none + 1; i < (size_t) TDI_end; i++)
    1777                 :        8244 :     if (update_dfi_for_opt_info (&dump_files[i]))
    1778                 :           0 :       n++;
    1779                 :             : 
    1780                 :      250616 :   for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
    1781                 :      249929 :     if (update_dfi_for_opt_info (&m_extra_dump_files[i]))
    1782                 :       12915 :       n++;
    1783                 :             : 
    1784                 :         687 :   return n;
    1785                 :             : }
    1786                 :             : 
    1787                 :             : /* Use the saved -fopt-info options to update DFI.
    1788                 :             :    Return true if the dump is enabled.  */
    1789                 :             : 
    1790                 :             : bool
    1791                 :      258339 : gcc::dump_manager::update_dfi_for_opt_info (dump_file_info *dfi) const
    1792                 :             : {
    1793                 :      258339 :   gcc_assert (dfi);
    1794                 :             : 
    1795                 :      258339 :   if (!(dfi->optgroup_flags & m_optgroup_flags))
    1796                 :             :     return false;
    1797                 :             : 
    1798                 :       12917 :   const char *old_filename = dfi->alt_filename;
    1799                 :             :   /* Since this file is shared among different passes, it
    1800                 :             :      should be opened in append mode.  */
    1801                 :       12917 :   dfi->alt_state = 1;
    1802                 :       12917 :   dfi->alt_flags |= m_optinfo_flags;
    1803                 :             :   /* Override the existing filename.  */
    1804                 :       12917 :   if (m_optinfo_filename)
    1805                 :       12917 :     dfi->alt_filename = xstrdup (m_optinfo_filename);
    1806                 :       12917 :   if (old_filename && m_optinfo_filename != old_filename)
    1807                 :           0 :     free (CONST_CAST (char *, old_filename));
    1808                 :             : 
    1809                 :             :   return true;
    1810                 :             : }
    1811                 :             : 
    1812                 :             : /* Helper routine to parse -<dump format>[=filename]
    1813                 :             :    and return the corresponding dump flag.  If POS_P is non-NULL,
    1814                 :             :    assign start of filename into *POS_P.  */
    1815                 :             : 
    1816                 :             : dump_flags_t
    1817                 :       22316 : parse_dump_option (const char *option_value, const char **pos_p)
    1818                 :             : {
    1819                 :       22316 :   const char *ptr;
    1820                 :       22316 :   dump_flags_t flags;
    1821                 :             : 
    1822                 :       22316 :   ptr = option_value;
    1823                 :       22316 :   if (pos_p)
    1824                 :       22316 :     *pos_p = NULL;
    1825                 :             : 
    1826                 :             :   /* Retain "user-facing" and "internals" messages, but filter out
    1827                 :             :      those from an opt_problem being re-emitted at the top level
    1828                 :             :      (MSG_PRIORITY_REEMITTED), so as to avoid duplicate messages
    1829                 :             :      messing up scan-tree-dump-times" in DejaGnu tests.  */
    1830                 :             :   flags = MSG_PRIORITY_USER_FACING | MSG_PRIORITY_INTERNALS;
    1831                 :             : 
    1832                 :       34556 :   while (*ptr)
    1833                 :             :     {
    1834                 :             :       const struct kv_pair<dump_flags_t> *option_ptr;
    1835                 :             :       const char *end_ptr;
    1836                 :             :       const char *eq_ptr;
    1837                 :             :       unsigned length;
    1838                 :       24481 :       while (*ptr == '-')
    1839                 :       12240 :         ptr++;
    1840                 :       12241 :       end_ptr = strchr (ptr, '-');
    1841                 :       12241 :       eq_ptr = strchr (ptr, '=');
    1842                 :             : 
    1843                 :       12241 :       if (eq_ptr && (!end_ptr || end_ptr > eq_ptr))
    1844                 :             :         end_ptr = eq_ptr;
    1845                 :             : 
    1846                 :       12241 :       if (!end_ptr)
    1847                 :       11415 :         end_ptr = ptr + strlen (ptr);
    1848                 :       12241 :       length = end_ptr - ptr;
    1849                 :             : 
    1850                 :      105774 :       for (option_ptr = dump_options; option_ptr->name; option_ptr++)
    1851                 :      105773 :         if (strlen (option_ptr->name) == length
    1852                 :       34471 :             && !memcmp (option_ptr->name, ptr, length))
    1853                 :             :           {
    1854                 :       12240 :             flags |= option_ptr->value;
    1855                 :       12240 :             goto found;
    1856                 :             :           }
    1857                 :             : 
    1858                 :           1 :       if (*ptr == '=')
    1859                 :             :         {
    1860                 :             :           /* Interpret rest of the argument as a dump filename.  This
    1861                 :             :              filename overrides other command line filenames.  */
    1862                 :           1 :           if (pos_p)
    1863                 :           1 :             *pos_p = ptr + 1;
    1864                 :             :           break;
    1865                 :             :         }
    1866                 :             :       else
    1867                 :             :       {
    1868                 :           0 :         warning (0, "ignoring unknown option %q.*s",
    1869                 :             :                  length, ptr);
    1870                 :           0 :         flags = TDF_ERROR;
    1871                 :             :       }
    1872                 :             :     found:
    1873                 :             :       ptr = end_ptr;
    1874                 :             :   }
    1875                 :             : 
    1876                 :       22316 :   return flags;
    1877                 :             : }
    1878                 :             : 
    1879                 :             : /* Parse ARG as a dump switch.  Return nonzero if it is, and store the
    1880                 :             :    relevant details in the dump_files array.  */
    1881                 :             : 
    1882                 :             : int
    1883                 :     8392160 : gcc::dump_manager::
    1884                 :             : dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
    1885                 :             : {
    1886                 :     8392160 :   const char *option_value;
    1887                 :     8392160 :   dump_flags_t flags = TDF_NONE;
    1888                 :             : 
    1889                 :     8392160 :   if (doglob && !dfi->glob)
    1890                 :             :     return 0;
    1891                 :             : 
    1892                 :     8178656 :   option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
    1893                 :       22476 :   if (!option_value)
    1894                 :             :     return 0;
    1895                 :             : 
    1896                 :       22476 :   if (*option_value && *option_value != '-' && *option_value != '=')
    1897                 :             :     return 0;
    1898                 :             : 
    1899                 :       22316 :   const char *filename;
    1900                 :       22316 :   flags = parse_dump_option (option_value, &filename);
    1901                 :       22316 :   if (filename)
    1902                 :             :     {
    1903                 :           1 :       if (dfi->pfilename)
    1904                 :           0 :   free (CONST_CAST (char *, dfi->pfilename));
    1905                 :           1 :       dfi->pfilename = xstrdup (filename);
    1906                 :             :     }
    1907                 :             : 
    1908                 :       22316 :   dfi->pstate = -1;
    1909                 :       22316 :   dfi->pflags |= flags;
    1910                 :             : 
    1911                 :             :   /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
    1912                 :             :      known dumps.  */
    1913                 :       22316 :   if (dfi->suffix == NULL)
    1914                 :         173 :     dump_enable_all (dfi->dkind, dfi->pflags, dfi->pfilename);
    1915                 :             : 
    1916                 :             :   return 1;
    1917                 :             : }
    1918                 :             : 
    1919                 :             : void
    1920                 :       20995 : gcc::dump_manager::
    1921                 :             : dump_switch_p (const char *arg)
    1922                 :             : {
    1923                 :       20995 :   size_t i;
    1924                 :       20995 :   int any = 0;
    1925                 :             : 
    1926                 :      272935 :   for (i = TDI_none + 1; i != TDI_end; i++)
    1927                 :      251940 :     any |= dump_switch_p_1 (arg, &dump_files[i], false);
    1928                 :             : 
    1929                 :             :   /* Don't glob if we got a hit already */
    1930                 :       20995 :   if (!any)
    1931                 :      231296 :     for (i = TDI_none + 1; i != TDI_end; i++)
    1932                 :      213504 :       any |= dump_switch_p_1 (arg, &dump_files[i], true);
    1933                 :             : 
    1934                 :     7653412 :   for (i = 0; i < m_extra_dump_files_in_use; i++)
    1935                 :     7632417 :     any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], false);
    1936                 :             : 
    1937                 :       20995 :   if (!any)
    1938                 :      295110 :     for (i = 0; i < m_extra_dump_files_in_use; i++)
    1939                 :      294299 :       any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], true);
    1940                 :             : 
    1941                 :         811 :   if (!any)
    1942                 :             :     {
    1943                 :           6 :       auto_vec<const char *> candidates;
    1944                 :          78 :       for (size_t i = TDI_none + 1; i != TDI_end; i++)
    1945                 :          72 :         candidates.safe_push (dump_files[i].swtch);
    1946                 :        2178 :       for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
    1947                 :        2172 :         candidates.safe_push (m_extra_dump_files[i].swtch);
    1948                 :           6 :       const char *hint = find_closest_string (arg, &candidates);
    1949                 :           6 :       if (hint)
    1950                 :           1 :         error ("unrecognized command-line option %<-fdump-%s%>; "
    1951                 :             :                "did you mean %<-fdump-%s%>?", arg, hint);
    1952                 :             :       else
    1953                 :           5 :         error ("unrecognized command-line option %<-fdump-%s%>", arg);
    1954                 :           6 :     }
    1955                 :       20995 : }
    1956                 :             : 
    1957                 :             : /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
    1958                 :             :    and filename.  Return non-zero if it is a recognized switch.  */
    1959                 :             : 
    1960                 :             : static int
    1961                 :         687 : opt_info_switch_p_1 (const char *arg, dump_flags_t *flags,
    1962                 :             :                      optgroup_flags_t *optgroup_flags, char **filename)
    1963                 :             : {
    1964                 :         687 :   const char *option_value;
    1965                 :         687 :   const char *ptr;
    1966                 :             : 
    1967                 :         687 :   option_value = arg;
    1968                 :         687 :   ptr = option_value;
    1969                 :             : 
    1970                 :         687 :   *filename = NULL;
    1971                 :             : 
    1972                 :             :   /* Default to filtering out "internals" messages, and retaining
    1973                 :             :      "user-facing" messages, and those from an opt_problem being
    1974                 :             :      re-emitted at the top level.  */
    1975                 :         687 :   *flags = MSG_PRIORITY_USER_FACING | MSG_PRIORITY_REEMITTED;
    1976                 :             : 
    1977                 :         687 :   *optgroup_flags = OPTGROUP_NONE;
    1978                 :             : 
    1979                 :         687 :   if (!ptr)
    1980                 :             :     return 1;       /* Handle '-fopt-info' without any additional options.  */
    1981                 :             : 
    1982                 :        2036 :   while (*ptr)
    1983                 :             :     {
    1984                 :             :       const char *end_ptr;
    1985                 :             :       const char *eq_ptr;
    1986                 :             :       unsigned length;
    1987                 :             : 
    1988                 :        2015 :       while (*ptr == '-')
    1989                 :         664 :         ptr++;
    1990                 :        1351 :       end_ptr = strchr (ptr, '-');
    1991                 :        1351 :       eq_ptr = strchr (ptr, '=');
    1992                 :             : 
    1993                 :        1351 :       if (eq_ptr && (!end_ptr || eq_ptr < end_ptr))
    1994                 :             :         end_ptr = eq_ptr;
    1995                 :        1348 :       else if (!end_ptr)
    1996                 :         685 :         end_ptr = ptr + strlen (ptr);
    1997                 :        1351 :       length = end_ptr - ptr;
    1998                 :             : 
    1999                 :        6342 :       for (const kv_pair<dump_flags_t> *option_ptr = optinfo_verbosity_options;
    2000                 :        6342 :            option_ptr->name; option_ptr++)
    2001                 :        5669 :         if (strlen (option_ptr->name) == length
    2002                 :        1351 :             && !memcmp (option_ptr->name, ptr, length))
    2003                 :             :           {
    2004                 :         678 :             *flags |= option_ptr->value;
    2005                 :         678 :             goto found;
    2006                 :             :           }
    2007                 :             : 
    2008                 :        2011 :       for (const kv_pair<optgroup_flags_t> *option_ptr = optgroup_options;
    2009                 :        2684 :            option_ptr->name; option_ptr++)
    2010                 :        2683 :         if (strlen (option_ptr->name) == length
    2011                 :        1347 :             && !memcmp (option_ptr->name, ptr, length))
    2012                 :             :           {
    2013                 :         672 :             *optgroup_flags |= option_ptr->value;
    2014                 :         672 :             goto found;
    2015                 :             :           }
    2016                 :             : 
    2017                 :           1 :       if (*ptr == '=')
    2018                 :             :         {
    2019                 :             :           /* Interpret rest of the argument as a dump filename.  This
    2020                 :             :              filename overrides other command line filenames.  */
    2021                 :           1 :           *filename = xstrdup (ptr + 1);
    2022                 :           1 :           break;
    2023                 :             :         }
    2024                 :             :       else
    2025                 :             :         {
    2026                 :           0 :           warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
    2027                 :             :                    length, ptr, arg);
    2028                 :           0 :           return 0;
    2029                 :             :         }
    2030                 :             :     found:;
    2031                 :             :       ptr = end_ptr;
    2032                 :             :     }
    2033                 :             : 
    2034                 :             :   return 1;
    2035                 :             : }
    2036                 :             : 
    2037                 :             : /* Return non-zero if ARG is a recognized switch for
    2038                 :             :    -fopt-info. Return zero otherwise.  */
    2039                 :             : 
    2040                 :             : int
    2041                 :         687 : opt_info_switch_p (const char *arg)
    2042                 :             : {
    2043                 :         687 :   dump_flags_t flags;
    2044                 :         687 :   optgroup_flags_t optgroup_flags;
    2045                 :         687 :   char *filename;
    2046                 :         687 :   static char *file_seen = NULL;
    2047                 :         687 :   gcc::dump_manager *dumps = g->get_dumps ();
    2048                 :             : 
    2049                 :         687 :   if (!opt_info_switch_p_1 (arg, &flags, &optgroup_flags, &filename))
    2050                 :             :     return 0;
    2051                 :             : 
    2052                 :         687 :   if (!filename)
    2053                 :         686 :     filename = xstrdup ("stderr");
    2054                 :             : 
    2055                 :             :   /* Bail out if a different filename has been specified.  */
    2056                 :         687 :   if (file_seen && strcmp (file_seen, filename))
    2057                 :             :     {
    2058                 :           0 :       warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
    2059                 :             :                arg);
    2060                 :           0 :       return 1;
    2061                 :             :     }
    2062                 :             : 
    2063                 :         687 :   file_seen = xstrdup (filename);
    2064                 :         687 :   if (!(flags & MSG_ALL_KINDS))
    2065                 :          11 :     flags |= MSG_OPTIMIZED_LOCATIONS;
    2066                 :         687 :   if (!optgroup_flags)
    2067                 :          15 :     optgroup_flags = OPTGROUP_ALL;
    2068                 :             : 
    2069                 :         687 :   return dumps->opt_info_enable_passes (optgroup_flags, flags, filename);
    2070                 :             : }
    2071                 :             : 
    2072                 :             : /* Print basic block on the dump streams.  */
    2073                 :             : 
    2074                 :             : void
    2075                 :           0 : dump_basic_block (dump_flags_t dump_kind, basic_block bb, int indent)
    2076                 :             : {
    2077                 :           0 :   if (dump_file
    2078                 :           0 :       && dump_context::get ().apply_dump_filter_p (dump_kind, pflags))
    2079                 :           0 :     dump_bb (dump_file, bb, indent, TDF_DETAILS);
    2080                 :           0 :   if (alt_dump_file
    2081                 :           0 :       && dump_context::get ().apply_dump_filter_p (dump_kind, alt_flags))
    2082                 :           0 :     dump_bb (alt_dump_file, bb, indent, TDF_DETAILS);
    2083                 :           0 : }
    2084                 :             : 
    2085                 :             : /* Dump FUNCTION_DECL FN as tree dump PHASE.  */
    2086                 :             : 
    2087                 :             : void
    2088                 :     3020466 : dump_function (int phase, tree fn)
    2089                 :             : {
    2090                 :     3020466 :   FILE *stream;
    2091                 :     3020466 :   dump_flags_t flags;
    2092                 :             : 
    2093                 :     3020466 :   stream = dump_begin (phase, &flags);
    2094                 :     3020466 :   if (stream)
    2095                 :             :     {
    2096                 :        9834 :       dump_function_to_file (fn, stream, flags);
    2097                 :        9834 :       dump_end (phase, stream);
    2098                 :             :     }
    2099                 :     3020466 : }
    2100                 :             : 
    2101                 :             : /* Enable RTL dump for all the RTL passes.  */
    2102                 :             : 
    2103                 :             : bool
    2104                 :           4 : enable_rtl_dump_file (void)
    2105                 :             : {
    2106                 :           4 :   gcc::dump_manager *dumps = g->get_dumps ();
    2107                 :           4 :   int num_enabled =
    2108                 :           4 :     dumps->dump_enable_all (DK_rtl, dump_flags_t (TDF_DETAILS) | TDF_BLOCKS,
    2109                 :             :                             NULL);
    2110                 :           4 :   return num_enabled > 0;
    2111                 :             : }
    2112                 :             : 
    2113                 :             : /* debug_dump_context's ctor.  Temporarily override the dump_context
    2114                 :             :    (to forcibly enable output to stderr).  */
    2115                 :             : 
    2116                 :           0 : debug_dump_context::debug_dump_context (FILE *f)
    2117                 :           0 : : m_context (),
    2118                 :           0 :   m_saved (&dump_context::get ()),
    2119                 :           0 :   m_saved_flags (dump_flags),
    2120                 :           0 :   m_saved_pflags (pflags),
    2121                 :           0 :   m_saved_file (dump_file)
    2122                 :             : {
    2123                 :           0 :   set_dump_file (f);
    2124                 :           0 :   dump_context::s_current = &m_context;
    2125                 :           0 :   pflags = dump_flags = MSG_ALL_KINDS | MSG_ALL_PRIORITIES;
    2126                 :           0 :   dump_context::get ().refresh_dumps_are_enabled ();
    2127                 :           0 : }
    2128                 :             : 
    2129                 :             : /* debug_dump_context's dtor.  Restore the saved dump_context.  */
    2130                 :             : 
    2131                 :           0 : debug_dump_context::~debug_dump_context ()
    2132                 :             : {
    2133                 :           0 :   set_dump_file (m_saved_file);
    2134                 :           0 :   dump_context::s_current = m_saved;
    2135                 :           0 :   dump_flags = m_saved_flags;
    2136                 :           0 :   pflags = m_saved_pflags;
    2137                 :           0 :   dump_context::get ().refresh_dumps_are_enabled ();
    2138                 :           0 : }
    2139                 :             : 
    2140                 :             : 
    2141                 :             : #if CHECKING_P
    2142                 :             : 
    2143                 :             : namespace selftest {
    2144                 :             : 
    2145                 :             : /* temp_dump_context's ctor.  Temporarily override the dump_context
    2146                 :             :    (to forcibly enable optinfo-generation).  */
    2147                 :             : 
    2148                 :        2422 : temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo,
    2149                 :             :                                       bool forcibly_enable_dumping,
    2150                 :        2422 :                                       dump_flags_t test_pp_flags)
    2151                 :        2422 : : m_context (),
    2152                 :        2422 :   m_saved (&dump_context::get ())
    2153                 :             : {
    2154                 :        2422 :   dump_context::s_current = &m_context;
    2155                 :        2422 :   if (forcibly_enable_optinfo)
    2156                 :        1243 :     m_context.set_json_writer (new optrecord_json_writer ());
    2157                 :             :   /* Conditionally enable the test dump, so that we can verify both the
    2158                 :             :      dump_enabled_p and the !dump_enabled_p cases in selftests.  */
    2159                 :        2422 :   if (forcibly_enable_dumping)
    2160                 :             :     {
    2161                 :        2251 :       m_context.m_test_pp = &m_pp;
    2162                 :        2251 :       m_context.m_test_pp_flags = test_pp_flags;
    2163                 :             :     }
    2164                 :             : 
    2165                 :        2422 :   dump_context::get ().refresh_dumps_are_enabled ();
    2166                 :        2422 : }
    2167                 :             : 
    2168                 :             : /* temp_dump_context's dtor.  Restore the saved dump_context.  */
    2169                 :             : 
    2170                 :        2422 : temp_dump_context::~temp_dump_context ()
    2171                 :             : {
    2172                 :        2422 :   m_context.set_json_writer (NULL);
    2173                 :             : 
    2174                 :        2422 :   dump_context::s_current = m_saved;
    2175                 :             : 
    2176                 :        2422 :   dump_context::get ().refresh_dumps_are_enabled ();
    2177                 :        2422 : }
    2178                 :             : 
    2179                 :             : /* 0-terminate the text dumped so far, and return it.  */
    2180                 :             : 
    2181                 :             : const char *
    2182                 :        2302 : temp_dump_context::get_dumped_text ()
    2183                 :             : {
    2184                 :        2302 :   return pp_formatted_text (&m_pp);
    2185                 :             : }
    2186                 :             : 
    2187                 :             : /* Verify that IMPL_LOC is within EXPECTED_FILE at EXPECTED_LINE,
    2188                 :             :    from EXPECTED_FUNCTION, using LOC for the location of any failure,
    2189                 :             :    provided that the build compiler is sufficiently recent.  */
    2190                 :             : 
    2191                 :             : static void
    2192                 :         908 : assert_impl_location_eq (const location &loc ATTRIBUTE_UNUSED,
    2193                 :             :                          const dump_impl_location_t &impl_loc ATTRIBUTE_UNUSED,
    2194                 :             :                          const char *expected_file ATTRIBUTE_UNUSED,
    2195                 :             :                          int expected_line ATTRIBUTE_UNUSED,
    2196                 :             :                          const char *expected_function ATTRIBUTE_UNUSED)
    2197                 :             : {
    2198                 :             : #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
    2199                 :         908 :   ASSERT_STR_CONTAINS_AT (loc, impl_loc.m_file, expected_file);
    2200                 :         908 :   ASSERT_EQ_AT (loc, impl_loc.m_line, expected_line);
    2201                 :         908 :   ASSERT_STR_CONTAINS_AT (loc, impl_loc.m_function, expected_function);
    2202                 :             : #endif
    2203                 :         908 : }
    2204                 :             : 
    2205                 :             : /* Verify that IMPL_LOC is within EXPECTED_FILE at EXPECTED_LINE,
    2206                 :             :    from EXPECTED_FUNCTION, provided that the build compiler is
    2207                 :             :    sufficiently recent.  */
    2208                 :             : 
    2209                 :             : #define ASSERT_IMPL_LOCATION_EQ(IMPL_LOC, EXPECTED_FILE, EXPECTED_LINE, \
    2210                 :             :                                 EXPECTED_FUNCTION)                      \
    2211                 :             :   SELFTEST_BEGIN_STMT                                                   \
    2212                 :             :     assert_impl_location_eq (SELFTEST_LOCATION, IMPL_LOC,               \
    2213                 :             :                              EXPECTED_FILE, EXPECTED_LINE,              \
    2214                 :             :                              EXPECTED_FUNCTION);                        \
    2215                 :             :   SELFTEST_END_STMT
    2216                 :             : 
    2217                 :             : /* Verify that the dump_location_t constructors capture the source location
    2218                 :             :    at which they were called (provided that the build compiler is sufficiently
    2219                 :             :    recent).  */
    2220                 :             : 
    2221                 :             : static void
    2222                 :           4 : test_impl_location ()
    2223                 :             : {
    2224                 :             :   /* Default ctor.  */
    2225                 :           4 :   {
    2226                 :           4 :     dump_location_t loc;
    2227                 :           4 :     const int expected_line = __LINE__ - 1;
    2228                 :           4 :     ASSERT_IMPL_LOCATION_EQ (loc.get_impl_location (),
    2229                 :             :                              "dumpfile.cc", expected_line, "test_impl_location");
    2230                 :             :   }
    2231                 :             : 
    2232                 :             :   /* Constructing from a gimple.  */
    2233                 :           4 :   {
    2234                 :           4 :     dump_location_t loc ((gimple *)NULL);
    2235                 :           4 :     const int expected_line = __LINE__ - 1;
    2236                 :           4 :     ASSERT_IMPL_LOCATION_EQ (loc.get_impl_location (),
    2237                 :             :                              "dumpfile.cc", expected_line, "test_impl_location");
    2238                 :             :   }
    2239                 :             : 
    2240                 :             :   /* Constructing from an rtx_insn.  */
    2241                 :           4 :   {
    2242                 :           4 :     dump_location_t loc ((rtx_insn *)NULL);
    2243                 :           4 :     const int expected_line = __LINE__ - 1;
    2244                 :           4 :     ASSERT_IMPL_LOCATION_EQ (loc.get_impl_location (),
    2245                 :             :                              "dumpfile.cc", expected_line, "test_impl_location");
    2246                 :             :   }
    2247                 :           4 : }
    2248                 :             : 
    2249                 :             : /* Verify that the text dumped so far in CONTEXT equals
    2250                 :             :    EXPECTED_TEXT, using LOC for the location of any failure.
    2251                 :             :    As a side-effect, the internal buffer is 0-terminated.  */
    2252                 :             : 
    2253                 :             : void
    2254                 :        2302 : verify_dumped_text (const location &loc,
    2255                 :             :                     temp_dump_context *context,
    2256                 :             :                     const char *expected_text)
    2257                 :             : {
    2258                 :        2302 :   gcc_assert (context);
    2259                 :        2302 :   ASSERT_STREQ_AT (loc, context->get_dumped_text (),
    2260                 :             :                    expected_text);
    2261                 :        2302 : }
    2262                 :             : 
    2263                 :             : /* Verify that ITEM has the expected values.  */
    2264                 :             : 
    2265                 :             : void
    2266                 :        2296 : verify_item (const location &loc,
    2267                 :             :              const optinfo_item *item,
    2268                 :             :              enum optinfo_item_kind expected_kind,
    2269                 :             :              location_t expected_location,
    2270                 :             :              const char *expected_text)
    2271                 :             : {
    2272                 :        2296 :   ASSERT_EQ_AT (loc, item->get_kind (), expected_kind);
    2273                 :        2296 :   ASSERT_EQ_AT (loc, item->get_location (), expected_location);
    2274                 :        2296 :   ASSERT_STREQ_AT (loc, item->get_text (), expected_text);
    2275                 :        2296 : }
    2276                 :             : 
    2277                 :             : /* Verify that calls to the dump_* API are captured and consolidated into
    2278                 :             :    optimization records. */
    2279                 :             : 
    2280                 :             : static void
    2281                 :          96 : test_capture_of_dump_calls (const line_table_case &case_)
    2282                 :             : {
    2283                 :             :   /* Generate a location_t for testing.  */
    2284                 :          96 :   line_table_test ltt (case_);
    2285                 :          96 :   linemap_add (line_table, LC_ENTER, false, "test.txt", 0);
    2286                 :          96 :   linemap_line_start (line_table, 5, 100);
    2287                 :          96 :   linemap_add (line_table, LC_LEAVE, false, NULL, 0);
    2288                 :          96 :   location_t decl_loc = linemap_position_for_column (line_table, 8);
    2289                 :          96 :   location_t stmt_loc = linemap_position_for_column (line_table, 10);
    2290                 :          96 :   if (stmt_loc > LINE_MAP_MAX_LOCATION_WITH_COLS)
    2291                 :          40 :     return;
    2292                 :             : 
    2293                 :          56 :   dump_user_location_t loc = dump_user_location_t::from_location_t (stmt_loc);
    2294                 :             : 
    2295                 :          56 :   gimple *stmt = gimple_build_return (NULL);
    2296                 :          56 :   gimple_set_location (stmt, stmt_loc);
    2297                 :             : 
    2298                 :          56 :   tree test_decl = build_decl (decl_loc, FUNCTION_DECL,
    2299                 :             :                                get_identifier ("test_decl"),
    2300                 :             :                                build_function_type_list (void_type_node,
    2301                 :             :                                                          NULL_TREE));
    2302                 :             : 
    2303                 :          56 :   symbol_table_test tmp_symtab;
    2304                 :             : 
    2305                 :          56 :   cgraph_node *node = cgraph_node::get_create (test_decl);
    2306                 :          56 :   gcc_assert (node);
    2307                 :             : 
    2308                 :             :   /* Run all tests twice, with and then without optinfo enabled, to ensure
    2309                 :             :      that immediate destinations vs optinfo-based destinations both
    2310                 :             :      work, independently of each other, with no leaks.  */
    2311                 :         168 :   for (int i = 0 ; i < 2; i++)
    2312                 :             :     {
    2313                 :         112 :       bool with_optinfo = (i == 0);
    2314                 :             : 
    2315                 :             :       /* Test of dump_printf.  */
    2316                 :         112 :       {
    2317                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2318                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2319                 :         112 :         dump_printf (MSG_NOTE, "int: %i str: %s", 42, "foo");
    2320                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2321                 :             : 
    2322                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "int: 42 str: foo");
    2323                 :         112 :         if (with_optinfo)
    2324                 :             :           {
    2325                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2326                 :          56 :             ASSERT_TRUE (info != NULL);
    2327                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2328                 :          56 :             ASSERT_EQ (info->num_items (), 1);
    2329                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "int: 42 str: foo");
    2330                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2331                 :             :                                      "dumpfile.cc", expected_impl_line,
    2332                 :             :                                      "test_capture_of_dump_calls");
    2333                 :             :           }
    2334                 :         112 :       }
    2335                 :             : 
    2336                 :             :       /* Test of dump_printf with %T.  */
    2337                 :         112 :       {
    2338                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2339                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2340                 :         112 :         dump_printf (MSG_NOTE, "tree: %T", integer_zero_node);
    2341                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2342                 :             : 
    2343                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "tree: 0");
    2344                 :         112 :         if (with_optinfo)
    2345                 :             :           {
    2346                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2347                 :          56 :             ASSERT_TRUE (info != NULL);
    2348                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2349                 :          56 :             ASSERT_EQ (info->num_items (), 2);
    2350                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "tree: ");
    2351                 :          56 :             ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
    2352                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2353                 :             :                                      "dumpfile.cc", expected_impl_line,
    2354                 :             :                                      "test_capture_of_dump_calls");
    2355                 :             :           }
    2356                 :         112 :       }
    2357                 :             : 
    2358                 :             :       /* Test of dump_printf with %E.  */
    2359                 :         112 :       {
    2360                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2361                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2362                 :         112 :         dump_printf (MSG_NOTE, "gimple: %E", stmt);
    2363                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2364                 :             : 
    2365                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "gimple: return;");
    2366                 :         112 :         if (with_optinfo)
    2367                 :             :           {
    2368                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2369                 :          56 :             ASSERT_TRUE (info != NULL);
    2370                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2371                 :          56 :             ASSERT_EQ (info->num_items (), 2);
    2372                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
    2373                 :          56 :             ASSERT_IS_GIMPLE (info->get_item (1), stmt_loc, "return;");
    2374                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2375                 :             :                                      "dumpfile.cc", expected_impl_line,
    2376                 :             :                                      "test_capture_of_dump_calls");
    2377                 :             :           }
    2378                 :         112 :       }
    2379                 :             : 
    2380                 :             :       /* Test of dump_printf with %G.  */
    2381                 :         112 :       {
    2382                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2383                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2384                 :         112 :         dump_printf (MSG_NOTE, "gimple: %G", stmt);
    2385                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2386                 :             : 
    2387                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "gimple: return;\n");
    2388                 :         112 :         if (with_optinfo)
    2389                 :             :           {
    2390                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2391                 :          56 :             ASSERT_TRUE (info != NULL);
    2392                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2393                 :          56 :             ASSERT_EQ (info->num_items (), 2);
    2394                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
    2395                 :          56 :             ASSERT_IS_GIMPLE (info->get_item (1), stmt_loc, "return;\n");
    2396                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2397                 :             :                                      "dumpfile.cc", expected_impl_line,
    2398                 :             :                                      "test_capture_of_dump_calls");
    2399                 :             :           }
    2400                 :         112 :       }
    2401                 :             : 
    2402                 :             :       /* Test of dump_printf with %C.  */
    2403                 :         112 :       {
    2404                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2405                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2406                 :         112 :         dump_printf (MSG_NOTE, "node: %C", node);
    2407                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2408                 :             : 
    2409                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "node: test_decl/1");
    2410                 :         112 :         if (with_optinfo)
    2411                 :             :           {
    2412                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2413                 :          56 :             ASSERT_TRUE (info != NULL);
    2414                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2415                 :          56 :             ASSERT_EQ (info->num_items (), 2);
    2416                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "node: ");
    2417                 :          56 :             ASSERT_IS_SYMTAB_NODE (info->get_item (1), decl_loc, "test_decl/1");
    2418                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2419                 :             :                                      "dumpfile.cc", expected_impl_line,
    2420                 :             :                                      "test_capture_of_dump_calls");
    2421                 :             :           }
    2422                 :         112 :       }
    2423                 :             : 
    2424                 :             :       /* dump_print_loc with multiple format codes.  This tests various
    2425                 :             :          things:
    2426                 :             :          - intermingling of text, format codes handled by the base
    2427                 :             :          pretty_printer, and dump-specific format codes
    2428                 :             :          - multiple dump-specific format codes: some consecutive, others
    2429                 :             :          separated by text, trailing text after the final one.  */
    2430                 :         112 :       {
    2431                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2432                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2433                 :         112 :         dump_printf_loc (MSG_NOTE, loc, "before %T and %T"
    2434                 :             :                          " %i consecutive %E%E after\n",
    2435                 :             :                          integer_zero_node, test_decl, 42, stmt, stmt);
    2436                 :             : 
    2437                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp,
    2438                 :             :                                "test.txt:5:10: note: before 0 and test_decl"
    2439                 :             :                                " 42 consecutive return;return; after\n");
    2440                 :         112 :         if (with_optinfo)
    2441                 :             :           {
    2442                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2443                 :          56 :             ASSERT_TRUE (info != NULL);
    2444                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2445                 :          56 :             ASSERT_EQ (info->num_items (), 8);
    2446                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "before ");
    2447                 :          56 :             ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
    2448                 :          56 :             ASSERT_IS_TEXT (info->get_item (2), " and ");
    2449                 :          56 :             ASSERT_IS_TREE (info->get_item (3), UNKNOWN_LOCATION, "test_decl");
    2450                 :          56 :             ASSERT_IS_TEXT (info->get_item (4), " 42 consecutive ");
    2451                 :          56 :             ASSERT_IS_GIMPLE (info->get_item (5), stmt_loc, "return;");
    2452                 :          56 :             ASSERT_IS_GIMPLE (info->get_item (6), stmt_loc, "return;");
    2453                 :          56 :             ASSERT_IS_TEXT (info->get_item (7), " after\n");
    2454                 :             :             /* We don't ASSERT_IMPL_LOCATION_EQ here, to avoid having to
    2455                 :             :                enforce at which exact line the multiline dump_printf_loc
    2456                 :             :                occurred.  */
    2457                 :             :           }
    2458                 :         112 :       }
    2459                 :             : 
    2460                 :             :       /* Tree, via dump_generic_expr.  */
    2461                 :         112 :       {
    2462                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2463                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2464                 :         112 :         dump_printf_loc (MSG_NOTE, loc, "test of tree: ");
    2465                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2466                 :         112 :         dump_generic_expr (MSG_NOTE, TDF_SLIM, integer_zero_node);
    2467                 :             : 
    2468                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: test of tree: 0");
    2469                 :         112 :         if (with_optinfo)
    2470                 :             :           {
    2471                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2472                 :          56 :             ASSERT_TRUE (info != NULL);
    2473                 :          56 :             ASSERT_EQ (info->get_location_t (), stmt_loc);
    2474                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2475                 :          56 :             ASSERT_EQ (info->num_items (), 2);
    2476                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "test of tree: ");
    2477                 :          56 :             ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
    2478                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2479                 :             :                                      "dumpfile.cc", expected_impl_line,
    2480                 :             :                                      "test_capture_of_dump_calls");
    2481                 :             :           }
    2482                 :         112 :       }
    2483                 :             : 
    2484                 :             :       /* Tree, via dump_generic_expr_loc.  */
    2485                 :         112 :       {
    2486                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2487                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2488                 :         112 :         dump_generic_expr_loc (MSG_NOTE, loc, TDF_SLIM, integer_one_node);
    2489                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2490                 :             : 
    2491                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: 1");
    2492                 :         112 :         if (with_optinfo)
    2493                 :             :           {
    2494                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2495                 :          56 :             ASSERT_TRUE (info != NULL);
    2496                 :          56 :             ASSERT_EQ (info->get_location_t (), stmt_loc);
    2497                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2498                 :          56 :             ASSERT_EQ (info->num_items (), 1);
    2499                 :          56 :             ASSERT_IS_TREE (info->get_item (0), UNKNOWN_LOCATION, "1");
    2500                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2501                 :             :                                      "dumpfile.cc", expected_impl_line,
    2502                 :             :                                      "test_capture_of_dump_calls");
    2503                 :             :           }
    2504                 :         112 :       }
    2505                 :             : 
    2506                 :             :       /* Gimple.  */
    2507                 :         112 :       {
    2508                 :             :         /* dump_gimple_stmt_loc.  */
    2509                 :         112 :         {
    2510                 :         112 :           temp_dump_context tmp (with_optinfo, true,
    2511                 :         112 :                                  MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2512                 :         112 :           dump_gimple_stmt_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
    2513                 :         112 :           const int expected_impl_line = __LINE__ - 1;
    2514                 :             : 
    2515                 :         112 :           ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: return;\n");
    2516                 :         112 :           if (with_optinfo)
    2517                 :             :             {
    2518                 :          56 :               optinfo *info = tmp.get_pending_optinfo ();
    2519                 :          56 :               ASSERT_TRUE (info != NULL);
    2520                 :          56 :               ASSERT_EQ (info->num_items (), 1);
    2521                 :          56 :               ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;\n");
    2522                 :          56 :               ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2523                 :             :                                        "dumpfile.cc", expected_impl_line,
    2524                 :             :                                        "test_capture_of_dump_calls");
    2525                 :             :             }
    2526                 :         112 :         }
    2527                 :             : 
    2528                 :             :         /* dump_gimple_stmt.  */
    2529                 :         112 :         {
    2530                 :         112 :           temp_dump_context tmp (with_optinfo, true,
    2531                 :         112 :                                  MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2532                 :         112 :           dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 2);
    2533                 :         112 :           const int expected_impl_line = __LINE__ - 1;
    2534                 :             : 
    2535                 :         112 :           ASSERT_DUMPED_TEXT_EQ (tmp, "return;\n");
    2536                 :         112 :           if (with_optinfo)
    2537                 :             :             {
    2538                 :          56 :               optinfo *info = tmp.get_pending_optinfo ();
    2539                 :          56 :               ASSERT_TRUE (info != NULL);
    2540                 :          56 :               ASSERT_EQ (info->num_items (), 1);
    2541                 :          56 :               ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;\n");
    2542                 :          56 :               ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2543                 :             :                                        "dumpfile.cc", expected_impl_line,
    2544                 :             :                                        "test_capture_of_dump_calls");
    2545                 :             :             }
    2546                 :         112 :         }
    2547                 :             : 
    2548                 :             :         /* dump_gimple_expr_loc.  */
    2549                 :         112 :         {
    2550                 :         112 :           temp_dump_context tmp (with_optinfo, true,
    2551                 :         112 :                                  MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2552                 :         112 :           dump_gimple_expr_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
    2553                 :         112 :           const int expected_impl_line = __LINE__ - 1;
    2554                 :             : 
    2555                 :         112 :           ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: return;");
    2556                 :         112 :           if (with_optinfo)
    2557                 :             :             {
    2558                 :          56 :               optinfo *info = tmp.get_pending_optinfo ();
    2559                 :          56 :               ASSERT_TRUE (info != NULL);
    2560                 :          56 :               ASSERT_EQ (info->num_items (), 1);
    2561                 :          56 :               ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;");
    2562                 :          56 :               ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2563                 :             :                                        "dumpfile.cc", expected_impl_line,
    2564                 :             :                                        "test_capture_of_dump_calls");
    2565                 :             :             }
    2566                 :         112 :         }
    2567                 :             : 
    2568                 :             :         /* dump_gimple_expr.  */
    2569                 :         112 :         {
    2570                 :         112 :           temp_dump_context tmp (with_optinfo, true,
    2571                 :         112 :                                  MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2572                 :         112 :           dump_gimple_expr (MSG_NOTE, TDF_SLIM, stmt, 2);
    2573                 :         112 :           const int expected_impl_line = __LINE__ - 1;
    2574                 :             : 
    2575                 :         112 :           ASSERT_DUMPED_TEXT_EQ (tmp, "return;");
    2576                 :         112 :           if (with_optinfo)
    2577                 :             :             {
    2578                 :          56 :               optinfo *info = tmp.get_pending_optinfo ();
    2579                 :          56 :               ASSERT_TRUE (info != NULL);
    2580                 :          56 :               ASSERT_EQ (info->num_items (), 1);
    2581                 :          56 :               ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;");
    2582                 :          56 :               ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2583                 :             :                                        "dumpfile.cc", expected_impl_line,
    2584                 :             :                                        "test_capture_of_dump_calls");
    2585                 :             :             }
    2586                 :         112 :         }
    2587                 :             :       }
    2588                 :             : 
    2589                 :             :       /* symtab_node.  */
    2590                 :         112 :       {
    2591                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2592                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2593                 :         112 :         dump_symtab_node (MSG_NOTE, node);
    2594                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2595                 :             : 
    2596                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "test_decl/1");
    2597                 :         112 :         if (with_optinfo)
    2598                 :             :           {
    2599                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2600                 :          56 :             ASSERT_TRUE (info != NULL);
    2601                 :          56 :             ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
    2602                 :          56 :             ASSERT_EQ (info->num_items (), 1);
    2603                 :          56 :             ASSERT_IS_SYMTAB_NODE (info->get_item (0), decl_loc, "test_decl/1");
    2604                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2605                 :             :                                      "dumpfile.cc", expected_impl_line,
    2606                 :             :                                      "test_capture_of_dump_calls");
    2607                 :             :           }
    2608                 :         112 :       }
    2609                 :             : 
    2610                 :             :       /* poly_int.  */
    2611                 :         112 :       {
    2612                 :         112 :         temp_dump_context tmp (with_optinfo, true,
    2613                 :         112 :                                MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2614                 :         112 :         dump_dec (MSG_NOTE, poly_int64 (42));
    2615                 :         112 :         const int expected_impl_line = __LINE__ - 1;
    2616                 :             : 
    2617                 :         112 :         ASSERT_DUMPED_TEXT_EQ (tmp, "42");
    2618                 :         112 :         if (with_optinfo)
    2619                 :             :           {
    2620                 :          56 :             optinfo *info = tmp.get_pending_optinfo ();
    2621                 :          56 :             ASSERT_TRUE (info != NULL);
    2622                 :          56 :             ASSERT_EQ (info->num_items (), 1);
    2623                 :          56 :             ASSERT_IS_TEXT (info->get_item (0), "42");
    2624                 :          56 :             ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2625                 :             :                                      "dumpfile.cc", expected_impl_line,
    2626                 :             :                                      "test_capture_of_dump_calls");
    2627                 :             :           }
    2628                 :         112 :       }
    2629                 :             : 
    2630                 :             :       /* Scopes.  Test with all 4 combinations of
    2631                 :             :          filtering by MSG_PRIORITY_USER_FACING
    2632                 :             :          and/or filtering by MSG_PRIORITY_INTERNALS.  */
    2633                 :         448 :       for (int j = 0; j < 3; j++)
    2634                 :             :         {
    2635                 :         336 :           dump_flags_t dump_filter = MSG_ALL_KINDS;
    2636                 :         336 :           if (j % 2)
    2637                 :         112 :             dump_filter |= MSG_PRIORITY_USER_FACING;
    2638                 :         336 :           if (j / 2)
    2639                 :         112 :             dump_filter |= MSG_PRIORITY_INTERNALS;
    2640                 :             : 
    2641                 :         336 :           temp_dump_context tmp (with_optinfo, true, dump_filter);
    2642                 :             :           /* Emit various messages, mostly with implicit priority.  */
    2643                 :         336 :           dump_printf_loc (MSG_NOTE, stmt, "msg 1\n");
    2644                 :         336 :           dump_printf_loc (MSG_NOTE | MSG_PRIORITY_INTERNALS, stmt,
    2645                 :             :                            "explicitly internal msg\n");
    2646                 :         336 :           {
    2647                 :         336 :             AUTO_DUMP_SCOPE ("outer scope", stmt);
    2648                 :         336 :             dump_printf_loc (MSG_NOTE, stmt, "msg 2\n");
    2649                 :         336 :             {
    2650                 :         336 :               AUTO_DUMP_SCOPE ("middle scope", stmt);
    2651                 :         336 :               dump_printf_loc (MSG_NOTE, stmt, "msg 3\n");
    2652                 :         336 :               {
    2653                 :         336 :                 AUTO_DUMP_SCOPE ("inner scope", stmt);
    2654                 :         336 :                 dump_printf_loc (MSG_NOTE, stmt, "msg 4\n");
    2655                 :         336 :                 dump_printf_loc (MSG_NOTE | MSG_PRIORITY_USER_FACING, stmt,
    2656                 :             :                                  "explicitly user-facing msg\n");
    2657                 :             :               }
    2658                 :         336 :               dump_printf_loc (MSG_NOTE, stmt, "msg 5\n");
    2659                 :             :             }
    2660                 :         336 :             dump_printf_loc (MSG_NOTE, stmt, "msg 6\n");
    2661                 :             :           }
    2662                 :         336 :           dump_printf_loc (MSG_NOTE, stmt, "msg 7\n");
    2663                 :         336 :           const int expected_impl_line = __LINE__ - 1;
    2664                 :             : 
    2665                 :         336 :           switch (dump_filter & MSG_ALL_PRIORITIES)
    2666                 :             :             {
    2667                 :           0 :             default:
    2668                 :           0 :               gcc_unreachable ();
    2669                 :         112 :             case 0:
    2670                 :         112 :               ASSERT_DUMPED_TEXT_EQ (tmp, "");
    2671                 :         112 :               break;
    2672                 :         112 :             case MSG_PRIORITY_USER_FACING:
    2673                 :         112 :               ASSERT_DUMPED_TEXT_EQ
    2674                 :             :                 (tmp,
    2675                 :             :                  "test.txt:5:10: note: msg 1\n"
    2676                 :             :                  "test.txt:5:10: note:    explicitly user-facing msg\n"
    2677                 :             :                  "test.txt:5:10: note: msg 7\n");
    2678                 :         112 :               break;
    2679                 :         112 :             case MSG_PRIORITY_INTERNALS:
    2680                 :         112 :               ASSERT_DUMPED_TEXT_EQ
    2681                 :             :                 (tmp,
    2682                 :             :                  "test.txt:5:10: note: explicitly internal msg\n"
    2683                 :             :                  "test.txt:5:10: note:  === outer scope ===\n"
    2684                 :             :                  "test.txt:5:10: note:  msg 2\n"
    2685                 :             :                  "test.txt:5:10: note:   === middle scope ===\n"
    2686                 :             :                  "test.txt:5:10: note:   msg 3\n"
    2687                 :             :                  "test.txt:5:10: note:    === inner scope ===\n"
    2688                 :             :                  "test.txt:5:10: note:    msg 4\n"
    2689                 :             :                  "test.txt:5:10: note:   msg 5\n"
    2690                 :             :                  "test.txt:5:10: note:  msg 6\n");
    2691                 :         112 :               break;
    2692                 :             :             case MSG_ALL_PRIORITIES:
    2693                 :             :               ASSERT_DUMPED_TEXT_EQ
    2694                 :             :                 (tmp,
    2695                 :             :                  "test.txt:5:10: note: msg 1\n"
    2696                 :             :                  "test.txt:5:10: note: explicitly internal msg\n"
    2697                 :             :                  "test.txt:5:10: note: === outer scope ===\n"
    2698                 :             :                  "test.txt:5:10: note:  msg 2\n"
    2699                 :             :                  "test.txt:5:10: note:  === middle scope ===\n"
    2700                 :             :                  "test.txt:5:10: note:   msg 3\n"
    2701                 :             :                  "test.txt:5:10: note:   === inner scope ===\n"
    2702                 :             :                  "test.txt:5:10: note:    msg 4\n"
    2703                 :             :                  "test.txt:5:10: note:    explicitly user-facing msg\n"
    2704                 :             :                  "test.txt:5:10: note:   msg 5\n"
    2705                 :             :                  "test.txt:5:10: note:  msg 6\n"
    2706                 :             :                  "test.txt:5:10: note: msg 7\n");
    2707                 :             :               break;
    2708                 :             :             }
    2709                 :         336 :           if (with_optinfo)
    2710                 :             :             {
    2711                 :         168 :               optinfo *info = tmp.get_pending_optinfo ();
    2712                 :         168 :               ASSERT_TRUE (info != NULL);
    2713                 :         168 :               ASSERT_EQ (info->num_items (), 1);
    2714                 :         168 :               ASSERT_IS_TEXT (info->get_item (0), "msg 7\n");
    2715                 :         168 :               ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
    2716                 :             :                                        "dumpfile.cc", expected_impl_line,
    2717                 :             :                                        "test_capture_of_dump_calls");
    2718                 :             :             }
    2719                 :         336 :         }
    2720                 :             :     }
    2721                 :             : 
    2722                 :             :   /* Verify that MSG_* affects optinfo->get_kind (); we tested MSG_NOTE
    2723                 :             :      above.  */
    2724                 :          56 :   {
    2725                 :             :     /* MSG_OPTIMIZED_LOCATIONS.  */
    2726                 :          56 :     {
    2727                 :          56 :       temp_dump_context tmp (true, true, MSG_ALL_KINDS);
    2728                 :          56 :       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, "test");
    2729                 :          56 :       ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
    2730                 :             :                  OPTINFO_KIND_SUCCESS);
    2731                 :          56 :     }
    2732                 :             : 
    2733                 :             :     /* MSG_MISSED_OPTIMIZATION.  */
    2734                 :          56 :     {
    2735                 :          56 :       temp_dump_context tmp (true, true, MSG_ALL_KINDS);
    2736                 :          56 :       dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, "test");
    2737                 :          56 :       ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
    2738                 :             :                  OPTINFO_KIND_FAILURE);
    2739                 :          56 :     }
    2740                 :             :   }
    2741                 :             : 
    2742                 :             :   /* Verify that MSG_* affect AUTO_DUMP_SCOPE and the dump calls.  */
    2743                 :          56 :   {
    2744                 :          56 :     temp_dump_context tmp (false, true,
    2745                 :          56 :                            MSG_OPTIMIZED_LOCATIONS | MSG_ALL_PRIORITIES);
    2746                 :          56 :     dump_printf_loc (MSG_NOTE, stmt, "msg 1\n");
    2747                 :          56 :     {
    2748                 :          56 :       AUTO_DUMP_SCOPE ("outer scope", stmt);
    2749                 :          56 :       dump_printf_loc (MSG_NOTE, stmt, "msg 2\n");
    2750                 :          56 :       {
    2751                 :          56 :         AUTO_DUMP_SCOPE ("middle scope", stmt);
    2752                 :          56 :         dump_printf_loc (MSG_NOTE, stmt, "msg 3\n");
    2753                 :          56 :         {
    2754                 :          56 :           AUTO_DUMP_SCOPE ("inner scope", stmt);
    2755                 :          56 :           dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt, "msg 4\n");
    2756                 :             :         }
    2757                 :          56 :         dump_printf_loc (MSG_NOTE, stmt, "msg 5\n");
    2758                 :             :       }
    2759                 :          56 :       dump_printf_loc (MSG_NOTE, stmt, "msg 6\n");
    2760                 :             :     }
    2761                 :          56 :     dump_printf_loc (MSG_NOTE, stmt, "msg 7\n");
    2762                 :             : 
    2763                 :          56 :     ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: optimized:    msg 4\n");
    2764                 :          56 :   }
    2765                 :          96 : }
    2766                 :             : 
    2767                 :             : static void
    2768                 :           4 : test_pr87025 ()
    2769                 :             : {
    2770                 :           4 :   dump_user_location_t loc
    2771                 :           4 :     = dump_user_location_t::from_location_t (UNKNOWN_LOCATION);
    2772                 :             : 
    2773                 :           4 :   temp_dump_context tmp (true, true,
    2774                 :           4 :                          MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
    2775                 :           4 :   {
    2776                 :           4 :     AUTO_DUMP_SCOPE ("outer scope", loc);
    2777                 :           4 :     dump_printf (MSG_NOTE, "msg1\n");
    2778                 :             :   }
    2779                 :           4 : }
    2780                 :             : 
    2781                 :             : /* Run all of the selftests within this file.  */
    2782                 :             : 
    2783                 :             : void
    2784                 :           4 : dumpfile_cc_tests ()
    2785                 :             : {
    2786                 :           4 :   test_impl_location ();
    2787                 :           4 :   for_each_line_table_case (test_capture_of_dump_calls);
    2788                 :           4 :   test_pr87025 ();
    2789                 :           4 : }
    2790                 :             : 
    2791                 :             : } // namespace selftest
    2792                 :             : 
    2793                 :             : #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.