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

Generated by: LCOV version 2.1-beta

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