* tree-ssa-dse.c (compute_trims): Avoid folding away undefined
[official-gcc.git] / gcc / dumpfile.c
bloba81ab3ed3c6da46dcb1ecd289414d73d99e61a0f
1 /* Dump infrastructure for optimizations and intermediate representation.
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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. */
43 /* If non-NULL, return one past-the-end of the matching SUBPART of
44 the WHOLE string. */
45 #define skip_leading_substring(whole, part) \
46 (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
48 static dump_flags_t pflags; /* current dump_flags */
50 static void dump_loc (dump_flags_t, FILE *, source_location);
52 /* Current -fopt-info output stream, if any, and flags. */
53 static FILE *alt_dump_file = NULL;
54 static dump_flags_t alt_flags;
56 static FILE *dump_open_alternate_stream (struct dump_file_info *);
58 /* These are currently used for communicating between passes.
59 However, instead of accessing them directly, the passes can use
60 dump_printf () for dumps. */
61 FILE *dump_file = NULL;
62 const char *dump_file_name;
63 dump_flags_t dump_flags;
64 bool dumps_are_enabled = false;
67 /* Set global "dump_file" to NEW_DUMP_FILE, refreshing the "dumps_are_enabled"
68 global. */
70 void
71 set_dump_file (FILE *new_dump_file)
73 dumpfile_ensure_any_optinfo_are_flushed ();
74 dump_file = new_dump_file;
75 dump_context::get ().refresh_dumps_are_enabled ();
78 /* Set "alt_dump_file" to NEW_ALT_DUMP_FILE, refreshing the "dumps_are_enabled"
79 global. */
81 static void
82 set_alt_dump_file (FILE *new_alt_dump_file)
84 dumpfile_ensure_any_optinfo_are_flushed ();
85 alt_dump_file = new_alt_dump_file;
86 dump_context::get ().refresh_dumps_are_enabled ();
89 #define DUMP_FILE_INFO(suffix, swtch, dkind, num) \
90 {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, TDF_NONE, TDF_NONE, \
91 OPTGROUP_NONE, 0, 0, num, false, false}
93 /* Table of tree dump switches. This must be consistent with the
94 TREE_DUMP_INDEX enumeration in dumpfile.h. */
95 static struct dump_file_info dump_files[TDI_end] =
97 DUMP_FILE_INFO (NULL, NULL, DK_none, 0),
98 DUMP_FILE_INFO (".cgraph", "ipa-cgraph", DK_ipa, 0),
99 DUMP_FILE_INFO (".type-inheritance", "ipa-type-inheritance", DK_ipa, 0),
100 DUMP_FILE_INFO (".ipa-clones", "ipa-clones", DK_ipa, 0),
101 DUMP_FILE_INFO (".original", "tree-original", DK_tree, 0),
102 DUMP_FILE_INFO (".gimple", "tree-gimple", DK_tree, 0),
103 DUMP_FILE_INFO (".nested", "tree-nested", DK_tree, 0),
104 DUMP_FILE_INFO (".lto-stream-out", "ipa-lto-stream-out", DK_ipa, 0),
105 #define FIRST_AUTO_NUMBERED_DUMP 1
106 #define FIRST_ME_AUTO_NUMBERED_DUMP 4
108 DUMP_FILE_INFO (NULL, "lang-all", DK_lang, 0),
109 DUMP_FILE_INFO (NULL, "tree-all", DK_tree, 0),
110 DUMP_FILE_INFO (NULL, "rtl-all", DK_rtl, 0),
111 DUMP_FILE_INFO (NULL, "ipa-all", DK_ipa, 0),
114 /* Table of dump options. This must be consistent with the TDF_* flags
115 in dumpfile.h and opt_info_options below. */
116 static const kv_pair<dump_flags_t> dump_options[] =
118 {"address", TDF_ADDRESS},
119 {"asmname", TDF_ASMNAME},
120 {"slim", TDF_SLIM},
121 {"raw", TDF_RAW},
122 {"graph", TDF_GRAPH},
123 {"details", (TDF_DETAILS | MSG_OPTIMIZED_LOCATIONS
124 | MSG_MISSED_OPTIMIZATION
125 | MSG_NOTE)},
126 {"cselib", TDF_CSELIB},
127 {"stats", TDF_STATS},
128 {"blocks", TDF_BLOCKS},
129 {"vops", TDF_VOPS},
130 {"lineno", TDF_LINENO},
131 {"uid", TDF_UID},
132 {"stmtaddr", TDF_STMTADDR},
133 {"memsyms", TDF_MEMSYMS},
134 {"eh", TDF_EH},
135 {"alias", TDF_ALIAS},
136 {"nouid", TDF_NOUID},
137 {"enumerate_locals", TDF_ENUMERATE_LOCALS},
138 {"scev", TDF_SCEV},
139 {"gimple", TDF_GIMPLE},
140 {"folding", TDF_FOLDING},
141 {"optimized", MSG_OPTIMIZED_LOCATIONS},
142 {"missed", MSG_MISSED_OPTIMIZATION},
143 {"note", MSG_NOTE},
144 {"optall", MSG_ALL},
145 {"all", dump_flags_t (TDF_ALL_VALUES
146 & ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_GRAPH
147 | TDF_STMTADDR | TDF_RHS_ONLY | TDF_NOUID
148 | TDF_ENUMERATE_LOCALS | TDF_SCEV | TDF_GIMPLE))},
149 {NULL, TDF_NONE}
152 /* A subset of the dump_options table which is used for -fopt-info
153 types. This must be consistent with the MSG_* flags in dumpfile.h.
155 static const kv_pair<dump_flags_t> optinfo_verbosity_options[] =
157 {"optimized", MSG_OPTIMIZED_LOCATIONS},
158 {"missed", MSG_MISSED_OPTIMIZATION},
159 {"note", MSG_NOTE},
160 {"all", MSG_ALL},
161 {NULL, TDF_NONE}
164 /* Flags used for -fopt-info groups. */
165 const kv_pair<optgroup_flags_t> optgroup_options[] =
167 {"ipa", OPTGROUP_IPA},
168 {"loop", OPTGROUP_LOOP},
169 {"inline", OPTGROUP_INLINE},
170 {"omp", OPTGROUP_OMP},
171 {"vec", OPTGROUP_VEC},
172 {"optall", OPTGROUP_ALL},
173 {NULL, OPTGROUP_NONE}
176 gcc::dump_manager::dump_manager ():
177 m_next_dump (FIRST_AUTO_NUMBERED_DUMP),
178 m_extra_dump_files (NULL),
179 m_extra_dump_files_in_use (0),
180 m_extra_dump_files_alloced (0)
184 gcc::dump_manager::~dump_manager ()
186 for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
188 dump_file_info *dfi = &m_extra_dump_files[i];
189 /* suffix, swtch, glob are statically allocated for the entries
190 in dump_files, and for statistics, but are dynamically allocated
191 for those for passes. */
192 if (dfi->owns_strings)
194 XDELETEVEC (const_cast <char *> (dfi->suffix));
195 XDELETEVEC (const_cast <char *> (dfi->swtch));
196 XDELETEVEC (const_cast <char *> (dfi->glob));
198 /* These, if non-NULL, are always dynamically allocated. */
199 XDELETEVEC (const_cast <char *> (dfi->pfilename));
200 XDELETEVEC (const_cast <char *> (dfi->alt_filename));
202 XDELETEVEC (m_extra_dump_files);
205 unsigned int
206 gcc::dump_manager::
207 dump_register (const char *suffix, const char *swtch, const char *glob,
208 dump_kind dkind, optgroup_flags_t optgroup_flags,
209 bool take_ownership)
211 int num = m_next_dump++;
213 size_t count = m_extra_dump_files_in_use++;
215 if (count >= m_extra_dump_files_alloced)
217 if (m_extra_dump_files_alloced == 0)
218 m_extra_dump_files_alloced = 512;
219 else
220 m_extra_dump_files_alloced *= 2;
221 m_extra_dump_files = XRESIZEVEC (struct dump_file_info,
222 m_extra_dump_files,
223 m_extra_dump_files_alloced);
225 /* Construct a new object in the space allocated above. */
226 new (m_extra_dump_files + count) dump_file_info ();
228 else
230 /* Zero out the already constructed object. */
231 m_extra_dump_files[count] = dump_file_info ();
234 m_extra_dump_files[count].suffix = suffix;
235 m_extra_dump_files[count].swtch = swtch;
236 m_extra_dump_files[count].glob = glob;
237 m_extra_dump_files[count].dkind = dkind;
238 m_extra_dump_files[count].optgroup_flags = optgroup_flags;
239 m_extra_dump_files[count].num = num;
240 m_extra_dump_files[count].owns_strings = take_ownership;
242 return count + TDI_end;
246 /* Allow languages and middle-end to register their dumps before the
247 optimization passes. */
249 void
250 gcc::dump_manager::
251 register_dumps ()
253 lang_hooks.register_dumps (this);
254 /* If this assert fails, some FE registered more than
255 FIRST_ME_AUTO_NUMBERED_DUMP - FIRST_AUTO_NUMBERED_DUMP
256 dump files. Bump FIRST_ME_AUTO_NUMBERED_DUMP accordingly. */
257 gcc_assert (m_next_dump <= FIRST_ME_AUTO_NUMBERED_DUMP);
258 m_next_dump = FIRST_ME_AUTO_NUMBERED_DUMP;
259 dump_files[TDI_original].num = m_next_dump++;
260 dump_files[TDI_gimple].num = m_next_dump++;
261 dump_files[TDI_nested].num = m_next_dump++;
265 /* Return the dump_file_info for the given phase. */
267 struct dump_file_info *
268 gcc::dump_manager::
269 get_dump_file_info (int phase) const
271 if (phase < TDI_end)
272 return &dump_files[phase];
273 else if ((size_t) (phase - TDI_end) >= m_extra_dump_files_in_use)
274 return NULL;
275 else
276 return m_extra_dump_files + (phase - TDI_end);
279 /* Locate the dump_file_info with swtch equal to SWTCH,
280 or return NULL if no such dump_file_info exists. */
282 struct dump_file_info *
283 gcc::dump_manager::
284 get_dump_file_info_by_switch (const char *swtch) const
286 for (unsigned i = 0; i < m_extra_dump_files_in_use; i++)
287 if (strcmp (m_extra_dump_files[i].swtch, swtch) == 0)
288 return &m_extra_dump_files[i];
290 /* Not found. */
291 return NULL;
295 /* Return the name of the dump file for the given phase.
296 The caller is responsible for calling free on the returned
297 buffer.
298 If the dump is not enabled, returns NULL. */
300 char *
301 gcc::dump_manager::
302 get_dump_file_name (int phase, int part) const
304 struct dump_file_info *dfi;
306 if (phase == TDI_none)
307 return NULL;
309 dfi = get_dump_file_info (phase);
311 return get_dump_file_name (dfi, part);
314 /* Return the name of the dump file for the given dump_file_info.
315 The caller is responsible for calling free on the returned
316 buffer.
317 If the dump is not enabled, returns NULL. */
319 char *
320 gcc::dump_manager::
321 get_dump_file_name (struct dump_file_info *dfi, int part) const
323 char dump_id[10];
325 gcc_assert (dfi);
327 if (dfi->pstate == 0)
328 return NULL;
330 /* If available, use the command line dump filename. */
331 if (dfi->pfilename)
332 return xstrdup (dfi->pfilename);
334 if (dfi->num < 0)
335 dump_id[0] = '\0';
336 else
338 /* (null), LANG, TREE, RTL, IPA. */
339 char suffix = " ltri"[dfi->dkind];
341 if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
342 dump_id[0] = '\0';
345 if (part != -1)
347 char part_id[8];
348 snprintf (part_id, sizeof (part_id), ".%i", part);
349 return concat (dump_base_name, dump_id, part_id, dfi->suffix, NULL);
351 else
352 return concat (dump_base_name, dump_id, dfi->suffix, NULL);
355 /* Open a dump file called FILENAME. Some filenames are special and
356 refer to the standard streams. TRUNC indicates whether this is the
357 first open (so the file should be truncated, rather than appended).
358 An error message is emitted in the event of failure. */
360 static FILE *
361 dump_open (const char *filename, bool trunc)
363 if (strcmp ("stderr", filename) == 0)
364 return stderr;
366 if (strcmp ("stdout", filename) == 0
367 || strcmp ("-", filename) == 0)
368 return stdout;
370 FILE *stream = fopen (filename, trunc ? "w" : "a");
372 if (!stream)
373 error ("could not open dump file %qs: %m", filename);
374 return stream;
377 /* For a given DFI, open an alternate dump filename (which could also
378 be a standard stream such as stdout/stderr). If the alternate dump
379 file cannot be opened, return NULL. */
381 static FILE *
382 dump_open_alternate_stream (struct dump_file_info *dfi)
384 if (!dfi->alt_filename)
385 return NULL;
387 if (dfi->alt_stream)
388 return dfi->alt_stream;
390 FILE *stream = dump_open (dfi->alt_filename, dfi->alt_state < 0);
392 if (stream)
393 dfi->alt_state = 1;
395 return stream;
398 /* Construct a dump_user_location_t from STMT (using its location and
399 hotness). */
401 dump_user_location_t::dump_user_location_t (const gimple *stmt)
402 : m_count (), m_loc (UNKNOWN_LOCATION)
404 if (stmt)
406 if (stmt->bb)
407 m_count = stmt->bb->count;
408 m_loc = gimple_location (stmt);
412 /* Construct a dump_user_location_t from an RTL instruction (using its
413 location and hotness). */
415 dump_user_location_t::dump_user_location_t (const rtx_insn *insn)
416 : m_count (), m_loc (UNKNOWN_LOCATION)
418 if (insn)
420 basic_block bb = BLOCK_FOR_INSN (insn);
421 if (bb)
422 m_count = bb->count;
423 m_loc = INSN_LOCATION (insn);
427 /* Construct from a function declaration. This one requires spelling out
428 to avoid accidentally constructing from other kinds of tree. */
430 dump_user_location_t
431 dump_user_location_t::from_function_decl (tree fndecl)
433 gcc_assert (fndecl);
435 // FIXME: profile count for function?
436 return dump_user_location_t (profile_count (),
437 DECL_SOURCE_LOCATION (fndecl));
440 /* Print source location on DFILE if enabled. */
442 static void
443 dump_loc (dump_flags_t dump_kind, FILE *dfile, source_location loc)
445 if (dump_kind)
447 if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
448 fprintf (dfile, "%s:%d:%d: note: ", LOCATION_FILE (loc),
449 LOCATION_LINE (loc), LOCATION_COLUMN (loc));
450 else if (current_function_decl)
451 fprintf (dfile, "%s:%d:%d: note: ",
452 DECL_SOURCE_FILE (current_function_decl),
453 DECL_SOURCE_LINE (current_function_decl),
454 DECL_SOURCE_COLUMN (current_function_decl));
455 /* Indentation based on scope depth. */
456 fprintf (dfile, "%*s", get_dump_scope_depth (), "");
460 /* Print source location to PP if enabled. */
462 static void
463 dump_loc (dump_flags_t dump_kind, pretty_printer *pp, source_location loc)
465 if (dump_kind)
467 if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
468 pp_printf (pp, "%s:%d:%d: note: ", LOCATION_FILE (loc),
469 LOCATION_LINE (loc), LOCATION_COLUMN (loc));
470 else if (current_function_decl)
471 pp_printf (pp, "%s:%d:%d: note: ",
472 DECL_SOURCE_FILE (current_function_decl),
473 DECL_SOURCE_LINE (current_function_decl),
474 DECL_SOURCE_COLUMN (current_function_decl));
475 /* Indentation based on scope depth. */
476 for (unsigned i = 0; i < get_dump_scope_depth (); i++)
477 pp_character (pp, ' ');
481 /* Implementation of dump_context member functions. */
483 /* dump_context's dtor. */
485 dump_context::~dump_context ()
487 delete m_pending;
490 /* Update the "dumps_are_enabled" global; to be called whenever dump_file
491 or alt_dump_file change, or when changing dump_context in selftests. */
493 void
494 dump_context::refresh_dumps_are_enabled ()
496 dumps_are_enabled = (dump_file || alt_dump_file || optinfo_enabled_p ()
497 || m_test_pp);
500 /* Print LOC to the appropriate dump destinations, given DUMP_KIND.
501 If optinfos are enabled, begin a new optinfo. */
503 void
504 dump_context::dump_loc (dump_flags_t dump_kind, const dump_location_t &loc)
506 end_any_optinfo ();
508 location_t srcloc = loc.get_location_t ();
510 if (dump_file && (dump_kind & pflags))
511 ::dump_loc (dump_kind, dump_file, srcloc);
513 if (alt_dump_file && (dump_kind & alt_flags))
514 ::dump_loc (dump_kind, alt_dump_file, srcloc);
516 /* Support for temp_dump_context in selftests. */
517 if (m_test_pp && (dump_kind & m_test_pp_flags))
518 ::dump_loc (dump_kind, m_test_pp, srcloc);
520 if (optinfo_enabled_p ())
522 optinfo &info = begin_next_optinfo (loc);
523 info.handle_dump_file_kind (dump_kind);
527 /* Make an item for the given dump call, equivalent to print_gimple_stmt. */
529 static optinfo_item *
530 make_item_for_dump_gimple_stmt (gimple *stmt, int spc, dump_flags_t dump_flags)
532 pretty_printer pp;
533 pp_needs_newline (&pp) = true;
534 pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);
535 pp_newline (&pp);
537 optinfo_item *item
538 = new optinfo_item (OPTINFO_ITEM_KIND_GIMPLE, gimple_location (stmt),
539 xstrdup (pp_formatted_text (&pp)));
540 return item;
543 /* Dump gimple statement GS with SPC indentation spaces and
544 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
546 void
547 dump_context::dump_gimple_stmt (dump_flags_t dump_kind,
548 dump_flags_t extra_dump_flags,
549 gimple *gs, int spc)
551 optinfo_item *item
552 = make_item_for_dump_gimple_stmt (gs, spc, dump_flags | extra_dump_flags);
553 emit_item (item, dump_kind);
555 if (optinfo_enabled_p ())
557 optinfo &info = ensure_pending_optinfo ();
558 info.handle_dump_file_kind (dump_kind);
559 info.add_item (item);
561 else
562 delete item;
565 /* Similar to dump_gimple_stmt, except additionally print source location. */
567 void
568 dump_context::dump_gimple_stmt_loc (dump_flags_t dump_kind,
569 const dump_location_t &loc,
570 dump_flags_t extra_dump_flags,
571 gimple *gs, int spc)
573 dump_loc (dump_kind, loc);
574 dump_gimple_stmt (dump_kind, extra_dump_flags, gs, spc);
577 /* Make an item for the given dump call, equivalent to print_gimple_expr. */
579 static optinfo_item *
580 make_item_for_dump_gimple_expr (gimple *stmt, int spc, dump_flags_t dump_flags)
582 dump_flags |= TDF_RHS_ONLY;
583 pretty_printer pp;
584 pp_needs_newline (&pp) = true;
585 pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);
587 optinfo_item *item
588 = new optinfo_item (OPTINFO_ITEM_KIND_GIMPLE, gimple_location (stmt),
589 xstrdup (pp_formatted_text (&pp)));
590 return item;
593 /* Dump gimple statement GS with SPC indentation spaces and
594 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.
595 Do not terminate with a newline or semicolon. */
597 void
598 dump_context::dump_gimple_expr (dump_flags_t dump_kind,
599 dump_flags_t extra_dump_flags,
600 gimple *gs, int spc)
602 optinfo_item *item
603 = make_item_for_dump_gimple_expr (gs, spc, dump_flags | extra_dump_flags);
604 emit_item (item, dump_kind);
606 if (optinfo_enabled_p ())
608 optinfo &info = ensure_pending_optinfo ();
609 info.handle_dump_file_kind (dump_kind);
610 info.add_item (item);
612 else
613 delete item;
616 /* Similar to dump_gimple_expr, except additionally print source location. */
618 void
619 dump_context::dump_gimple_expr_loc (dump_flags_t dump_kind,
620 const dump_location_t &loc,
621 dump_flags_t extra_dump_flags,
622 gimple *gs,
623 int spc)
625 dump_loc (dump_kind, loc);
626 dump_gimple_expr (dump_kind, extra_dump_flags, gs, spc);
629 /* Make an item for the given dump call, equivalent to print_generic_expr. */
631 static optinfo_item *
632 make_item_for_dump_generic_expr (tree node, dump_flags_t dump_flags)
634 pretty_printer pp;
635 pp_needs_newline (&pp) = true;
636 pp_translate_identifiers (&pp) = false;
637 dump_generic_node (&pp, node, 0, dump_flags, false);
639 location_t loc = UNKNOWN_LOCATION;
640 if (EXPR_HAS_LOCATION (node))
641 loc = EXPR_LOCATION (node);
643 optinfo_item *item
644 = new optinfo_item (OPTINFO_ITEM_KIND_TREE, loc,
645 xstrdup (pp_formatted_text (&pp)));
646 return item;
649 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
650 DUMP_KIND is enabled. */
652 void
653 dump_context::dump_generic_expr (dump_flags_t dump_kind,
654 dump_flags_t extra_dump_flags,
655 tree t)
657 optinfo_item *item
658 = make_item_for_dump_generic_expr (t, dump_flags | extra_dump_flags);
659 emit_item (item, dump_kind);
661 if (optinfo_enabled_p ())
663 optinfo &info = ensure_pending_optinfo ();
664 info.handle_dump_file_kind (dump_kind);
665 info.add_item (item);
667 else
668 delete item;
672 /* Similar to dump_generic_expr, except additionally print the source
673 location. */
675 void
676 dump_context::dump_generic_expr_loc (dump_flags_t dump_kind,
677 const dump_location_t &loc,
678 dump_flags_t extra_dump_flags,
679 tree t)
681 dump_loc (dump_kind, loc);
682 dump_generic_expr (dump_kind, extra_dump_flags, t);
685 /* A subclass of pretty_printer for implementing dump_context::dump_printf_va.
686 In particular, the formatted chunks are captured as optinfo_item instances,
687 thus retaining metadata about the entities being dumped (e.g. source
688 locations), rather than just as plain text. */
690 class dump_pretty_printer : public pretty_printer
692 public:
693 dump_pretty_printer (dump_context *context, dump_flags_t dump_kind);
695 void emit_items (optinfo *dest);
697 private:
698 /* Information on an optinfo_item that was generated during phase 2 of
699 formatting. */
700 struct stashed_item
702 stashed_item (const char **buffer_ptr_, optinfo_item *item_)
703 : buffer_ptr (buffer_ptr_), item (item_) {}
704 const char **buffer_ptr;
705 optinfo_item *item;
708 static bool format_decoder_cb (pretty_printer *pp, text_info *text,
709 const char *spec, int /*precision*/,
710 bool /*wide*/, bool /*set_locus*/,
711 bool /*verbose*/, bool */*quoted*/,
712 const char **buffer_ptr);
714 bool decode_format (text_info *text, const char *spec,
715 const char **buffer_ptr);
717 void stash_item (const char **buffer_ptr, optinfo_item *item);
719 void emit_any_pending_textual_chunks (optinfo *dest);
721 void emit_item (optinfo_item *item, optinfo *dest);
723 dump_context *m_context;
724 dump_flags_t m_dump_kind;
725 auto_vec<stashed_item> m_stashed_items;
728 /* dump_pretty_printer's ctor. */
730 dump_pretty_printer::dump_pretty_printer (dump_context *context,
731 dump_flags_t dump_kind)
732 : pretty_printer (), m_context (context), m_dump_kind (dump_kind),
733 m_stashed_items ()
735 pp_format_decoder (this) = format_decoder_cb;
738 /* Phase 3 of formatting; compare with pp_output_formatted_text.
740 Emit optinfo_item instances for the various formatted chunks from phases
741 1 and 2 (i.e. pp_format).
743 Some chunks may already have had their items built (during decode_format).
744 These chunks have been stashed into m_stashed_items; we emit them here.
746 For all other purely textual chunks, they are printed into
747 buffer->formatted_obstack, and then emitted as a textual optinfo_item.
748 This consolidates multiple adjacent text chunks into a single text
749 optinfo_item. */
751 void
752 dump_pretty_printer::emit_items (optinfo *dest)
754 output_buffer *buffer = pp_buffer (this);
755 struct chunk_info *chunk_array = buffer->cur_chunk_array;
756 const char **args = chunk_array->args;
758 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
759 gcc_assert (buffer->line_length == 0);
761 unsigned stashed_item_idx = 0;
762 for (unsigned chunk = 0; args[chunk]; chunk++)
764 if (stashed_item_idx < m_stashed_items.length ()
765 && args[chunk] == *m_stashed_items[stashed_item_idx].buffer_ptr)
767 emit_any_pending_textual_chunks (dest);
768 /* This chunk has a stashed item: use it. */
769 emit_item (m_stashed_items[stashed_item_idx++].item, dest);
771 else
772 /* This chunk is purely textual. Print it (to
773 buffer->formatted_obstack), so that we can consolidate adjacent
774 chunks into one textual optinfo_item. */
775 pp_string (this, args[chunk]);
778 emit_any_pending_textual_chunks (dest);
780 /* Ensure that we consumed all of stashed_items. */
781 gcc_assert (stashed_item_idx == m_stashed_items.length ());
783 /* Deallocate the chunk structure and everything after it (i.e. the
784 associated series of formatted strings). */
785 buffer->cur_chunk_array = chunk_array->prev;
786 obstack_free (&buffer->chunk_obstack, chunk_array);
789 /* Subroutine of dump_pretty_printer::emit_items
790 for consolidating multiple adjacent pure-text chunks into single
791 optinfo_items (in phase 3). */
793 void
794 dump_pretty_printer::emit_any_pending_textual_chunks (optinfo *dest)
796 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
798 /* Don't emit an item if the pending text is empty. */
799 if (output_buffer_last_position_in_text (buffer) == NULL)
800 return;
802 char *formatted_text = xstrdup (pp_formatted_text (this));
803 optinfo_item *item
804 = new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
805 formatted_text);
806 emit_item (item, dest);
808 /* Clear the pending text by unwinding formatted_text back to the start
809 of the buffer (without deallocating). */
810 obstack_free (&buffer->formatted_obstack,
811 buffer->formatted_obstack.object_base);
814 /* Emit ITEM and take ownership of it. If DEST is non-NULL, add ITEM
815 to DEST; otherwise delete ITEM. */
817 void
818 dump_pretty_printer::emit_item (optinfo_item *item, optinfo *dest)
820 m_context->emit_item (item, m_dump_kind);
821 if (dest)
822 dest->add_item (item);
823 else
824 delete item;
827 /* Record that ITEM (generated in phase 2 of formatting) is to be used for
828 the chunk at BUFFER_PTR in phase 3 (by emit_items). */
830 void
831 dump_pretty_printer::stash_item (const char **buffer_ptr, optinfo_item *item)
833 gcc_assert (buffer_ptr);
834 gcc_assert (item);
836 m_stashed_items.safe_push (stashed_item (buffer_ptr, item));
839 /* pp_format_decoder callback for dump_pretty_printer, and thus for
840 dump_printf and dump_printf_loc.
842 A wrapper around decode_format, for type-safety. */
844 bool
845 dump_pretty_printer::format_decoder_cb (pretty_printer *pp, text_info *text,
846 const char *spec, int /*precision*/,
847 bool /*wide*/, bool /*set_locus*/,
848 bool /*verbose*/, bool */*quoted*/,
849 const char **buffer_ptr)
851 dump_pretty_printer *opp = static_cast <dump_pretty_printer *> (pp);
852 return opp->decode_format (text, spec, buffer_ptr);
855 /* Format decoder for dump_pretty_printer, and thus for dump_printf and
856 dump_printf_loc.
858 Supported format codes (in addition to the standard pretty_printer ones)
859 are:
861 %E: gimple *:
862 Equivalent to: dump_gimple_expr (MSG_*, TDF_SLIM, stmt, 0)
863 %G: gimple *:
864 Equivalent to: dump_gimple_stmt (MSG_*, TDF_SLIM, stmt, 0)
865 %T: tree:
866 Equivalent to: dump_generic_expr (MSG_*, arg, TDF_SLIM).
868 FIXME: add symtab_node?
870 These format codes build optinfo_item instances, thus capturing metadata
871 about the arguments being dumped, as well as the textual output. */
873 bool
874 dump_pretty_printer::decode_format (text_info *text, const char *spec,
875 const char **buffer_ptr)
877 /* Various format codes that imply making an optinfo_item and stashed it
878 for later use (to capture metadata, rather than plain text). */
879 switch (*spec)
881 case 'E':
883 gimple *stmt = va_arg (*text->args_ptr, gimple *);
885 /* Make an item for the stmt, and stash it. */
886 optinfo_item *item = make_item_for_dump_gimple_expr (stmt, 0, TDF_SLIM);
887 stash_item (buffer_ptr, item);
888 return true;
891 case 'G':
893 gimple *stmt = va_arg (*text->args_ptr, gimple *);
895 /* Make an item for the stmt, and stash it. */
896 optinfo_item *item = make_item_for_dump_gimple_stmt (stmt, 0, TDF_SLIM);
897 stash_item (buffer_ptr, item);
898 return true;
901 case 'T':
903 tree t = va_arg (*text->args_ptr, tree);
905 /* Make an item for the tree, and stash it. */
906 optinfo_item *item = make_item_for_dump_generic_expr (t, TDF_SLIM);
907 stash_item (buffer_ptr, item);
908 return true;
911 default:
912 return false;
916 /* Output a formatted message using FORMAT on appropriate dump streams. */
918 void
919 dump_context::dump_printf_va (dump_flags_t dump_kind, const char *format,
920 va_list *ap)
922 dump_pretty_printer pp (this, dump_kind);
924 text_info text;
925 text.err_no = errno;
926 text.args_ptr = ap;
927 text.format_spec = format;
929 /* Phases 1 and 2, using pp_format. */
930 pp_format (&pp, &text);
932 /* Phase 3. */
933 if (optinfo_enabled_p ())
935 optinfo &info = ensure_pending_optinfo ();
936 info.handle_dump_file_kind (dump_kind);
937 pp.emit_items (&info);
939 else
940 pp.emit_items (NULL);
943 /* Similar to dump_printf, except source location is also printed, and
944 dump location captured. */
946 void
947 dump_context::dump_printf_loc_va (dump_flags_t dump_kind,
948 const dump_location_t &loc,
949 const char *format, va_list *ap)
951 dump_loc (dump_kind, loc);
952 dump_printf_va (dump_kind, format, ap);
955 /* Make an item for the given dump call, equivalent to print_dec. */
957 template<unsigned int N, typename C>
958 static optinfo_item *
959 make_item_for_dump_dec (const poly_int<N, C> &value)
961 STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
962 signop sgn = poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED;
964 pretty_printer pp;
966 if (value.is_constant ())
967 pp_wide_int (&pp, value.coeffs[0], sgn);
968 else
970 pp_character (&pp, '[');
971 for (unsigned int i = 0; i < N; ++i)
973 pp_wide_int (&pp, value.coeffs[i], sgn);
974 pp_character (&pp, i == N - 1 ? ']' : ',');
978 optinfo_item *item
979 = new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
980 xstrdup (pp_formatted_text (&pp)));
981 return item;
984 /* Output VALUE in decimal to appropriate dump streams. */
986 template<unsigned int N, typename C>
987 void
988 dump_context::dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value)
990 optinfo_item *item = make_item_for_dump_dec (value);
991 emit_item (item, dump_kind);
993 if (optinfo_enabled_p ())
995 optinfo &info = ensure_pending_optinfo ();
996 info.handle_dump_file_kind (dump_kind);
997 info.add_item (item);
999 else
1000 delete item;
1003 /* Make an item for the given dump call. */
1005 static optinfo_item *
1006 make_item_for_dump_symtab_node (symtab_node *node)
1008 location_t loc = DECL_SOURCE_LOCATION (node->decl);
1009 optinfo_item *item
1010 = new optinfo_item (OPTINFO_ITEM_KIND_SYMTAB_NODE, loc,
1011 xstrdup (node->dump_name ()));
1012 return item;
1015 /* Output the name of NODE on appropriate dump streams. */
1017 void
1018 dump_context::dump_symtab_node (dump_flags_t dump_kind, symtab_node *node)
1020 optinfo_item *item = make_item_for_dump_symtab_node (node);
1021 emit_item (item, dump_kind);
1023 if (optinfo_enabled_p ())
1025 optinfo &info = ensure_pending_optinfo ();
1026 info.handle_dump_file_kind (dump_kind);
1027 info.add_item (item);
1029 else
1030 delete item;
1033 /* Get the current dump scope-nesting depth.
1034 For use by -fopt-info (for showing nesting via indentation). */
1036 unsigned int
1037 dump_context::get_scope_depth () const
1039 return m_scope_depth;
1042 /* Push a nested dump scope.
1043 Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
1044 destination, if any.
1045 Emit a "scope" optinfo if optinfos are enabled.
1046 Increment the scope depth. */
1048 void
1049 dump_context::begin_scope (const char *name, const dump_location_t &loc)
1051 if (dump_file)
1052 ::dump_loc (MSG_NOTE, dump_file, loc.get_location_t ());
1054 if (alt_dump_file)
1055 ::dump_loc (MSG_NOTE, alt_dump_file, loc.get_location_t ());
1057 /* Support for temp_dump_context in selftests. */
1058 if (m_test_pp)
1059 ::dump_loc (MSG_NOTE, m_test_pp, loc.get_location_t ());
1061 pretty_printer pp;
1062 pp_printf (&pp, "=== %s ===\n", name);
1063 optinfo_item *item
1064 = new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
1065 xstrdup (pp_formatted_text (&pp)));
1066 emit_item (item, MSG_NOTE);
1068 if (optinfo_enabled_p ())
1070 optinfo &info = begin_next_optinfo (loc);
1071 info.m_kind = OPTINFO_KIND_SCOPE;
1072 info.add_item (item);
1074 else
1075 delete item;
1077 m_scope_depth++;
1080 /* Pop a nested dump scope. */
1082 void
1083 dump_context::end_scope ()
1085 end_any_optinfo ();
1086 m_scope_depth--;
1087 optimization_records_maybe_pop_dump_scope ();
1090 /* Return the optinfo currently being accumulated, creating one if
1091 necessary. */
1093 optinfo &
1094 dump_context::ensure_pending_optinfo ()
1096 if (!m_pending)
1097 return begin_next_optinfo (dump_location_t (dump_user_location_t ()));
1098 return *m_pending;
1101 /* Start a new optinfo and return it, ending any optinfo that was already
1102 accumulated. */
1104 optinfo &
1105 dump_context::begin_next_optinfo (const dump_location_t &loc)
1107 end_any_optinfo ();
1108 gcc_assert (m_pending == NULL);
1109 m_pending = new optinfo (loc, OPTINFO_KIND_NOTE, current_pass);
1110 return *m_pending;
1113 /* End any optinfo that has been accumulated within this context; emitting
1114 it to any destinations as appropriate, such as optimization records. */
1116 void
1117 dump_context::end_any_optinfo ()
1119 if (m_pending)
1120 m_pending->emit ();
1121 delete m_pending;
1122 m_pending = NULL;
1125 /* Emit ITEM to all item destinations (those that don't require
1126 consolidation into optinfo instances). */
1128 void
1129 dump_context::emit_item (optinfo_item *item, dump_flags_t dump_kind)
1131 if (dump_file && (dump_kind & pflags))
1132 fprintf (dump_file, "%s", item->get_text ());
1134 if (alt_dump_file && (dump_kind & alt_flags))
1135 fprintf (alt_dump_file, "%s", item->get_text ());
1137 /* Support for temp_dump_context in selftests. */
1138 if (m_test_pp && (dump_kind & m_test_pp_flags))
1139 pp_string (m_test_pp, item->get_text ());
1142 /* The current singleton dump_context, and its default. */
1144 dump_context *dump_context::s_current = &dump_context::s_default;
1145 dump_context dump_context::s_default;
1147 /* Implementation of dump_* API calls, calling into dump_context
1148 member functions. */
1150 /* Dump gimple statement GS with SPC indentation spaces and
1151 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
1153 void
1154 dump_gimple_stmt (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
1155 gimple *gs, int spc)
1157 dump_context::get ().dump_gimple_stmt (dump_kind, extra_dump_flags, gs, spc);
1160 /* Similar to dump_gimple_stmt, except additionally print source location. */
1162 void
1163 dump_gimple_stmt_loc (dump_flags_t dump_kind, const dump_location_t &loc,
1164 dump_flags_t extra_dump_flags, gimple *gs, int spc)
1166 dump_context::get ().dump_gimple_stmt_loc (dump_kind, loc, extra_dump_flags,
1167 gs, spc);
1170 /* Dump gimple statement GS with SPC indentation spaces and
1171 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.
1172 Do not terminate with a newline or semicolon. */
1174 void
1175 dump_gimple_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
1176 gimple *gs, int spc)
1178 dump_context::get ().dump_gimple_expr (dump_kind, extra_dump_flags, gs, spc);
1181 /* Similar to dump_gimple_expr, except additionally print source location. */
1183 void
1184 dump_gimple_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
1185 dump_flags_t extra_dump_flags, gimple *gs, int spc)
1187 dump_context::get ().dump_gimple_expr_loc (dump_kind, loc, extra_dump_flags,
1188 gs, spc);
1191 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
1192 DUMP_KIND is enabled. */
1194 void
1195 dump_generic_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
1196 tree t)
1198 dump_context::get ().dump_generic_expr (dump_kind, extra_dump_flags, t);
1201 /* Similar to dump_generic_expr, except additionally print the source
1202 location. */
1204 void
1205 dump_generic_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
1206 dump_flags_t extra_dump_flags, tree t)
1208 dump_context::get ().dump_generic_expr_loc (dump_kind, loc, extra_dump_flags,
1212 /* Output a formatted message using FORMAT on appropriate dump streams. */
1214 void
1215 dump_printf (dump_flags_t dump_kind, const char *format, ...)
1217 va_list ap;
1218 va_start (ap, format);
1219 dump_context::get ().dump_printf_va (dump_kind, format, &ap);
1220 va_end (ap);
1223 /* Similar to dump_printf, except source location is also printed, and
1224 dump location captured. */
1226 void
1227 dump_printf_loc (dump_flags_t dump_kind, const dump_location_t &loc,
1228 const char *format, ...)
1230 va_list ap;
1231 va_start (ap, format);
1232 dump_context::get ().dump_printf_loc_va (dump_kind, loc, format, &ap);
1233 va_end (ap);
1236 /* Output VALUE in decimal to appropriate dump streams. */
1238 template<unsigned int N, typename C>
1239 void
1240 dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value)
1242 dump_context::get ().dump_dec (dump_kind, value);
1245 template void dump_dec (dump_flags_t, const poly_uint16 &);
1246 template void dump_dec (dump_flags_t, const poly_int64 &);
1247 template void dump_dec (dump_flags_t, const poly_uint64 &);
1248 template void dump_dec (dump_flags_t, const poly_offset_int &);
1249 template void dump_dec (dump_flags_t, const poly_widest_int &);
1251 void
1252 dump_dec (dump_flags_t dump_kind, const poly_wide_int &value, signop sgn)
1254 if (dump_file && (dump_kind & pflags))
1255 print_dec (value, dump_file, sgn);
1257 if (alt_dump_file && (dump_kind & alt_flags))
1258 print_dec (value, alt_dump_file, sgn);
1261 /* Output VALUE in hexadecimal to appropriate dump streams. */
1263 void
1264 dump_hex (dump_flags_t dump_kind, const poly_wide_int &value)
1266 if (dump_file && (dump_kind & pflags))
1267 print_hex (value, dump_file);
1269 if (alt_dump_file && (dump_kind & alt_flags))
1270 print_hex (value, alt_dump_file);
1273 /* Emit and delete the currently pending optinfo, if there is one,
1274 without the caller needing to know about class dump_context. */
1276 void
1277 dumpfile_ensure_any_optinfo_are_flushed ()
1279 dump_context::get().end_any_optinfo ();
1282 /* Output the name of NODE on appropriate dump streams. */
1284 void
1285 dump_symtab_node (dump_flags_t dump_kind, symtab_node *node)
1287 dump_context::get ().dump_symtab_node (dump_kind, node);
1290 /* Get the current dump scope-nesting depth.
1291 For use by -fopt-info (for showing nesting via indentation). */
1293 unsigned int
1294 get_dump_scope_depth ()
1296 return dump_context::get ().get_scope_depth ();
1299 /* Push a nested dump scope.
1300 Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
1301 destination, if any.
1302 Emit a "scope" opinfo if optinfos are enabled.
1303 Increment the scope depth. */
1305 void
1306 dump_begin_scope (const char *name, const dump_location_t &loc)
1308 dump_context::get ().begin_scope (name, loc);
1311 /* Pop a nested dump scope. */
1313 void
1314 dump_end_scope ()
1316 dump_context::get ().end_scope ();
1319 /* Start a dump for PHASE. Store user-supplied dump flags in
1320 *FLAG_PTR. Return the number of streams opened. Set globals
1321 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
1322 set dump_flags appropriately for both pass dump stream and
1323 -fopt-info stream. */
1326 gcc::dump_manager::
1327 dump_start (int phase, dump_flags_t *flag_ptr)
1329 int count = 0;
1330 char *name;
1331 struct dump_file_info *dfi;
1332 FILE *stream;
1333 if (phase == TDI_none || !dump_phase_enabled_p (phase))
1334 return 0;
1336 dfi = get_dump_file_info (phase);
1337 name = get_dump_file_name (phase);
1338 if (name)
1340 stream = dump_open (name, dfi->pstate < 0);
1341 if (stream)
1343 dfi->pstate = 1;
1344 count++;
1346 free (name);
1347 dfi->pstream = stream;
1348 set_dump_file (dfi->pstream);
1349 /* Initialize current dump flags. */
1350 pflags = dfi->pflags;
1353 stream = dump_open_alternate_stream (dfi);
1354 if (stream)
1356 dfi->alt_stream = stream;
1357 count++;
1358 set_alt_dump_file (dfi->alt_stream);
1359 /* Initialize current -fopt-info flags. */
1360 alt_flags = dfi->alt_flags;
1363 if (flag_ptr)
1364 *flag_ptr = dfi->pflags;
1366 return count;
1369 /* Finish a tree dump for PHASE and close associated dump streams. Also
1370 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
1372 void
1373 gcc::dump_manager::
1374 dump_finish (int phase)
1376 struct dump_file_info *dfi;
1378 if (phase < 0)
1379 return;
1380 dfi = get_dump_file_info (phase);
1381 if (dfi->pstream && dfi->pstream != stdout && dfi->pstream != stderr)
1382 fclose (dfi->pstream);
1384 if (dfi->alt_stream && dfi->alt_stream != stdout && dfi->alt_stream != stderr)
1385 fclose (dfi->alt_stream);
1387 dfi->alt_stream = NULL;
1388 dfi->pstream = NULL;
1389 set_dump_file (NULL);
1390 set_alt_dump_file (NULL);
1391 dump_flags = TDF_NONE;
1392 alt_flags = TDF_NONE;
1393 pflags = TDF_NONE;
1396 /* Begin a tree dump for PHASE. Stores any user supplied flag in
1397 *FLAG_PTR and returns a stream to write to. If the dump is not
1398 enabled, returns NULL.
1399 PART can be used for dump files which should be split to multiple
1400 parts. PART == -1 indicates dump file with no parts.
1401 If PART is -1, multiple calls will reopen and append to the dump file. */
1403 FILE *
1404 dump_begin (int phase, dump_flags_t *flag_ptr, int part)
1406 return g->get_dumps ()->dump_begin (phase, flag_ptr, part);
1409 FILE *
1410 gcc::dump_manager::
1411 dump_begin (int phase, dump_flags_t *flag_ptr, int part)
1413 char *name;
1414 struct dump_file_info *dfi;
1415 FILE *stream;
1417 if (phase == TDI_none || !dump_phase_enabled_p (phase))
1418 return NULL;
1420 name = get_dump_file_name (phase, part);
1421 if (!name)
1422 return NULL;
1423 dfi = get_dump_file_info (phase);
1425 /* We do not support re-opening of dump files with parts. This would require
1426 tracking pstate per part of the dump file. */
1427 stream = dump_open (name, part != -1 || dfi->pstate < 0);
1428 if (stream)
1429 dfi->pstate = 1;
1430 free (name);
1432 if (flag_ptr)
1433 *flag_ptr = dfi->pflags;
1435 /* Initialize current flags */
1436 pflags = dfi->pflags;
1437 return stream;
1440 /* Returns nonzero if dump PHASE is enabled for at least one stream.
1441 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
1442 any phase. */
1445 gcc::dump_manager::
1446 dump_phase_enabled_p (int phase) const
1448 if (phase == TDI_tree_all)
1450 size_t i;
1451 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
1452 if (dump_files[i].pstate || dump_files[i].alt_state)
1453 return 1;
1454 for (i = 0; i < m_extra_dump_files_in_use; i++)
1455 if (m_extra_dump_files[i].pstate || m_extra_dump_files[i].alt_state)
1456 return 1;
1457 return 0;
1459 else
1461 struct dump_file_info *dfi = get_dump_file_info (phase);
1462 return dfi->pstate || dfi->alt_state;
1466 /* Returns nonzero if tree dump PHASE has been initialized. */
1469 gcc::dump_manager::
1470 dump_initialized_p (int phase) const
1472 struct dump_file_info *dfi = get_dump_file_info (phase);
1473 return dfi->pstate > 0 || dfi->alt_state > 0;
1476 /* Returns the switch name of PHASE. */
1478 const char *
1479 dump_flag_name (int phase)
1481 return g->get_dumps ()->dump_flag_name (phase);
1484 const char *
1485 gcc::dump_manager::
1486 dump_flag_name (int phase) const
1488 struct dump_file_info *dfi = get_dump_file_info (phase);
1489 return dfi->swtch;
1492 /* Finish a tree dump for PHASE. STREAM is the stream created by
1493 dump_begin. */
1495 void
1496 dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
1498 if (stream != stderr && stream != stdout)
1499 fclose (stream);
1502 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
1503 enabled tree dumps. */
1506 gcc::dump_manager::
1507 dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename)
1509 int n = 0;
1510 size_t i;
1512 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
1514 if ((dump_files[i].dkind == dkind))
1516 const char *old_filename = dump_files[i].pfilename;
1517 dump_files[i].pstate = -1;
1518 dump_files[i].pflags |= flags;
1519 n++;
1520 /* Override the existing filename. */
1521 if (filename)
1523 dump_files[i].pfilename = xstrdup (filename);
1524 /* Since it is a command-line provided file, which is
1525 common to all the phases, use it in append mode. */
1526 dump_files[i].pstate = 1;
1528 if (old_filename && filename != old_filename)
1529 free (CONST_CAST (char *, old_filename));
1533 for (i = 0; i < m_extra_dump_files_in_use; i++)
1535 if ((m_extra_dump_files[i].dkind == dkind))
1537 const char *old_filename = m_extra_dump_files[i].pfilename;
1538 m_extra_dump_files[i].pstate = -1;
1539 m_extra_dump_files[i].pflags |= flags;
1540 n++;
1541 /* Override the existing filename. */
1542 if (filename)
1544 m_extra_dump_files[i].pfilename = xstrdup (filename);
1545 /* Since it is a command-line provided file, which is
1546 common to all the phases, use it in append mode. */
1547 m_extra_dump_files[i].pstate = 1;
1549 if (old_filename && filename != old_filename)
1550 free (CONST_CAST (char *, old_filename));
1554 return n;
1557 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
1558 Enable dumps with FLAGS on FILENAME. Return the number of enabled
1559 dumps. */
1562 gcc::dump_manager::
1563 opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags,
1564 const char *filename)
1566 int n = 0;
1567 size_t i;
1569 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
1571 if ((dump_files[i].optgroup_flags & optgroup_flags))
1573 const char *old_filename = dump_files[i].alt_filename;
1574 /* Since this file is shared among different passes, it
1575 should be opened in append mode. */
1576 dump_files[i].alt_state = 1;
1577 dump_files[i].alt_flags |= flags;
1578 n++;
1579 /* Override the existing filename. */
1580 if (filename)
1581 dump_files[i].alt_filename = xstrdup (filename);
1582 if (old_filename && filename != old_filename)
1583 free (CONST_CAST (char *, old_filename));
1587 for (i = 0; i < m_extra_dump_files_in_use; i++)
1589 if ((m_extra_dump_files[i].optgroup_flags & optgroup_flags))
1591 const char *old_filename = m_extra_dump_files[i].alt_filename;
1592 /* Since this file is shared among different passes, it
1593 should be opened in append mode. */
1594 m_extra_dump_files[i].alt_state = 1;
1595 m_extra_dump_files[i].alt_flags |= flags;
1596 n++;
1597 /* Override the existing filename. */
1598 if (filename)
1599 m_extra_dump_files[i].alt_filename = xstrdup (filename);
1600 if (old_filename && filename != old_filename)
1601 free (CONST_CAST (char *, old_filename));
1605 return n;
1608 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
1609 relevant details in the dump_files array. */
1612 gcc::dump_manager::
1613 dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
1615 const char *option_value;
1616 const char *ptr;
1617 dump_flags_t flags;
1619 if (doglob && !dfi->glob)
1620 return 0;
1622 option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
1623 if (!option_value)
1624 return 0;
1626 if (*option_value && *option_value != '-' && *option_value != '=')
1627 return 0;
1629 ptr = option_value;
1630 flags = TDF_NONE;
1632 while (*ptr)
1634 const struct kv_pair<dump_flags_t> *option_ptr;
1635 const char *end_ptr;
1636 const char *eq_ptr;
1637 unsigned length;
1639 while (*ptr == '-')
1640 ptr++;
1641 end_ptr = strchr (ptr, '-');
1642 eq_ptr = strchr (ptr, '=');
1644 if (eq_ptr && !end_ptr)
1645 end_ptr = eq_ptr;
1647 if (!end_ptr)
1648 end_ptr = ptr + strlen (ptr);
1649 length = end_ptr - ptr;
1651 for (option_ptr = dump_options; option_ptr->name; option_ptr++)
1652 if (strlen (option_ptr->name) == length
1653 && !memcmp (option_ptr->name, ptr, length))
1655 flags |= option_ptr->value;
1656 goto found;
1659 if (*ptr == '=')
1661 /* Interpret rest of the argument as a dump filename. This
1662 filename overrides other command line filenames. */
1663 if (dfi->pfilename)
1664 free (CONST_CAST (char *, dfi->pfilename));
1665 dfi->pfilename = xstrdup (ptr + 1);
1666 break;
1668 else
1669 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
1670 length, ptr, dfi->swtch);
1671 found:;
1672 ptr = end_ptr;
1675 dfi->pstate = -1;
1676 dfi->pflags |= flags;
1678 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
1679 known dumps. */
1680 if (dfi->suffix == NULL)
1681 dump_enable_all (dfi->dkind, dfi->pflags, dfi->pfilename);
1683 return 1;
1687 gcc::dump_manager::
1688 dump_switch_p (const char *arg)
1690 size_t i;
1691 int any = 0;
1693 for (i = TDI_none + 1; i != TDI_end; i++)
1694 any |= dump_switch_p_1 (arg, &dump_files[i], false);
1696 /* Don't glob if we got a hit already */
1697 if (!any)
1698 for (i = TDI_none + 1; i != TDI_end; i++)
1699 any |= dump_switch_p_1 (arg, &dump_files[i], true);
1701 for (i = 0; i < m_extra_dump_files_in_use; i++)
1702 any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], false);
1704 if (!any)
1705 for (i = 0; i < m_extra_dump_files_in_use; i++)
1706 any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], true);
1709 return any;
1712 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
1713 and filename. Return non-zero if it is a recognized switch. */
1715 static int
1716 opt_info_switch_p_1 (const char *arg, dump_flags_t *flags,
1717 optgroup_flags_t *optgroup_flags, char **filename)
1719 const char *option_value;
1720 const char *ptr;
1722 option_value = arg;
1723 ptr = option_value;
1725 *filename = NULL;
1726 *flags = TDF_NONE;
1727 *optgroup_flags = OPTGROUP_NONE;
1729 if (!ptr)
1730 return 1; /* Handle '-fopt-info' without any additional options. */
1732 while (*ptr)
1734 const char *end_ptr;
1735 const char *eq_ptr;
1736 unsigned length;
1738 while (*ptr == '-')
1739 ptr++;
1740 end_ptr = strchr (ptr, '-');
1741 eq_ptr = strchr (ptr, '=');
1743 if (eq_ptr && !end_ptr)
1744 end_ptr = eq_ptr;
1746 if (!end_ptr)
1747 end_ptr = ptr + strlen (ptr);
1748 length = end_ptr - ptr;
1750 for (const kv_pair<dump_flags_t> *option_ptr = optinfo_verbosity_options;
1751 option_ptr->name; option_ptr++)
1752 if (strlen (option_ptr->name) == length
1753 && !memcmp (option_ptr->name, ptr, length))
1755 *flags |= option_ptr->value;
1756 goto found;
1759 for (const kv_pair<optgroup_flags_t> *option_ptr = optgroup_options;
1760 option_ptr->name; option_ptr++)
1761 if (strlen (option_ptr->name) == length
1762 && !memcmp (option_ptr->name, ptr, length))
1764 *optgroup_flags |= option_ptr->value;
1765 goto found;
1768 if (*ptr == '=')
1770 /* Interpret rest of the argument as a dump filename. This
1771 filename overrides other command line filenames. */
1772 *filename = xstrdup (ptr + 1);
1773 break;
1775 else
1777 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
1778 length, ptr, arg);
1779 return 0;
1781 found:;
1782 ptr = end_ptr;
1785 return 1;
1788 /* Return non-zero if ARG is a recognized switch for
1789 -fopt-info. Return zero otherwise. */
1792 opt_info_switch_p (const char *arg)
1794 dump_flags_t flags;
1795 optgroup_flags_t optgroup_flags;
1796 char *filename;
1797 static char *file_seen = NULL;
1798 gcc::dump_manager *dumps = g->get_dumps ();
1800 if (!opt_info_switch_p_1 (arg, &flags, &optgroup_flags, &filename))
1801 return 0;
1803 if (!filename)
1804 filename = xstrdup ("stderr");
1806 /* Bail out if a different filename has been specified. */
1807 if (file_seen && strcmp (file_seen, filename))
1809 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
1810 arg);
1811 return 1;
1814 file_seen = xstrdup (filename);
1815 if (!flags)
1816 flags = MSG_OPTIMIZED_LOCATIONS;
1817 if (!optgroup_flags)
1818 optgroup_flags = OPTGROUP_ALL;
1820 return dumps->opt_info_enable_passes (optgroup_flags, flags, filename);
1823 /* Print basic block on the dump streams. */
1825 void
1826 dump_basic_block (dump_flags_t dump_kind, basic_block bb, int indent)
1828 if (dump_file && (dump_kind & pflags))
1829 dump_bb (dump_file, bb, indent, TDF_DETAILS);
1830 if (alt_dump_file && (dump_kind & alt_flags))
1831 dump_bb (alt_dump_file, bb, indent, TDF_DETAILS);
1834 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
1836 void
1837 dump_function (int phase, tree fn)
1839 FILE *stream;
1840 dump_flags_t flags;
1842 stream = dump_begin (phase, &flags);
1843 if (stream)
1845 dump_function_to_file (fn, stream, flags);
1846 dump_end (phase, stream);
1850 /* Print information from the combine pass on dump_file. */
1852 void
1853 print_combine_total_stats (void)
1855 if (dump_file)
1856 dump_combine_total_stats (dump_file);
1859 /* Enable RTL dump for all the RTL passes. */
1861 bool
1862 enable_rtl_dump_file (void)
1864 gcc::dump_manager *dumps = g->get_dumps ();
1865 int num_enabled =
1866 dumps->dump_enable_all (DK_rtl, dump_flags_t (TDF_DETAILS) | TDF_BLOCKS,
1867 NULL);
1868 return num_enabled > 0;
1871 #if CHECKING_P
1873 /* temp_dump_context's ctor. Temporarily override the dump_context
1874 (to forcibly enable optinfo-generation). */
1876 temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo,
1877 dump_flags_t test_pp_flags)
1879 : m_context (),
1880 m_saved (&dump_context ().get ())
1882 dump_context::s_current = &m_context;
1883 m_context.m_forcibly_enable_optinfo = forcibly_enable_optinfo;
1884 m_context.m_test_pp = &m_pp;
1885 m_context.m_test_pp_flags = test_pp_flags;
1887 dump_context::get ().refresh_dumps_are_enabled ();
1890 /* temp_dump_context's dtor. Restore the saved dump_context. */
1892 temp_dump_context::~temp_dump_context ()
1894 dump_context::s_current = m_saved;
1896 dump_context::get ().refresh_dumps_are_enabled ();
1899 /* 0-terminate the text dumped so far, and return it. */
1901 const char *
1902 temp_dump_context::get_dumped_text ()
1904 return pp_formatted_text (&m_pp);
1907 namespace selftest {
1909 /* Verify that the dump_location_t constructors capture the source location
1910 at which they were called (provided that the build compiler is sufficiently
1911 recent). */
1913 static void
1914 test_impl_location ()
1916 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
1917 /* Default ctor. */
1919 dump_location_t loc;
1920 const int expected_line = __LINE__ - 1;
1921 ASSERT_STR_CONTAINS (loc.get_impl_location ().m_file, "dumpfile.c");
1922 ASSERT_EQ (loc.get_impl_location ().m_line, expected_line);
1925 /* Constructing from a gimple. */
1927 dump_location_t loc ((gimple *)NULL);
1928 const int expected_line = __LINE__ - 1;
1929 ASSERT_STR_CONTAINS (loc.get_impl_location ().m_file, "dumpfile.c");
1930 ASSERT_EQ (loc.get_impl_location ().m_line, expected_line);
1933 /* Constructing from an rtx_insn. */
1935 dump_location_t loc ((rtx_insn *)NULL);
1936 const int expected_line = __LINE__ - 1;
1937 ASSERT_STR_CONTAINS (loc.get_impl_location ().m_file, "dumpfile.c");
1938 ASSERT_EQ (loc.get_impl_location ().m_line, expected_line);
1940 #endif
1943 /* Verify that the text dumped so far in CONTEXT equals
1944 EXPECTED_TEXT, using LOC for the location of any failure.
1945 As a side-effect, the internal buffer is 0-terminated. */
1947 static void
1948 verify_dumped_text (const location &loc,
1949 temp_dump_context *context,
1950 const char *expected_text)
1952 gcc_assert (context);
1953 ASSERT_STREQ_AT (loc, context->get_dumped_text (),
1954 expected_text);
1957 /* Verify that the text dumped so far in CONTEXT equals
1958 EXPECTED_TEXT.
1959 As a side-effect, the internal buffer is 0-terminated. */
1961 #define ASSERT_DUMPED_TEXT_EQ(CONTEXT, EXPECTED_TEXT) \
1962 SELFTEST_BEGIN_STMT \
1963 verify_dumped_text (SELFTEST_LOCATION, &(CONTEXT), (EXPECTED_TEXT)); \
1964 SELFTEST_END_STMT
1966 /* Verify that ITEM has the expected values. */
1968 static void
1969 verify_item (const location &loc,
1970 const optinfo_item *item,
1971 enum optinfo_item_kind expected_kind,
1972 location_t expected_location,
1973 const char *expected_text)
1975 ASSERT_EQ_AT (loc, item->get_kind (), expected_kind);
1976 ASSERT_EQ_AT (loc, item->get_location (), expected_location);
1977 ASSERT_STREQ_AT (loc, item->get_text (), expected_text);
1980 /* Verify that ITEM is a text item, with EXPECTED_TEXT. */
1982 #define ASSERT_IS_TEXT(ITEM, EXPECTED_TEXT) \
1983 SELFTEST_BEGIN_STMT \
1984 verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_TEXT, \
1985 UNKNOWN_LOCATION, (EXPECTED_TEXT)); \
1986 SELFTEST_END_STMT
1988 /* Verify that ITEM is a tree item, with the expected values. */
1990 #define ASSERT_IS_TREE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
1991 SELFTEST_BEGIN_STMT \
1992 verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_TREE, \
1993 (EXPECTED_LOCATION), (EXPECTED_TEXT)); \
1994 SELFTEST_END_STMT
1996 /* Verify that ITEM is a gimple item, with the expected values. */
1998 #define ASSERT_IS_GIMPLE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
1999 SELFTEST_BEGIN_STMT \
2000 verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_GIMPLE, \
2001 (EXPECTED_LOCATION), (EXPECTED_TEXT)); \
2002 SELFTEST_END_STMT
2004 /* Verify that calls to the dump_* API are captured and consolidated into
2005 optimization records. */
2007 static void
2008 test_capture_of_dump_calls (const line_table_case &case_)
2010 /* Generate a location_t for testing. */
2011 line_table_test ltt (case_);
2012 linemap_add (line_table, LC_ENTER, false, "test.txt", 0);
2013 linemap_line_start (line_table, 5, 100);
2014 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2015 location_t where = linemap_position_for_column (line_table, 10);
2016 if (where > LINE_MAP_MAX_LOCATION_WITH_COLS)
2017 return;
2019 dump_location_t loc = dump_location_t::from_location_t (where);
2021 gimple *stmt = gimple_build_return (NULL);
2022 gimple_set_location (stmt, where);
2024 tree test_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
2025 get_identifier ("test_decl"),
2026 integer_type_node);
2027 /* Run all tests twice, with and then without optinfo enabled, to ensure
2028 that immediate destinations vs optinfo-based destinations both
2029 work, independently of each other, with no leaks. */
2030 for (int i = 0 ; i < 2; i++)
2032 bool with_optinfo = (i == 0);
2034 /* Test of dump_printf. */
2036 temp_dump_context tmp (with_optinfo, MSG_ALL);
2037 dump_printf (MSG_NOTE, "int: %i str: %s", 42, "foo");
2039 ASSERT_DUMPED_TEXT_EQ (tmp, "int: 42 str: foo");
2040 if (with_optinfo)
2042 optinfo *info = tmp.get_pending_optinfo ();
2043 ASSERT_TRUE (info != NULL);
2044 ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
2045 ASSERT_EQ (info->num_items (), 1);
2046 ASSERT_IS_TEXT (info->get_item (0), "int: 42 str: foo");
2050 /* Test of dump_printf with %T. */
2052 temp_dump_context tmp (with_optinfo, MSG_ALL);
2053 dump_printf (MSG_NOTE, "tree: %T", integer_zero_node);
2055 ASSERT_DUMPED_TEXT_EQ (tmp, "tree: 0");
2056 if (with_optinfo)
2058 optinfo *info = tmp.get_pending_optinfo ();
2059 ASSERT_TRUE (info != NULL);
2060 ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
2061 ASSERT_EQ (info->num_items (), 2);
2062 ASSERT_IS_TEXT (info->get_item (0), "tree: ");
2063 ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
2067 /* Test of dump_printf with %E. */
2069 temp_dump_context tmp (with_optinfo, MSG_ALL);
2070 dump_printf (MSG_NOTE, "gimple: %E", stmt);
2072 ASSERT_DUMPED_TEXT_EQ (tmp, "gimple: return;");
2073 if (with_optinfo)
2075 optinfo *info = tmp.get_pending_optinfo ();
2076 ASSERT_TRUE (info != NULL);
2077 ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
2078 ASSERT_EQ (info->num_items (), 2);
2079 ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
2080 ASSERT_IS_GIMPLE (info->get_item (1), where, "return;");
2084 /* Test of dump_printf with %G. */
2086 temp_dump_context tmp (with_optinfo, MSG_ALL);
2087 dump_printf (MSG_NOTE, "gimple: %G", stmt);
2089 ASSERT_DUMPED_TEXT_EQ (tmp, "gimple: return;\n");
2090 if (with_optinfo)
2092 optinfo *info = tmp.get_pending_optinfo ();
2093 ASSERT_TRUE (info != NULL);
2094 ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
2095 ASSERT_EQ (info->num_items (), 2);
2096 ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
2097 ASSERT_IS_GIMPLE (info->get_item (1), where, "return;\n");
2101 /* dump_print_loc with multiple format codes. This tests various
2102 things:
2103 - intermingling of text, format codes handled by the base
2104 pretty_printer, and dump-specific format codes
2105 - multiple dump-specific format codes: some consecutive, others
2106 separated by text, trailing text after the final one. */
2108 temp_dump_context tmp (with_optinfo, MSG_ALL);
2109 dump_printf_loc (MSG_NOTE, loc, "before %T and %T"
2110 " %i consecutive %E%E after\n",
2111 integer_zero_node, test_decl, 42, stmt, stmt);
2113 ASSERT_DUMPED_TEXT_EQ (tmp,
2114 "test.txt:5:10: note: before 0 and test_decl"
2115 " 42 consecutive return;return; after\n");
2116 if (with_optinfo)
2118 optinfo *info = tmp.get_pending_optinfo ();
2119 ASSERT_TRUE (info != NULL);
2120 ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
2121 ASSERT_EQ (info->num_items (), 8);
2122 ASSERT_IS_TEXT (info->get_item (0), "before ");
2123 ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
2124 ASSERT_IS_TEXT (info->get_item (2), " and ");
2125 ASSERT_IS_TREE (info->get_item (3), UNKNOWN_LOCATION, "test_decl");
2126 ASSERT_IS_TEXT (info->get_item (4), " 42 consecutive ");
2127 ASSERT_IS_GIMPLE (info->get_item (5), where, "return;");
2128 ASSERT_IS_GIMPLE (info->get_item (6), where, "return;");
2129 ASSERT_IS_TEXT (info->get_item (7), " after\n");
2133 /* Tree, via dump_generic_expr. */
2135 temp_dump_context tmp (with_optinfo, MSG_ALL);
2136 dump_printf_loc (MSG_NOTE, loc, "test of tree: ");
2137 dump_generic_expr (MSG_NOTE, TDF_SLIM, integer_zero_node);
2139 ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: test of tree: 0");
2140 if (with_optinfo)
2142 optinfo *info = tmp.get_pending_optinfo ();
2143 ASSERT_TRUE (info != NULL);
2144 ASSERT_EQ (info->get_location_t (), where);
2145 ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
2146 ASSERT_EQ (info->num_items (), 2);
2147 ASSERT_IS_TEXT (info->get_item (0), "test of tree: ");
2148 ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
2152 /* Tree, via dump_generic_expr_loc. */
2154 temp_dump_context tmp (with_optinfo, MSG_ALL);
2155 dump_generic_expr_loc (MSG_NOTE, loc, TDF_SLIM, integer_one_node);
2157 ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: 1");
2158 if (with_optinfo)
2160 optinfo *info = tmp.get_pending_optinfo ();
2161 ASSERT_TRUE (info != NULL);
2162 ASSERT_EQ (info->get_location_t (), where);
2163 ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
2164 ASSERT_EQ (info->num_items (), 1);
2165 ASSERT_IS_TREE (info->get_item (0), UNKNOWN_LOCATION, "1");
2169 /* Gimple. */
2171 /* dump_gimple_stmt_loc. */
2173 temp_dump_context tmp (with_optinfo, MSG_ALL);
2174 dump_gimple_stmt_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
2176 ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: return;\n");
2177 if (with_optinfo)
2179 optinfo *info = tmp.get_pending_optinfo ();
2180 ASSERT_TRUE (info != NULL);
2181 ASSERT_EQ (info->num_items (), 1);
2182 ASSERT_IS_GIMPLE (info->get_item (0), where, "return;\n");
2186 /* dump_gimple_stmt. */
2188 temp_dump_context tmp (with_optinfo, MSG_ALL);
2189 dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 2);
2191 ASSERT_DUMPED_TEXT_EQ (tmp, "return;\n");
2192 if (with_optinfo)
2194 optinfo *info = tmp.get_pending_optinfo ();
2195 ASSERT_TRUE (info != NULL);
2196 ASSERT_EQ (info->num_items (), 1);
2197 ASSERT_IS_GIMPLE (info->get_item (0), where, "return;\n");
2201 /* dump_gimple_expr_loc. */
2203 temp_dump_context tmp (with_optinfo, MSG_ALL);
2204 dump_gimple_expr_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
2206 ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: return;");
2207 if (with_optinfo)
2209 optinfo *info = tmp.get_pending_optinfo ();
2210 ASSERT_TRUE (info != NULL);
2211 ASSERT_EQ (info->num_items (), 1);
2212 ASSERT_IS_GIMPLE (info->get_item (0), where, "return;");
2216 /* dump_gimple_expr. */
2218 temp_dump_context tmp (with_optinfo, MSG_ALL);
2219 dump_gimple_expr (MSG_NOTE, TDF_SLIM, stmt, 2);
2221 ASSERT_DUMPED_TEXT_EQ (tmp, "return;");
2222 if (with_optinfo)
2224 optinfo *info = tmp.get_pending_optinfo ();
2225 ASSERT_TRUE (info != NULL);
2226 ASSERT_EQ (info->num_items (), 1);
2227 ASSERT_IS_GIMPLE (info->get_item (0), where, "return;");
2232 /* poly_int. */
2234 temp_dump_context tmp (with_optinfo, MSG_ALL);
2235 dump_dec (MSG_NOTE, poly_int64 (42));
2237 ASSERT_DUMPED_TEXT_EQ (tmp, "42");
2238 if (with_optinfo)
2240 optinfo *info = tmp.get_pending_optinfo ();
2241 ASSERT_TRUE (info != NULL);
2242 ASSERT_EQ (info->num_items (), 1);
2243 ASSERT_IS_TEXT (info->get_item (0), "42");
2247 /* scopes. */
2249 temp_dump_context tmp (with_optinfo, MSG_ALL);
2250 dump_printf_loc (MSG_NOTE, stmt, "msg 1\n");
2252 AUTO_DUMP_SCOPE ("outer scope", stmt);
2253 dump_printf_loc (MSG_NOTE, stmt, "msg 2\n");
2255 AUTO_DUMP_SCOPE ("middle scope", stmt);
2256 dump_printf_loc (MSG_NOTE, stmt, "msg 3\n");
2258 AUTO_DUMP_SCOPE ("inner scope", stmt);
2259 dump_printf_loc (MSG_NOTE, stmt, "msg 4\n");
2261 dump_printf_loc (MSG_NOTE, stmt, "msg 5\n");
2263 dump_printf_loc (MSG_NOTE, stmt, "msg 6\n");
2265 dump_printf_loc (MSG_NOTE, stmt, "msg 7\n");
2267 ASSERT_DUMPED_TEXT_EQ (tmp,
2268 "test.txt:5:10: note: msg 1\n"
2269 "test.txt:5:10: note: === outer scope ===\n"
2270 "test.txt:5:10: note: msg 2\n"
2271 "test.txt:5:10: note: === middle scope ===\n"
2272 "test.txt:5:10: note: msg 3\n"
2273 "test.txt:5:10: note: === inner scope ===\n"
2274 "test.txt:5:10: note: msg 4\n"
2275 "test.txt:5:10: note: msg 5\n"
2276 "test.txt:5:10: note: msg 6\n"
2277 "test.txt:5:10: note: msg 7\n");
2278 if (with_optinfo)
2280 optinfo *info = tmp.get_pending_optinfo ();
2281 ASSERT_TRUE (info != NULL);
2282 ASSERT_EQ (info->num_items (), 1);
2283 ASSERT_IS_TEXT (info->get_item (0), "msg 7\n");
2288 /* Verify that MSG_* affects optinfo->get_kind (); we tested MSG_NOTE
2289 above. */
2291 /* MSG_OPTIMIZED_LOCATIONS. */
2293 temp_dump_context tmp (true, MSG_ALL);
2294 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, "test");
2295 ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
2296 OPTINFO_KIND_SUCCESS);
2299 /* MSG_MISSED_OPTIMIZATION. */
2301 temp_dump_context tmp (true, MSG_ALL);
2302 dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, "test");
2303 ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
2304 OPTINFO_KIND_FAILURE);
2309 /* Run all of the selftests within this file. */
2311 void
2312 dumpfile_c_tests ()
2314 test_impl_location ();
2315 for_each_line_table_case (test_capture_of_dump_calls);
2318 } // namespace selftest
2320 #endif /* CHECKING_P */