* config/rs6000/rs6000.c (rs6000_option_override_internal): Do not
[official-gcc.git] / gcc / dumpfile.c
blob92d1409be081a37888d0c115ab885415b6062e7d
1 /* Dump infrastructure for optimizations and intermediate representation.
2 Copyright (C) 2012 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 "gimple-pretty-print.h"
26 #include "tree.h"
28 /* If non-NULL, return one past-the-end of the matching SUBPART of
29 the WHOLE string. */
30 #define skip_leading_substring(whole, part) \
31 (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
33 static int pflags; /* current dump_flags */
34 static int alt_flags; /* current opt_info flags */
35 static FILE *alt_dump_file = NULL;
37 static void dump_loc (int, FILE *, source_location);
38 static int dump_enabled_p (int);
39 static FILE *dump_open_alternate_stream (struct dump_file_info *);
41 /* Table of tree dump switches. This must be consistent with the
42 TREE_DUMP_INDEX enumeration in dumpfile.h. */
43 static struct dump_file_info dump_files[TDI_end] =
45 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0},
46 {".cgraph", "ipa-cgraph", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
47 0, 0, 0, 0},
48 {".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
49 0, 0, 0, 1},
50 {".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
51 0, 0, 0, 2},
52 {".original", "tree-original", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
53 0, 0, 0, 3},
54 {".gimple", "tree-gimple", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
55 0, 0, 0, 4},
56 {".nested", "tree-nested", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
57 0, 0, 0, 5},
58 {".vcg", "tree-vcg", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
59 0, 0, 0, 6},
60 {".ads", "ada-spec", NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 7},
61 #define FIRST_AUTO_NUMBERED_DUMP 8
63 {NULL, "tree-all", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
64 0, 0, 0, 0},
65 {NULL, "rtl-all", NULL, NULL, NULL, NULL, NULL, TDF_RTL,
66 0, 0, 0, 0},
67 {NULL, "ipa-all", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
68 0, 0, 0, 0},
71 /* Dynamically registered tree dump files and switches. */
72 static struct dump_file_info *extra_dump_files;
73 static size_t extra_dump_files_in_use;
74 static size_t extra_dump_files_alloced;
76 /* Define a name->number mapping for a dump flag value. */
77 struct dump_option_value_info
79 const char *const name; /* the name of the value */
80 const int value; /* the value of the name */
83 /* Table of dump options. This must be consistent with the TDF_* flags
84 in dumpfile.h and opt_info_options below. */
85 static const struct dump_option_value_info dump_options[] =
87 {"address", TDF_ADDRESS},
88 {"asmname", TDF_ASMNAME},
89 {"slim", TDF_SLIM},
90 {"raw", TDF_RAW},
91 {"graph", TDF_GRAPH},
92 {"details", (TDF_DETAILS | MSG_OPTIMIZED_LOCATIONS
93 | MSG_MISSED_OPTIMIZATION
94 | MSG_NOTE)},
95 {"cselib", TDF_CSELIB},
96 {"stats", TDF_STATS},
97 {"blocks", TDF_BLOCKS},
98 {"vops", TDF_VOPS},
99 {"lineno", TDF_LINENO},
100 {"uid", TDF_UID},
101 {"stmtaddr", TDF_STMTADDR},
102 {"memsyms", TDF_MEMSYMS},
103 {"verbose", TDF_VERBOSE},
104 {"eh", TDF_EH},
105 {"alias", TDF_ALIAS},
106 {"nouid", TDF_NOUID},
107 {"enumerate_locals", TDF_ENUMERATE_LOCALS},
108 {"scev", TDF_SCEV},
109 {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
110 | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
111 | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
112 {NULL, 0}
115 /* A subset of the dump_options table which is used for opt-info
116 options. This must be consistent with the MSG_* flags in
117 dump_options.
119 static const struct dump_option_value_info opt_info_options[] =
121 {"optimized", MSG_OPTIMIZED_LOCATIONS},
122 {"missed", MSG_MISSED_OPTIMIZATION},
123 {"note", MSG_NOTE},
124 {"optall", (MSG_OPTIMIZED_LOCATIONS
125 | MSG_MISSED_OPTIMIZATION
126 | MSG_NOTE)},
127 {NULL, 0}
130 unsigned int
131 dump_register (const char *suffix, const char *swtch, const char *glob,
132 int flags)
134 static int next_dump = FIRST_AUTO_NUMBERED_DUMP;
135 int num = next_dump++;
137 size_t count = extra_dump_files_in_use++;
139 if (count >= extra_dump_files_alloced)
141 if (extra_dump_files_alloced == 0)
142 extra_dump_files_alloced = 32;
143 else
144 extra_dump_files_alloced *= 2;
145 extra_dump_files = XRESIZEVEC (struct dump_file_info,
146 extra_dump_files,
147 extra_dump_files_alloced);
150 memset (&extra_dump_files[count], 0, sizeof (struct dump_file_info));
151 extra_dump_files[count].suffix = suffix;
152 extra_dump_files[count].swtch = swtch;
153 extra_dump_files[count].glob = glob;
154 extra_dump_files[count].pflags = flags;
155 extra_dump_files[count].num = num;
157 return count + TDI_end;
161 /* Return the dump_file_info for the given phase. */
163 struct dump_file_info *
164 get_dump_file_info (int phase)
166 if (phase < TDI_end)
167 return &dump_files[phase];
168 else if ((size_t) (phase - TDI_end) >= extra_dump_files_in_use)
169 return NULL;
170 else
171 return extra_dump_files + (phase - TDI_end);
175 /* Return the name of the dump file for the given phase.
176 If the dump is not enabled, returns NULL. */
178 char *
179 get_dump_file_name (int phase)
181 char dump_id[10];
182 struct dump_file_info *dfi;
184 if (phase == TDI_none)
185 return NULL;
187 dfi = get_dump_file_info (phase);
188 if (dfi->pstate == 0)
189 return NULL;
191 /* If available, use the command line dump filename. */
192 if (dfi->pfilename)
193 return xstrdup (dfi->pfilename);
195 if (dfi->num < 0)
196 dump_id[0] = '\0';
197 else
199 char suffix;
200 if (dfi->pflags & TDF_TREE)
201 suffix = 't';
202 else if (dfi->pflags & TDF_IPA)
203 suffix = 'i';
204 else
205 suffix = 'r';
207 if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
208 dump_id[0] = '\0';
211 return concat (dump_base_name, dump_id, dfi->suffix, NULL);
214 /* For a given DFI, open an alternate dump filename (which could also
215 be a standard stream such as stdout/stderr). If the alternate dump
216 file cannot be opened, return NULL. */
218 static FILE *
219 dump_open_alternate_stream (struct dump_file_info *dfi)
221 FILE *stream ;
222 if (!dfi->alt_filename)
223 return NULL;
225 if (dfi->alt_stream)
226 return dfi->alt_stream;
228 stream = strcmp("stderr", dfi->alt_filename) == 0
229 ? stderr
230 : strcmp("stdout", dfi->alt_filename) == 0
231 ? stdout
232 : fopen (dfi->alt_filename, dfi->alt_state < 0 ? "w" : "a");
234 if (!stream)
235 error ("could not open dump file %qs: %m", dfi->alt_filename);
236 else
237 dfi->alt_state = 1;
239 return stream;
242 /* Print source location on DFILE if enabled. */
244 void
245 dump_loc (int dump_kind, FILE *dfile, source_location loc)
247 /* Currently vectorization passes print location information. */
248 if (dump_kind)
250 if (loc == UNKNOWN_LOCATION)
251 fprintf (dfile, "\n%s:%d: note: ",
252 DECL_SOURCE_FILE (current_function_decl),
253 DECL_SOURCE_LINE (current_function_decl));
254 else
255 fprintf (dfile, "\n%d: ", LOCATION_LINE (loc));
259 /* Dump gimple statement GS with SPC indentation spaces and
260 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
262 void
263 dump_gimple_stmt (int dump_kind, int extra_dump_flags, gimple gs, int spc)
265 if (dump_file && (dump_kind & pflags))
266 print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
268 if (alt_dump_file && (dump_kind & alt_flags))
269 print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
272 /* Similar to dump_gimple_stmt, except additionally print source location. */
274 void
275 dump_gimple_stmt_loc (int dump_kind, source_location loc, int extra_dump_flags,
276 gimple gs, int spc)
278 if (dump_file && (dump_kind & pflags))
280 dump_loc (dump_kind, dump_file, loc);
281 print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
284 if (alt_dump_file && (dump_kind & alt_flags))
286 dump_loc (dump_kind, alt_dump_file, loc);
287 print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
291 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
292 DUMP_KIND is enabled. */
294 void
295 dump_generic_expr (int dump_kind, int extra_dump_flags, tree t)
297 if (dump_file && (dump_kind & pflags))
298 print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
300 if (alt_dump_file && (dump_kind & alt_flags))
301 print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
305 /* Similar to dump_generic_expr, except additionally print the source
306 location. */
308 void
309 dump_generic_expr_loc (int dump_kind, source_location loc,
310 int extra_dump_flags, tree t)
312 if (dump_file && (dump_kind & pflags))
314 dump_loc (dump_kind, dump_file, loc);
315 print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
318 if (alt_dump_file && (dump_kind & alt_flags))
320 dump_loc (dump_kind, alt_dump_file, loc);
321 print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
325 /* Output a formatted message using FORMAT on appropriate dump streams. */
327 void
328 dump_printf (int dump_kind, const char *format, ...)
330 if (dump_file && (dump_kind & pflags))
332 va_list ap;
333 va_start (ap, format);
334 vfprintf (dump_file, format, ap);
335 va_end (ap);
338 if (alt_dump_file && (dump_kind & alt_flags))
340 va_list ap;
341 va_start (ap, format);
342 vfprintf (alt_dump_file, format, ap);
343 va_end (ap);
347 /* Similar to dump_printf, except source location is also printed. */
349 void
350 dump_printf_loc (int dump_kind, source_location loc, const char *format, ...)
352 if (dump_file && (dump_kind & pflags))
354 va_list ap;
355 dump_loc (dump_kind, dump_file, loc);
356 va_start (ap, format);
357 vfprintf (dump_file, format, ap);
358 va_end (ap);
361 if (alt_dump_file && (dump_kind & alt_flags))
363 va_list ap;
364 dump_loc (dump_kind, alt_dump_file, loc);
365 va_start (ap, format);
366 vfprintf (alt_dump_file, format, ap);
367 va_end (ap);
371 /* Start a dump for PHASE. Store user-supplied dump flags in
372 *FLAG_PTR. Return the number of streams opened. Set globals
373 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
374 set dump_flags appropriately for both pass dump stream and opt-info
375 stream. */
378 dump_start (int phase, int *flag_ptr)
380 int count = 0;
381 char *name;
382 struct dump_file_info *dfi;
383 FILE *stream;
384 if (phase == TDI_none || !dump_enabled_p (phase))
385 return 0;
387 dfi = get_dump_file_info (phase);
388 name = get_dump_file_name (phase);
389 if (name)
391 stream = strcmp("stderr", name) == 0
392 ? stderr
393 : strcmp("stdout", name) == 0
394 ? stdout
395 : fopen (name, dfi->pstate < 0 ? "w" : "a");
396 if (!stream)
397 error ("could not open dump file %qs: %m", name);
398 else
400 dfi->pstate = 1;
401 count++;
403 free (name);
404 dfi->pstream = stream;
405 dump_file = dfi->pstream;
406 /* Initialize current dump flags. */
407 pflags = dfi->pflags;
410 stream = dump_open_alternate_stream (dfi);
411 if (stream)
413 dfi->alt_stream = stream;
414 count++;
415 alt_dump_file = dfi->alt_stream;
416 /* Initialize current opt-info flags. */
417 alt_flags = dfi->alt_flags;
420 if (flag_ptr)
421 *flag_ptr = dfi->pflags;
423 return count;
426 /* Finish a tree dump for PHASE and close associated dump streams. Also
427 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
429 void
430 dump_finish (int phase)
432 struct dump_file_info *dfi;
434 if (phase < 0)
435 return;
436 dfi = get_dump_file_info (phase);
437 if (dfi->pstream)
438 fclose (dfi->pstream);
440 if (dfi->alt_stream && strcmp("stderr", dfi->alt_filename) != 0
441 && strcmp("stdout", dfi->alt_filename) != 0)
442 fclose (dfi->alt_stream);
444 dfi->alt_stream = NULL;
445 dfi->pstream = NULL;
446 dump_file = NULL;
447 alt_dump_file = NULL;
448 dump_flags = TDI_none;
449 alt_flags = 0;
450 pflags = 0;
453 /* Begin a tree dump for PHASE. Stores any user supplied flag in
454 *FLAG_PTR and returns a stream to write to. If the dump is not
455 enabled, returns NULL.
456 Multiple calls will reopen and append to the dump file. */
458 FILE *
459 dump_begin (int phase, int *flag_ptr)
461 char *name;
462 struct dump_file_info *dfi;
463 FILE *stream;
465 if (phase == TDI_none || !dump_enabled_p (phase))
466 return NULL;
468 name = get_dump_file_name (phase);
469 if (!name)
470 return NULL;
471 dfi = get_dump_file_info (phase);
473 stream = strcmp("stderr", name) == 0
474 ? stderr
475 : strcmp("stdout", name) == 0
476 ? stdout
477 : fopen (name, dfi->pstate < 0 ? "w" : "a");
479 if (!stream)
480 error ("could not open dump file %qs: %m", name);
481 else
482 dfi->pstate = 1;
483 free (name);
485 if (flag_ptr)
486 *flag_ptr = dfi->pflags;
488 /* Initialize current flags */
489 pflags = dfi->pflags;
490 return stream;
493 /* Returns nonzero if dump PHASE is enabled for at least one stream.
494 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
495 any phase. */
498 dump_enabled_p (int phase)
500 if (phase == TDI_tree_all)
502 size_t i;
503 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
504 if (dump_files[i].pstate || dump_files[i].alt_state)
505 return 1;
506 for (i = 0; i < extra_dump_files_in_use; i++)
507 if (extra_dump_files[i].pstate || extra_dump_files[i].alt_state)
508 return 1;
509 return 0;
511 else
513 struct dump_file_info *dfi = get_dump_file_info (phase);
514 return dfi->pstate || dfi->alt_state;
518 /* Returns nonzero if tree dump PHASE has been initialized. */
521 dump_initialized_p (int phase)
523 struct dump_file_info *dfi = get_dump_file_info (phase);
524 return dfi->pstate > 0 || dfi->alt_state > 0;
527 /* Returns the switch name of PHASE. */
529 const char *
530 dump_flag_name (int phase)
532 struct dump_file_info *dfi = get_dump_file_info (phase);
533 return dfi->swtch;
536 /* Finish a tree dump for PHASE. STREAM is the stream created by
537 dump_begin. */
539 void
540 dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
542 if (stream != stderr && stream != stdout)
543 fclose (stream);
546 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
547 enabled tree dumps. */
549 static int
550 dump_enable_all (int flags, const char *filename)
552 int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
553 int n = 0;
554 size_t i;
556 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
558 if ((dump_files[i].pflags & ir_dump_type))
560 const char *old_filename = dump_files[i].pfilename;
561 dump_files[i].pstate = -1;
562 dump_files[i].pflags |= flags;
563 n++;
564 /* Override the existing filename. */
565 if (filename)
567 dump_files[i].pfilename = xstrdup (filename);
568 /* Since it is a command-line provided file, which is
569 common to all the phases, use it in append mode. */
570 dump_files[i].pstate = 1;
572 if (old_filename && filename != old_filename)
573 free (CONST_CAST (char *, old_filename));
577 for (i = 0; i < extra_dump_files_in_use; i++)
579 if ((extra_dump_files[i].pflags & ir_dump_type))
581 const char *old_filename = extra_dump_files[i].pfilename;
582 extra_dump_files[i].pstate = -1;
583 extra_dump_files[i].pflags |= flags;
584 n++;
585 /* Override the existing filename. */
586 if (filename)
588 extra_dump_files[i].pfilename = xstrdup (filename);
589 /* Since it is a command-line provided file, which is
590 common to all the phases, use it in append mode. */
591 extra_dump_files[i].pstate = 1;
593 if (old_filename && filename != old_filename)
594 free (CONST_CAST (char *, old_filename));
598 return n;
601 /* Enable opt-info dumps on all IR_DUMP_TYPE passes with FLAGS on
602 FILENAME. Return the number of enabled dumps. */
604 static int
605 opt_info_enable_all (int ir_dump_type, int flags, const char *filename)
607 int n = 0;
608 size_t i;
610 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
612 if ((dump_files[i].pflags & ir_dump_type))
614 const char *old_filename = dump_files[i].alt_filename;
615 /* Since this file is shared among different passes, it
616 should be opened in append mode. */
617 dump_files[i].alt_state = 1;
618 dump_files[i].alt_flags |= flags;
619 n++;
620 /* Override the existing filename. */
621 if (filename)
622 dump_files[i].alt_filename = xstrdup (filename);
623 if (old_filename && filename != old_filename)
624 free (CONST_CAST (char *, old_filename));
628 for (i = 0; i < extra_dump_files_in_use; i++)
630 if ((extra_dump_files[i].pflags & ir_dump_type))
632 const char *old_filename = extra_dump_files[i].alt_filename;
633 /* Since this file is shared among different passes, it
634 should be opened in append mode. */
635 extra_dump_files[i].alt_state = 1;
636 extra_dump_files[i].alt_flags |= flags;
637 n++;
638 /* Override the existing filename. */
639 if (filename)
640 extra_dump_files[i].alt_filename = xstrdup (filename);
641 if (old_filename && filename != old_filename)
642 free (CONST_CAST (char *, old_filename));
646 return n;
649 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
650 relevant details in the dump_files array. */
652 static int
653 dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
655 const char *option_value;
656 const char *ptr;
657 int flags;
659 if (doglob && !dfi->glob)
660 return 0;
662 option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
663 if (!option_value)
664 return 0;
666 if (*option_value && *option_value != '-' && *option_value != '=')
667 return 0;
669 ptr = option_value;
670 flags = 0;
672 while (*ptr)
674 const struct dump_option_value_info *option_ptr;
675 const char *end_ptr;
676 const char *eq_ptr;
677 unsigned length;
679 while (*ptr == '-')
680 ptr++;
681 end_ptr = strchr (ptr, '-');
682 eq_ptr = strchr (ptr, '=');
684 if (eq_ptr && !end_ptr)
685 end_ptr = eq_ptr;
687 if (!end_ptr)
688 end_ptr = ptr + strlen (ptr);
689 length = end_ptr - ptr;
691 for (option_ptr = dump_options; option_ptr->name; option_ptr++)
692 if (strlen (option_ptr->name) == length
693 && !memcmp (option_ptr->name, ptr, length))
695 flags |= option_ptr->value;
696 goto found;
699 if (*ptr == '=')
701 /* Interpret rest of the argument as a dump filename. This
702 filename overrides other command line filenames. */
703 if (dfi->pfilename)
704 free (CONST_CAST (char *, dfi->pfilename));
705 dfi->pfilename = xstrdup (ptr + 1);
706 break;
708 else
709 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
710 length, ptr, dfi->swtch);
711 found:;
712 ptr = end_ptr;
715 dfi->pstate = -1;
716 dfi->pflags |= flags;
718 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
719 known dumps. */
720 if (dfi->suffix == NULL)
721 dump_enable_all (dfi->pflags, dfi->pfilename);
723 return 1;
727 dump_switch_p (const char *arg)
729 size_t i;
730 int any = 0;
732 for (i = TDI_none + 1; i != TDI_end; i++)
733 any |= dump_switch_p_1 (arg, &dump_files[i], false);
735 /* Don't glob if we got a hit already */
736 if (!any)
737 for (i = TDI_none + 1; i != TDI_end; i++)
738 any |= dump_switch_p_1 (arg, &dump_files[i], true);
740 for (i = 0; i < extra_dump_files_in_use; i++)
741 any |= dump_switch_p_1 (arg, &extra_dump_files[i], false);
743 if (!any)
744 for (i = 0; i < extra_dump_files_in_use; i++)
745 any |= dump_switch_p_1 (arg, &extra_dump_files[i], true);
748 return any;
751 /* Parse ARG as a -fopt-info switch and store flags and filename.
752 Return non-zero if it is a recognized switch. */
754 static int
755 opt_info_switch_p_1 (const char *arg, int *flags, char **filename)
757 const char *option_value;
758 const char *ptr;
760 option_value = arg;
761 ptr = option_value;
763 *filename = NULL;
764 *flags = 0;
766 if (!ptr)
767 return 1;
769 while (*ptr)
771 const struct dump_option_value_info *option_ptr;
772 const char *end_ptr;
773 const char *eq_ptr;
774 unsigned length;
776 while (*ptr == '-')
777 ptr++;
778 end_ptr = strchr (ptr, '-');
779 eq_ptr = strchr (ptr, '=');
781 if (eq_ptr && !end_ptr)
782 end_ptr = eq_ptr;
784 if (!end_ptr)
785 end_ptr = ptr + strlen (ptr);
786 length = end_ptr - ptr;
788 for (option_ptr = opt_info_options; option_ptr->name; option_ptr++)
789 if (strlen (option_ptr->name) == length
790 && !memcmp (option_ptr->name, ptr, length))
792 *flags |= option_ptr->value;
793 goto found;
796 if (*ptr == '=')
798 /* Interpret rest of the argument as a dump filename. This
799 filename overrides other command line filenames. */
800 *filename = xstrdup (ptr + 1);
801 break;
803 else
804 warning (0, "ignoring unknown option %q.*s in %<-fopt-info=%s%>",
805 length, ptr, arg);
806 found:;
807 ptr = end_ptr;
810 return 1;
813 /* Return non-zero if ARG is a recognized switch for
814 -fopt-info. Return zero otherwise. */
817 opt_info_switch_p (const char *arg)
819 int flags;
820 char *filename;
822 opt_info_switch_p_1 (arg, &flags, &filename);
824 if (!filename)
825 filename = xstrdup ("stderr");
826 if (!flags)
827 flags = MSG_ALL;
829 return opt_info_enable_all ((TDF_TREE | TDF_RTL | TDF_IPA), flags, filename);
832 /* Return true if any dumps are enabled for the given MSG_TYPE, false
833 otherwise. */
835 bool
836 dump_kind_p (int msg_type)
838 if (!current_function_decl)
839 return 0;
840 return ((msg_type & pflags) || (msg_type & alt_flags));
843 /* Print basic block on the dump streams. */
845 void
846 dump_basic_block (int dump_kind, basic_block bb, int indent)
848 if (dump_file && (dump_kind & pflags))
849 dump_bb (dump_file, bb, indent, TDF_DETAILS);
850 if (alt_dump_file && (dump_kind & alt_flags))
851 dump_bb (alt_dump_file, bb, indent, TDF_DETAILS);
854 /* Print information from the combine pass on dump_file. */
856 void
857 print_combine_total_stats (void)
859 if (dump_file)
860 dump_combine_total_stats (dump_file);
863 /* Enable RTL dump for all the RTL passes. */
865 bool
866 enable_rtl_dump_file (void)
868 return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS, NULL) > 0;