* pt.c (lookup_template_class_1): Splice out abi_tag attribute if
[official-gcc.git] / gcc / dumpfile.c
blobfca7b5145ba8d1fc33e001498f78def24bf686ec
1 /* Dump infrastructure for optimizations and intermediate representation.
2 Copyright (C) 2012-2014 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 "diagnostic-core.h"
24 #include "dumpfile.h"
25 #include "tree.h"
26 #include "gimple-pretty-print.h"
27 #include "context.h"
29 /* If non-NULL, return one past-the-end of the matching SUBPART of
30 the WHOLE string. */
31 #define skip_leading_substring(whole, part) \
32 (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
34 static int pflags; /* current dump_flags */
35 static int alt_flags; /* current opt_info flags */
37 static void dump_loc (int, FILE *, source_location);
38 static FILE *dump_open_alternate_stream (struct dump_file_info *);
40 /* These are currently used for communicating between passes.
41 However, instead of accessing them directly, the passes can use
42 dump_printf () for dumps. */
43 FILE *dump_file = NULL;
44 FILE *alt_dump_file = NULL;
45 const char *dump_file_name;
46 int dump_flags;
48 /* Table of tree dump switches. This must be consistent with the
49 TREE_DUMP_INDEX enumeration in dumpfile.h. */
50 static struct dump_file_info dump_files[TDI_end] =
52 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0},
53 {".cgraph", "ipa-cgraph", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
54 0, 0, 0, 0, 0},
55 {".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
56 0, 0, 0, 0, 0},
57 {".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
58 0, 0, 0, 0, 1},
59 {".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
60 0, 0, 0, 0, 2},
61 {".original", "tree-original", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
62 0, 0, 0, 0, 3},
63 {".gimple", "tree-gimple", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
64 0, 0, 0, 0, 4},
65 {".nested", "tree-nested", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
66 0, 0, 0, 0, 5},
67 #define FIRST_AUTO_NUMBERED_DUMP 6
69 {NULL, "tree-all", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
70 0, 0, 0, 0, 0},
71 {NULL, "rtl-all", NULL, NULL, NULL, NULL, NULL, TDF_RTL,
72 0, 0, 0, 0, 0},
73 {NULL, "ipa-all", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
74 0, 0, 0, 0, 0},
77 /* Define a name->number mapping for a dump flag value. */
78 struct dump_option_value_info
80 const char *const name; /* the name of the value */
81 const int value; /* the value of the name */
84 /* Table of dump options. This must be consistent with the TDF_* flags
85 in dumpfile.h and opt_info_options below. */
86 static const struct dump_option_value_info dump_options[] =
88 {"address", TDF_ADDRESS},
89 {"asmname", TDF_ASMNAME},
90 {"slim", TDF_SLIM},
91 {"raw", TDF_RAW},
92 {"graph", TDF_GRAPH},
93 {"details", (TDF_DETAILS | MSG_OPTIMIZED_LOCATIONS
94 | MSG_MISSED_OPTIMIZATION
95 | MSG_NOTE)},
96 {"cselib", TDF_CSELIB},
97 {"stats", TDF_STATS},
98 {"blocks", TDF_BLOCKS},
99 {"vops", TDF_VOPS},
100 {"lineno", TDF_LINENO},
101 {"uid", TDF_UID},
102 {"stmtaddr", TDF_STMTADDR},
103 {"memsyms", TDF_MEMSYMS},
104 {"verbose", TDF_VERBOSE},
105 {"eh", TDF_EH},
106 {"alias", TDF_ALIAS},
107 {"nouid", TDF_NOUID},
108 {"enumerate_locals", TDF_ENUMERATE_LOCALS},
109 {"scev", TDF_SCEV},
110 {"optimized", MSG_OPTIMIZED_LOCATIONS},
111 {"missed", MSG_MISSED_OPTIMIZATION},
112 {"note", MSG_NOTE},
113 {"optall", MSG_ALL},
114 {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
115 | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
116 | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
117 {NULL, 0}
120 /* A subset of the dump_options table which is used for -fopt-info
121 types. This must be consistent with the MSG_* flags in dumpfile.h.
123 static const struct dump_option_value_info optinfo_verbosity_options[] =
125 {"optimized", MSG_OPTIMIZED_LOCATIONS},
126 {"missed", MSG_MISSED_OPTIMIZATION},
127 {"note", MSG_NOTE},
128 {"all", MSG_ALL},
129 {NULL, 0}
132 /* Flags used for -fopt-info groups. */
133 static const struct dump_option_value_info optgroup_options[] =
135 {"ipa", OPTGROUP_IPA},
136 {"loop", OPTGROUP_LOOP},
137 {"inline", OPTGROUP_INLINE},
138 {"vec", OPTGROUP_VEC},
139 {"optall", OPTGROUP_ALL},
140 {NULL, 0}
143 gcc::dump_manager::dump_manager ():
144 m_next_dump (FIRST_AUTO_NUMBERED_DUMP),
145 m_extra_dump_files (NULL),
146 m_extra_dump_files_in_use (0),
147 m_extra_dump_files_alloced (0)
151 unsigned int
152 gcc::dump_manager::
153 dump_register (const char *suffix, const char *swtch, const char *glob,
154 int flags, int optgroup_flags)
156 int num = m_next_dump++;
158 size_t count = m_extra_dump_files_in_use++;
160 if (count >= m_extra_dump_files_alloced)
162 if (m_extra_dump_files_alloced == 0)
163 m_extra_dump_files_alloced = 32;
164 else
165 m_extra_dump_files_alloced *= 2;
166 m_extra_dump_files = XRESIZEVEC (struct dump_file_info,
167 m_extra_dump_files,
168 m_extra_dump_files_alloced);
171 memset (&m_extra_dump_files[count], 0, sizeof (struct dump_file_info));
172 m_extra_dump_files[count].suffix = suffix;
173 m_extra_dump_files[count].swtch = swtch;
174 m_extra_dump_files[count].glob = glob;
175 m_extra_dump_files[count].pflags = flags;
176 m_extra_dump_files[count].optgroup_flags = optgroup_flags;
177 m_extra_dump_files[count].num = num;
179 return count + TDI_end;
183 /* Return the dump_file_info for the given phase. */
185 struct dump_file_info *
186 gcc::dump_manager::
187 get_dump_file_info (int phase) const
189 if (phase < TDI_end)
190 return &dump_files[phase];
191 else if ((size_t) (phase - TDI_end) >= m_extra_dump_files_in_use)
192 return NULL;
193 else
194 return m_extra_dump_files + (phase - TDI_end);
198 /* Return the name of the dump file for the given phase.
199 If the dump is not enabled, returns NULL. */
201 char *
202 gcc::dump_manager::
203 get_dump_file_name (int phase) const
205 char dump_id[10];
206 struct dump_file_info *dfi;
208 if (phase == TDI_none)
209 return NULL;
211 dfi = get_dump_file_info (phase);
212 if (dfi->pstate == 0)
213 return NULL;
215 /* If available, use the command line dump filename. */
216 if (dfi->pfilename)
217 return xstrdup (dfi->pfilename);
219 if (dfi->num < 0)
220 dump_id[0] = '\0';
221 else
223 char suffix;
224 if (dfi->pflags & TDF_TREE)
225 suffix = 't';
226 else if (dfi->pflags & TDF_IPA)
227 suffix = 'i';
228 else
229 suffix = 'r';
231 if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
232 dump_id[0] = '\0';
235 return concat (dump_base_name, dump_id, dfi->suffix, NULL);
238 /* For a given DFI, open an alternate dump filename (which could also
239 be a standard stream such as stdout/stderr). If the alternate dump
240 file cannot be opened, return NULL. */
242 static FILE *
243 dump_open_alternate_stream (struct dump_file_info *dfi)
245 FILE *stream ;
246 if (!dfi->alt_filename)
247 return NULL;
249 if (dfi->alt_stream)
250 return dfi->alt_stream;
252 stream = strcmp ("stderr", dfi->alt_filename) == 0
253 ? stderr
254 : strcmp ("stdout", dfi->alt_filename) == 0
255 ? stdout
256 : fopen (dfi->alt_filename, dfi->alt_state < 0 ? "w" : "a");
258 if (!stream)
259 error ("could not open dump file %qs: %m", dfi->alt_filename);
260 else
261 dfi->alt_state = 1;
263 return stream;
266 /* Print source location on DFILE if enabled. */
268 void
269 dump_loc (int dump_kind, FILE *dfile, source_location loc)
271 if (dump_kind)
273 if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
274 fprintf (dfile, "%s:%d:%d: note: ", LOCATION_FILE (loc),
275 LOCATION_LINE (loc), LOCATION_COLUMN (loc));
276 else if (current_function_decl)
277 fprintf (dfile, "%s:%d:%d: note: ",
278 DECL_SOURCE_FILE (current_function_decl),
279 DECL_SOURCE_LINE (current_function_decl),
280 DECL_SOURCE_COLUMN (current_function_decl));
284 /* Dump gimple statement GS with SPC indentation spaces and
285 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
287 void
288 dump_gimple_stmt (int dump_kind, int extra_dump_flags, gimple gs, int spc)
290 if (dump_file && (dump_kind & pflags))
291 print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
293 if (alt_dump_file && (dump_kind & alt_flags))
294 print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
297 /* Similar to dump_gimple_stmt, except additionally print source location. */
299 void
300 dump_gimple_stmt_loc (int dump_kind, source_location loc, int extra_dump_flags,
301 gimple gs, int spc)
303 if (dump_file && (dump_kind & pflags))
305 dump_loc (dump_kind, dump_file, loc);
306 print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
309 if (alt_dump_file && (dump_kind & alt_flags))
311 dump_loc (dump_kind, alt_dump_file, loc);
312 print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
316 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
317 DUMP_KIND is enabled. */
319 void
320 dump_generic_expr (int dump_kind, int extra_dump_flags, tree t)
322 if (dump_file && (dump_kind & pflags))
323 print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
325 if (alt_dump_file && (dump_kind & alt_flags))
326 print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
330 /* Similar to dump_generic_expr, except additionally print the source
331 location. */
333 void
334 dump_generic_expr_loc (int dump_kind, source_location loc,
335 int extra_dump_flags, tree t)
337 if (dump_file && (dump_kind & pflags))
339 dump_loc (dump_kind, dump_file, loc);
340 print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
343 if (alt_dump_file && (dump_kind & alt_flags))
345 dump_loc (dump_kind, alt_dump_file, loc);
346 print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
350 /* Output a formatted message using FORMAT on appropriate dump streams. */
352 void
353 dump_printf (int dump_kind, const char *format, ...)
355 if (dump_file && (dump_kind & pflags))
357 va_list ap;
358 va_start (ap, format);
359 vfprintf (dump_file, format, ap);
360 va_end (ap);
363 if (alt_dump_file && (dump_kind & alt_flags))
365 va_list ap;
366 va_start (ap, format);
367 vfprintf (alt_dump_file, format, ap);
368 va_end (ap);
372 /* Similar to dump_printf, except source location is also printed. */
374 void
375 dump_printf_loc (int dump_kind, source_location loc, const char *format, ...)
377 if (dump_file && (dump_kind & pflags))
379 va_list ap;
380 dump_loc (dump_kind, dump_file, loc);
381 va_start (ap, format);
382 vfprintf (dump_file, format, ap);
383 va_end (ap);
386 if (alt_dump_file && (dump_kind & alt_flags))
388 va_list ap;
389 dump_loc (dump_kind, alt_dump_file, loc);
390 va_start (ap, format);
391 vfprintf (alt_dump_file, format, ap);
392 va_end (ap);
396 /* Start a dump for PHASE. Store user-supplied dump flags in
397 *FLAG_PTR. Return the number of streams opened. Set globals
398 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
399 set dump_flags appropriately for both pass dump stream and
400 -fopt-info stream. */
403 gcc::dump_manager::
404 dump_start (int phase, int *flag_ptr)
406 int count = 0;
407 char *name;
408 struct dump_file_info *dfi;
409 FILE *stream;
410 if (phase == TDI_none || !dump_phase_enabled_p (phase))
411 return 0;
413 dfi = get_dump_file_info (phase);
414 name = get_dump_file_name (phase);
415 if (name)
417 stream = strcmp ("stderr", name) == 0
418 ? stderr
419 : strcmp ("stdout", name) == 0
420 ? stdout
421 : fopen (name, dfi->pstate < 0 ? "w" : "a");
422 if (!stream)
423 error ("could not open dump file %qs: %m", name);
424 else
426 dfi->pstate = 1;
427 count++;
429 free (name);
430 dfi->pstream = stream;
431 dump_file = dfi->pstream;
432 /* Initialize current dump flags. */
433 pflags = dfi->pflags;
436 stream = dump_open_alternate_stream (dfi);
437 if (stream)
439 dfi->alt_stream = stream;
440 count++;
441 alt_dump_file = dfi->alt_stream;
442 /* Initialize current -fopt-info flags. */
443 alt_flags = dfi->alt_flags;
446 if (flag_ptr)
447 *flag_ptr = dfi->pflags;
449 return count;
452 /* Finish a tree dump for PHASE and close associated dump streams. Also
453 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
455 void
456 gcc::dump_manager::
457 dump_finish (int phase)
459 struct dump_file_info *dfi;
461 if (phase < 0)
462 return;
463 dfi = get_dump_file_info (phase);
464 if (dfi->pstream && (!dfi->pfilename
465 || (strcmp ("stderr", dfi->pfilename) != 0
466 && strcmp ("stdout", dfi->pfilename) != 0)))
467 fclose (dfi->pstream);
469 if (dfi->alt_stream && strcmp ("stderr", dfi->alt_filename) != 0
470 && strcmp ("stdout", dfi->alt_filename) != 0)
471 fclose (dfi->alt_stream);
473 dfi->alt_stream = NULL;
474 dfi->pstream = NULL;
475 dump_file = NULL;
476 alt_dump_file = NULL;
477 dump_flags = TDI_none;
478 alt_flags = 0;
479 pflags = 0;
482 /* Begin a tree dump for PHASE. Stores any user supplied flag in
483 *FLAG_PTR and returns a stream to write to. If the dump is not
484 enabled, returns NULL.
485 Multiple calls will reopen and append to the dump file. */
487 FILE *
488 dump_begin (int phase, int *flag_ptr)
490 return g->get_dumps ()->dump_begin (phase, flag_ptr);
493 FILE *
494 gcc::dump_manager::
495 dump_begin (int phase, int *flag_ptr)
497 char *name;
498 struct dump_file_info *dfi;
499 FILE *stream;
501 if (phase == TDI_none || !dump_phase_enabled_p (phase))
502 return NULL;
504 name = get_dump_file_name (phase);
505 if (!name)
506 return NULL;
507 dfi = get_dump_file_info (phase);
509 stream = strcmp ("stderr", name) == 0
510 ? stderr
511 : strcmp ("stdout", name) == 0
512 ? stdout
513 : fopen (name, dfi->pstate < 0 ? "w" : "a");
515 if (!stream)
516 error ("could not open dump file %qs: %m", name);
517 else
518 dfi->pstate = 1;
519 free (name);
521 if (flag_ptr)
522 *flag_ptr = dfi->pflags;
524 /* Initialize current flags */
525 pflags = dfi->pflags;
526 return stream;
529 /* Returns nonzero if dump PHASE is enabled for at least one stream.
530 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
531 any phase. */
534 gcc::dump_manager::
535 dump_phase_enabled_p (int phase) const
537 if (phase == TDI_tree_all)
539 size_t i;
540 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
541 if (dump_files[i].pstate || dump_files[i].alt_state)
542 return 1;
543 for (i = 0; i < m_extra_dump_files_in_use; i++)
544 if (m_extra_dump_files[i].pstate || m_extra_dump_files[i].alt_state)
545 return 1;
546 return 0;
548 else
550 struct dump_file_info *dfi = get_dump_file_info (phase);
551 return dfi->pstate || dfi->alt_state;
555 /* Returns nonzero if tree dump PHASE has been initialized. */
558 gcc::dump_manager::
559 dump_initialized_p (int phase) const
561 struct dump_file_info *dfi = get_dump_file_info (phase);
562 return dfi->pstate > 0 || dfi->alt_state > 0;
565 /* Returns the switch name of PHASE. */
567 const char *
568 dump_flag_name (int phase)
570 return g->get_dumps ()->dump_flag_name (phase);
573 const char *
574 gcc::dump_manager::
575 dump_flag_name (int phase) const
577 struct dump_file_info *dfi = get_dump_file_info (phase);
578 return dfi->swtch;
581 /* Finish a tree dump for PHASE. STREAM is the stream created by
582 dump_begin. */
584 void
585 dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
587 if (stream != stderr && stream != stdout)
588 fclose (stream);
591 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
592 enabled tree dumps. */
595 gcc::dump_manager::
596 dump_enable_all (int flags, const char *filename)
598 int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
599 int n = 0;
600 size_t i;
602 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
604 if ((dump_files[i].pflags & ir_dump_type))
606 const char *old_filename = dump_files[i].pfilename;
607 dump_files[i].pstate = -1;
608 dump_files[i].pflags |= flags;
609 n++;
610 /* Override the existing filename. */
611 if (filename)
613 dump_files[i].pfilename = xstrdup (filename);
614 /* Since it is a command-line provided file, which is
615 common to all the phases, use it in append mode. */
616 dump_files[i].pstate = 1;
618 if (old_filename && filename != old_filename)
619 free (CONST_CAST (char *, old_filename));
623 for (i = 0; i < m_extra_dump_files_in_use; i++)
625 if ((m_extra_dump_files[i].pflags & ir_dump_type))
627 const char *old_filename = m_extra_dump_files[i].pfilename;
628 m_extra_dump_files[i].pstate = -1;
629 m_extra_dump_files[i].pflags |= flags;
630 n++;
631 /* Override the existing filename. */
632 if (filename)
634 m_extra_dump_files[i].pfilename = xstrdup (filename);
635 /* Since it is a command-line provided file, which is
636 common to all the phases, use it in append mode. */
637 m_extra_dump_files[i].pstate = 1;
639 if (old_filename && filename != old_filename)
640 free (CONST_CAST (char *, old_filename));
644 return n;
647 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
648 Enable dumps with FLAGS on FILENAME. Return the number of enabled
649 dumps. */
652 gcc::dump_manager::
653 opt_info_enable_passes (int optgroup_flags, int flags, const char *filename)
655 int n = 0;
656 size_t i;
658 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
660 if ((dump_files[i].optgroup_flags & optgroup_flags))
662 const char *old_filename = dump_files[i].alt_filename;
663 /* Since this file is shared among different passes, it
664 should be opened in append mode. */
665 dump_files[i].alt_state = 1;
666 dump_files[i].alt_flags |= flags;
667 n++;
668 /* Override the existing filename. */
669 if (filename)
670 dump_files[i].alt_filename = xstrdup (filename);
671 if (old_filename && filename != old_filename)
672 free (CONST_CAST (char *, old_filename));
676 for (i = 0; i < m_extra_dump_files_in_use; i++)
678 if ((m_extra_dump_files[i].optgroup_flags & optgroup_flags))
680 const char *old_filename = m_extra_dump_files[i].alt_filename;
681 /* Since this file is shared among different passes, it
682 should be opened in append mode. */
683 m_extra_dump_files[i].alt_state = 1;
684 m_extra_dump_files[i].alt_flags |= flags;
685 n++;
686 /* Override the existing filename. */
687 if (filename)
688 m_extra_dump_files[i].alt_filename = xstrdup (filename);
689 if (old_filename && filename != old_filename)
690 free (CONST_CAST (char *, old_filename));
694 return n;
697 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
698 relevant details in the dump_files array. */
701 gcc::dump_manager::
702 dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
704 const char *option_value;
705 const char *ptr;
706 int flags;
708 if (doglob && !dfi->glob)
709 return 0;
711 option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
712 if (!option_value)
713 return 0;
715 if (*option_value && *option_value != '-' && *option_value != '=')
716 return 0;
718 ptr = option_value;
719 flags = 0;
721 while (*ptr)
723 const struct dump_option_value_info *option_ptr;
724 const char *end_ptr;
725 const char *eq_ptr;
726 unsigned length;
728 while (*ptr == '-')
729 ptr++;
730 end_ptr = strchr (ptr, '-');
731 eq_ptr = strchr (ptr, '=');
733 if (eq_ptr && !end_ptr)
734 end_ptr = eq_ptr;
736 if (!end_ptr)
737 end_ptr = ptr + strlen (ptr);
738 length = end_ptr - ptr;
740 for (option_ptr = dump_options; option_ptr->name; option_ptr++)
741 if (strlen (option_ptr->name) == length
742 && !memcmp (option_ptr->name, ptr, length))
744 flags |= option_ptr->value;
745 goto found;
748 if (*ptr == '=')
750 /* Interpret rest of the argument as a dump filename. This
751 filename overrides other command line filenames. */
752 if (dfi->pfilename)
753 free (CONST_CAST (char *, dfi->pfilename));
754 dfi->pfilename = xstrdup (ptr + 1);
755 break;
757 else
758 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
759 length, ptr, dfi->swtch);
760 found:;
761 ptr = end_ptr;
764 dfi->pstate = -1;
765 dfi->pflags |= flags;
767 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
768 known dumps. */
769 if (dfi->suffix == NULL)
770 dump_enable_all (dfi->pflags, dfi->pfilename);
772 return 1;
776 gcc::dump_manager::
777 dump_switch_p (const char *arg)
779 size_t i;
780 int any = 0;
782 for (i = TDI_none + 1; i != TDI_end; i++)
783 any |= dump_switch_p_1 (arg, &dump_files[i], false);
785 /* Don't glob if we got a hit already */
786 if (!any)
787 for (i = TDI_none + 1; i != TDI_end; i++)
788 any |= dump_switch_p_1 (arg, &dump_files[i], true);
790 for (i = 0; i < m_extra_dump_files_in_use; i++)
791 any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], false);
793 if (!any)
794 for (i = 0; i < m_extra_dump_files_in_use; i++)
795 any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], true);
798 return any;
801 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
802 and filename. Return non-zero if it is a recognized switch. */
804 static int
805 opt_info_switch_p_1 (const char *arg, int *flags, int *optgroup_flags,
806 char **filename)
808 const char *option_value;
809 const char *ptr;
811 option_value = arg;
812 ptr = option_value;
814 *filename = NULL;
815 *flags = 0;
816 *optgroup_flags = 0;
818 if (!ptr)
819 return 1; /* Handle '-fopt-info' without any additional options. */
821 while (*ptr)
823 const struct dump_option_value_info *option_ptr;
824 const char *end_ptr;
825 const char *eq_ptr;
826 unsigned length;
828 while (*ptr == '-')
829 ptr++;
830 end_ptr = strchr (ptr, '-');
831 eq_ptr = strchr (ptr, '=');
833 if (eq_ptr && !end_ptr)
834 end_ptr = eq_ptr;
836 if (!end_ptr)
837 end_ptr = ptr + strlen (ptr);
838 length = end_ptr - ptr;
840 for (option_ptr = optinfo_verbosity_options; option_ptr->name;
841 option_ptr++)
842 if (strlen (option_ptr->name) == length
843 && !memcmp (option_ptr->name, ptr, length))
845 *flags |= option_ptr->value;
846 goto found;
849 for (option_ptr = optgroup_options; option_ptr->name; option_ptr++)
850 if (strlen (option_ptr->name) == length
851 && !memcmp (option_ptr->name, ptr, length))
853 *optgroup_flags |= option_ptr->value;
854 goto found;
857 if (*ptr == '=')
859 /* Interpret rest of the argument as a dump filename. This
860 filename overrides other command line filenames. */
861 *filename = xstrdup (ptr + 1);
862 break;
864 else
866 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
867 length, ptr, arg);
868 return 0;
870 found:;
871 ptr = end_ptr;
874 return 1;
877 /* Return non-zero if ARG is a recognized switch for
878 -fopt-info. Return zero otherwise. */
881 opt_info_switch_p (const char *arg)
883 int flags;
884 int optgroup_flags;
885 char *filename;
886 static char *file_seen = NULL;
887 gcc::dump_manager *dumps = g->get_dumps ();
889 if (!opt_info_switch_p_1 (arg, &flags, &optgroup_flags, &filename))
890 return 0;
892 if (!filename)
893 filename = xstrdup ("stderr");
895 /* Bail out if a different filename has been specified. */
896 if (file_seen && strcmp (file_seen, filename))
898 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
899 arg);
900 return 1;
903 file_seen = xstrdup (filename);
904 if (!flags)
905 flags = MSG_OPTIMIZED_LOCATIONS;
906 if (!optgroup_flags)
907 optgroup_flags = OPTGROUP_ALL;
909 return dumps->opt_info_enable_passes (optgroup_flags, flags, filename);
912 /* Print basic block on the dump streams. */
914 void
915 dump_basic_block (int dump_kind, basic_block bb, int indent)
917 if (dump_file && (dump_kind & pflags))
918 dump_bb (dump_file, bb, indent, TDF_DETAILS);
919 if (alt_dump_file && (dump_kind & alt_flags))
920 dump_bb (alt_dump_file, bb, indent, TDF_DETAILS);
923 /* Print information from the combine pass on dump_file. */
925 void
926 print_combine_total_stats (void)
928 if (dump_file)
929 dump_combine_total_stats (dump_file);
932 /* Enable RTL dump for all the RTL passes. */
934 bool
935 enable_rtl_dump_file (void)
937 gcc::dump_manager *dumps = g->get_dumps ();
938 int num_enabled =
939 dumps->dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS, NULL);
940 return num_enabled > 0;