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

Generated by: LCOV version 1.0

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