1 /* Dump infrastructure for optimizations and intermediate representation.
2 Copyright (C) 2012-2015 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
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
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/>. */
22 #include "coretypes.h"
23 #include "diagnostic-core.h"
28 #include "gimple-pretty-print.h"
31 /* If non-NULL, return one past-the-end of the matching SUBPART of
33 #define skip_leading_substring(whole, part) \
34 (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
36 static int pflags
; /* current dump_flags */
37 static int alt_flags
; /* current opt_info flags */
39 static void dump_loc (int, FILE *, source_location
);
40 static FILE *dump_open_alternate_stream (struct dump_file_info
*);
42 /* These are currently used for communicating between passes.
43 However, instead of accessing them directly, the passes can use
44 dump_printf () for dumps. */
45 FILE *dump_file
= NULL
;
46 FILE *alt_dump_file
= NULL
;
47 const char *dump_file_name
;
50 /* Table of tree dump switches. This must be consistent with the
51 TREE_DUMP_INDEX enumeration in dumpfile.h. */
52 static struct dump_file_info dump_files
[TDI_end
] =
54 {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, 0, 0, 0, 0, 0, 0, false},
55 {".cgraph", "ipa-cgraph", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
56 0, 0, 0, 0, 0, false},
57 {".type-inheritance", "ipa-type-inheritance", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
58 0, 0, 0, 0, 0, false},
59 {".tu", "translation-unit", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
60 0, 0, 0, 0, 1, false},
61 {".class", "class-hierarchy", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
62 0, 0, 0, 0, 2, false},
63 {".original", "tree-original", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
64 0, 0, 0, 0, 3, false},
65 {".gimple", "tree-gimple", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
66 0, 0, 0, 0, 4, false},
67 {".nested", "tree-nested", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
68 0, 0, 0, 0, 5, false},
69 #define FIRST_AUTO_NUMBERED_DUMP 6
71 {NULL
, "tree-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
72 0, 0, 0, 0, 0, false},
73 {NULL
, "rtl-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_RTL
,
74 0, 0, 0, 0, 0, false},
75 {NULL
, "ipa-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
76 0, 0, 0, 0, 0, false},
79 /* Define a name->number mapping for a dump flag value. */
80 struct dump_option_value_info
82 const char *const name
; /* the name of the value */
83 const int value
; /* the value of the name */
86 /* Table of dump options. This must be consistent with the TDF_* flags
87 in dumpfile.h and opt_info_options below. */
88 static const struct dump_option_value_info dump_options
[] =
90 {"address", TDF_ADDRESS
},
91 {"asmname", TDF_ASMNAME
},
95 {"details", (TDF_DETAILS
| MSG_OPTIMIZED_LOCATIONS
96 | MSG_MISSED_OPTIMIZATION
98 {"cselib", TDF_CSELIB
},
100 {"blocks", TDF_BLOCKS
},
102 {"lineno", TDF_LINENO
},
104 {"stmtaddr", TDF_STMTADDR
},
105 {"memsyms", TDF_MEMSYMS
},
106 {"verbose", TDF_VERBOSE
},
108 {"alias", TDF_ALIAS
},
109 {"nouid", TDF_NOUID
},
110 {"enumerate_locals", TDF_ENUMERATE_LOCALS
},
112 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
113 {"missed", MSG_MISSED_OPTIMIZATION
},
116 {"all", ~(TDF_RAW
| TDF_SLIM
| TDF_LINENO
| TDF_TREE
| TDF_RTL
| TDF_IPA
117 | TDF_STMTADDR
| TDF_GRAPH
| TDF_DIAGNOSTIC
| TDF_VERBOSE
118 | TDF_RHS_ONLY
| TDF_NOUID
| TDF_ENUMERATE_LOCALS
| TDF_SCEV
)},
122 /* A subset of the dump_options table which is used for -fopt-info
123 types. This must be consistent with the MSG_* flags in dumpfile.h.
125 static const struct dump_option_value_info optinfo_verbosity_options
[] =
127 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
128 {"missed", MSG_MISSED_OPTIMIZATION
},
134 /* Flags used for -fopt-info groups. */
135 static const struct dump_option_value_info optgroup_options
[] =
137 {"ipa", OPTGROUP_IPA
},
138 {"loop", OPTGROUP_LOOP
},
139 {"inline", OPTGROUP_INLINE
},
140 {"vec", OPTGROUP_VEC
},
141 {"optall", OPTGROUP_ALL
},
145 gcc::dump_manager::dump_manager ():
146 m_next_dump (FIRST_AUTO_NUMBERED_DUMP
),
147 m_extra_dump_files (NULL
),
148 m_extra_dump_files_in_use (0),
149 m_extra_dump_files_alloced (0)
153 gcc::dump_manager::~dump_manager ()
155 for (size_t i
= 0; i
< m_extra_dump_files_in_use
; i
++)
157 dump_file_info
*dfi
= &m_extra_dump_files
[i
];
158 /* suffix, swtch, glob are statically allocated for the entries
159 in dump_files, and for statistics, but are dynamically allocated
160 for those for passes. */
161 if (dfi
->owns_strings
)
163 XDELETEVEC (const_cast <char *> (dfi
->suffix
));
164 XDELETEVEC (const_cast <char *> (dfi
->swtch
));
165 XDELETEVEC (const_cast <char *> (dfi
->glob
));
167 /* These, if non-NULL, are always dynamically allocated. */
168 XDELETEVEC (const_cast <char *> (dfi
->pfilename
));
169 XDELETEVEC (const_cast <char *> (dfi
->alt_filename
));
171 XDELETEVEC (m_extra_dump_files
);
176 dump_register (const char *suffix
, const char *swtch
, const char *glob
,
177 int flags
, int optgroup_flags
,
180 int num
= m_next_dump
++;
182 size_t count
= m_extra_dump_files_in_use
++;
184 if (count
>= m_extra_dump_files_alloced
)
186 if (m_extra_dump_files_alloced
== 0)
187 m_extra_dump_files_alloced
= 32;
189 m_extra_dump_files_alloced
*= 2;
190 m_extra_dump_files
= XRESIZEVEC (struct dump_file_info
,
192 m_extra_dump_files_alloced
);
195 memset (&m_extra_dump_files
[count
], 0, sizeof (struct dump_file_info
));
196 m_extra_dump_files
[count
].suffix
= suffix
;
197 m_extra_dump_files
[count
].swtch
= swtch
;
198 m_extra_dump_files
[count
].glob
= glob
;
199 m_extra_dump_files
[count
].pflags
= flags
;
200 m_extra_dump_files
[count
].optgroup_flags
= optgroup_flags
;
201 m_extra_dump_files
[count
].num
= num
;
202 m_extra_dump_files
[count
].owns_strings
= take_ownership
;
204 return count
+ TDI_end
;
208 /* Return the dump_file_info for the given phase. */
210 struct dump_file_info
*
212 get_dump_file_info (int phase
) const
215 return &dump_files
[phase
];
216 else if ((size_t) (phase
- TDI_end
) >= m_extra_dump_files_in_use
)
219 return m_extra_dump_files
+ (phase
- TDI_end
);
222 /* Locate the dump_file_info with swtch equal to SWTCH,
223 or return NULL if no such dump_file_info exists. */
225 struct dump_file_info
*
227 get_dump_file_info_by_switch (const char *swtch
) const
229 for (unsigned i
= 0; i
< m_extra_dump_files_in_use
; i
++)
230 if (0 == strcmp (m_extra_dump_files
[i
].swtch
, swtch
))
231 return &m_extra_dump_files
[i
];
238 /* Return the name of the dump file for the given phase.
239 The caller is responsible for calling free on the returned
241 If the dump is not enabled, returns NULL. */
245 get_dump_file_name (int phase
) const
247 struct dump_file_info
*dfi
;
249 if (phase
== TDI_none
)
252 dfi
= get_dump_file_info (phase
);
254 return get_dump_file_name (dfi
);
257 /* Return the name of the dump file for the given dump_file_info.
258 The caller is responsible for calling free on the returned
260 If the dump is not enabled, returns NULL. */
264 get_dump_file_name (struct dump_file_info
*dfi
) const
270 if (dfi
->pstate
== 0)
273 /* If available, use the command line dump filename. */
275 return xstrdup (dfi
->pfilename
);
282 if (dfi
->pflags
& TDF_TREE
)
284 else if (dfi
->pflags
& TDF_IPA
)
289 if (snprintf (dump_id
, sizeof (dump_id
), ".%03d%c", dfi
->num
, suffix
) < 0)
293 return concat (dump_base_name
, dump_id
, dfi
->suffix
, NULL
);
296 /* For a given DFI, open an alternate dump filename (which could also
297 be a standard stream such as stdout/stderr). If the alternate dump
298 file cannot be opened, return NULL. */
301 dump_open_alternate_stream (struct dump_file_info
*dfi
)
304 if (!dfi
->alt_filename
)
308 return dfi
->alt_stream
;
310 stream
= strcmp ("stderr", dfi
->alt_filename
) == 0
312 : strcmp ("stdout", dfi
->alt_filename
) == 0
314 : fopen (dfi
->alt_filename
, dfi
->alt_state
< 0 ? "w" : "a");
317 error ("could not open dump file %qs: %m", dfi
->alt_filename
);
324 /* Print source location on DFILE if enabled. */
327 dump_loc (int dump_kind
, FILE *dfile
, source_location loc
)
331 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
332 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
333 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
334 else if (current_function_decl
)
335 fprintf (dfile
, "%s:%d:%d: note: ",
336 DECL_SOURCE_FILE (current_function_decl
),
337 DECL_SOURCE_LINE (current_function_decl
),
338 DECL_SOURCE_COLUMN (current_function_decl
));
342 /* Dump gimple statement GS with SPC indentation spaces and
343 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
346 dump_gimple_stmt (int dump_kind
, int extra_dump_flags
, gimple
*gs
, int spc
)
348 if (dump_file
&& (dump_kind
& pflags
))
349 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
351 if (alt_dump_file
&& (dump_kind
& alt_flags
))
352 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
355 /* Similar to dump_gimple_stmt, except additionally print source location. */
358 dump_gimple_stmt_loc (int dump_kind
, source_location loc
, int extra_dump_flags
,
361 if (dump_file
&& (dump_kind
& pflags
))
363 dump_loc (dump_kind
, dump_file
, loc
);
364 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
367 if (alt_dump_file
&& (dump_kind
& alt_flags
))
369 dump_loc (dump_kind
, alt_dump_file
, loc
);
370 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
374 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
375 DUMP_KIND is enabled. */
378 dump_generic_expr (int dump_kind
, int extra_dump_flags
, tree t
)
380 if (dump_file
&& (dump_kind
& pflags
))
381 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
383 if (alt_dump_file
&& (dump_kind
& alt_flags
))
384 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
388 /* Similar to dump_generic_expr, except additionally print the source
392 dump_generic_expr_loc (int dump_kind
, source_location loc
,
393 int extra_dump_flags
, tree t
)
395 if (dump_file
&& (dump_kind
& pflags
))
397 dump_loc (dump_kind
, dump_file
, loc
);
398 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
401 if (alt_dump_file
&& (dump_kind
& alt_flags
))
403 dump_loc (dump_kind
, alt_dump_file
, loc
);
404 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
408 /* Output a formatted message using FORMAT on appropriate dump streams. */
411 dump_printf (int dump_kind
, const char *format
, ...)
413 if (dump_file
&& (dump_kind
& pflags
))
416 va_start (ap
, format
);
417 vfprintf (dump_file
, format
, ap
);
421 if (alt_dump_file
&& (dump_kind
& alt_flags
))
424 va_start (ap
, format
);
425 vfprintf (alt_dump_file
, format
, ap
);
430 /* Similar to dump_printf, except source location is also printed. */
433 dump_printf_loc (int dump_kind
, source_location loc
, const char *format
, ...)
435 if (dump_file
&& (dump_kind
& pflags
))
438 dump_loc (dump_kind
, dump_file
, loc
);
439 va_start (ap
, format
);
440 vfprintf (dump_file
, format
, ap
);
444 if (alt_dump_file
&& (dump_kind
& alt_flags
))
447 dump_loc (dump_kind
, alt_dump_file
, loc
);
448 va_start (ap
, format
);
449 vfprintf (alt_dump_file
, format
, ap
);
454 /* Start a dump for PHASE. Store user-supplied dump flags in
455 *FLAG_PTR. Return the number of streams opened. Set globals
456 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
457 set dump_flags appropriately for both pass dump stream and
458 -fopt-info stream. */
462 dump_start (int phase
, int *flag_ptr
)
466 struct dump_file_info
*dfi
;
468 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
471 dfi
= get_dump_file_info (phase
);
472 name
= get_dump_file_name (phase
);
475 stream
= strcmp ("stderr", name
) == 0
477 : strcmp ("stdout", name
) == 0
479 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
481 error ("could not open dump file %qs: %m", name
);
488 dfi
->pstream
= stream
;
489 dump_file
= dfi
->pstream
;
490 /* Initialize current dump flags. */
491 pflags
= dfi
->pflags
;
494 stream
= dump_open_alternate_stream (dfi
);
497 dfi
->alt_stream
= stream
;
499 alt_dump_file
= dfi
->alt_stream
;
500 /* Initialize current -fopt-info flags. */
501 alt_flags
= dfi
->alt_flags
;
505 *flag_ptr
= dfi
->pflags
;
510 /* Finish a tree dump for PHASE and close associated dump streams. Also
511 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
515 dump_finish (int phase
)
517 struct dump_file_info
*dfi
;
521 dfi
= get_dump_file_info (phase
);
522 if (dfi
->pstream
&& (!dfi
->pfilename
523 || (strcmp ("stderr", dfi
->pfilename
) != 0
524 && strcmp ("stdout", dfi
->pfilename
) != 0)))
525 fclose (dfi
->pstream
);
527 if (dfi
->alt_stream
&& strcmp ("stderr", dfi
->alt_filename
) != 0
528 && strcmp ("stdout", dfi
->alt_filename
) != 0)
529 fclose (dfi
->alt_stream
);
531 dfi
->alt_stream
= NULL
;
534 alt_dump_file
= NULL
;
535 dump_flags
= TDI_none
;
540 /* Begin a tree dump for PHASE. Stores any user supplied flag in
541 *FLAG_PTR and returns a stream to write to. If the dump is not
542 enabled, returns NULL.
543 Multiple calls will reopen and append to the dump file. */
546 dump_begin (int phase
, int *flag_ptr
)
548 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
553 dump_begin (int phase
, int *flag_ptr
)
556 struct dump_file_info
*dfi
;
559 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
562 name
= get_dump_file_name (phase
);
565 dfi
= get_dump_file_info (phase
);
567 stream
= strcmp ("stderr", name
) == 0
569 : strcmp ("stdout", name
) == 0
571 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
574 error ("could not open dump file %qs: %m", name
);
580 *flag_ptr
= dfi
->pflags
;
582 /* Initialize current flags */
583 pflags
= dfi
->pflags
;
587 /* Returns nonzero if dump PHASE is enabled for at least one stream.
588 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
593 dump_phase_enabled_p (int phase
) const
595 if (phase
== TDI_tree_all
)
598 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
599 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
601 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
602 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
608 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
609 return dfi
->pstate
|| dfi
->alt_state
;
613 /* Returns nonzero if tree dump PHASE has been initialized. */
617 dump_initialized_p (int phase
) const
619 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
620 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
623 /* Returns the switch name of PHASE. */
626 dump_flag_name (int phase
)
628 return g
->get_dumps ()->dump_flag_name (phase
);
633 dump_flag_name (int phase
) const
635 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
639 /* Finish a tree dump for PHASE. STREAM is the stream created by
643 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
645 if (stream
!= stderr
&& stream
!= stdout
)
649 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
650 enabled tree dumps. */
654 dump_enable_all (int flags
, const char *filename
)
656 int ir_dump_type
= (flags
& (TDF_TREE
| TDF_RTL
| TDF_IPA
));
660 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
662 if ((dump_files
[i
].pflags
& ir_dump_type
))
664 const char *old_filename
= dump_files
[i
].pfilename
;
665 dump_files
[i
].pstate
= -1;
666 dump_files
[i
].pflags
|= flags
;
668 /* Override the existing filename. */
671 dump_files
[i
].pfilename
= xstrdup (filename
);
672 /* Since it is a command-line provided file, which is
673 common to all the phases, use it in append mode. */
674 dump_files
[i
].pstate
= 1;
676 if (old_filename
&& filename
!= old_filename
)
677 free (CONST_CAST (char *, old_filename
));
681 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
683 if ((m_extra_dump_files
[i
].pflags
& ir_dump_type
))
685 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
686 m_extra_dump_files
[i
].pstate
= -1;
687 m_extra_dump_files
[i
].pflags
|= flags
;
689 /* Override the existing filename. */
692 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
693 /* Since it is a command-line provided file, which is
694 common to all the phases, use it in append mode. */
695 m_extra_dump_files
[i
].pstate
= 1;
697 if (old_filename
&& filename
!= old_filename
)
698 free (CONST_CAST (char *, old_filename
));
705 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
706 Enable dumps with FLAGS on FILENAME. Return the number of enabled
711 opt_info_enable_passes (int optgroup_flags
, int flags
, const char *filename
)
716 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
718 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
720 const char *old_filename
= dump_files
[i
].alt_filename
;
721 /* Since this file is shared among different passes, it
722 should be opened in append mode. */
723 dump_files
[i
].alt_state
= 1;
724 dump_files
[i
].alt_flags
|= flags
;
726 /* Override the existing filename. */
728 dump_files
[i
].alt_filename
= xstrdup (filename
);
729 if (old_filename
&& filename
!= old_filename
)
730 free (CONST_CAST (char *, old_filename
));
734 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
736 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
738 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
739 /* Since this file is shared among different passes, it
740 should be opened in append mode. */
741 m_extra_dump_files
[i
].alt_state
= 1;
742 m_extra_dump_files
[i
].alt_flags
|= flags
;
744 /* Override the existing filename. */
746 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
747 if (old_filename
&& filename
!= old_filename
)
748 free (CONST_CAST (char *, old_filename
));
755 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
756 relevant details in the dump_files array. */
760 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
762 const char *option_value
;
766 if (doglob
&& !dfi
->glob
)
769 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
773 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
781 const struct dump_option_value_info
*option_ptr
;
788 end_ptr
= strchr (ptr
, '-');
789 eq_ptr
= strchr (ptr
, '=');
791 if (eq_ptr
&& !end_ptr
)
795 end_ptr
= ptr
+ strlen (ptr
);
796 length
= end_ptr
- ptr
;
798 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
799 if (strlen (option_ptr
->name
) == length
800 && !memcmp (option_ptr
->name
, ptr
, length
))
802 flags
|= option_ptr
->value
;
808 /* Interpret rest of the argument as a dump filename. This
809 filename overrides other command line filenames. */
811 free (CONST_CAST (char *, dfi
->pfilename
));
812 dfi
->pfilename
= xstrdup (ptr
+ 1);
816 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
817 length
, ptr
, dfi
->swtch
);
823 dfi
->pflags
|= flags
;
825 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
827 if (dfi
->suffix
== NULL
)
828 dump_enable_all (dfi
->pflags
, dfi
->pfilename
);
835 dump_switch_p (const char *arg
)
840 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
841 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
843 /* Don't glob if we got a hit already */
845 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
846 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
848 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
849 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
852 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
853 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
859 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
860 and filename. Return non-zero if it is a recognized switch. */
863 opt_info_switch_p_1 (const char *arg
, int *flags
, int *optgroup_flags
,
866 const char *option_value
;
877 return 1; /* Handle '-fopt-info' without any additional options. */
881 const struct dump_option_value_info
*option_ptr
;
888 end_ptr
= strchr (ptr
, '-');
889 eq_ptr
= strchr (ptr
, '=');
891 if (eq_ptr
&& !end_ptr
)
895 end_ptr
= ptr
+ strlen (ptr
);
896 length
= end_ptr
- ptr
;
898 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
900 if (strlen (option_ptr
->name
) == length
901 && !memcmp (option_ptr
->name
, ptr
, length
))
903 *flags
|= option_ptr
->value
;
907 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
908 if (strlen (option_ptr
->name
) == length
909 && !memcmp (option_ptr
->name
, ptr
, length
))
911 *optgroup_flags
|= option_ptr
->value
;
917 /* Interpret rest of the argument as a dump filename. This
918 filename overrides other command line filenames. */
919 *filename
= xstrdup (ptr
+ 1);
924 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
935 /* Return non-zero if ARG is a recognized switch for
936 -fopt-info. Return zero otherwise. */
939 opt_info_switch_p (const char *arg
)
944 static char *file_seen
= NULL
;
945 gcc::dump_manager
*dumps
= g
->get_dumps ();
947 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
951 filename
= xstrdup ("stderr");
953 /* Bail out if a different filename has been specified. */
954 if (file_seen
&& strcmp (file_seen
, filename
))
956 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
961 file_seen
= xstrdup (filename
);
963 flags
= MSG_OPTIMIZED_LOCATIONS
;
965 optgroup_flags
= OPTGROUP_ALL
;
967 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
970 /* Print basic block on the dump streams. */
973 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
975 if (dump_file
&& (dump_kind
& pflags
))
976 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
977 if (alt_dump_file
&& (dump_kind
& alt_flags
))
978 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
981 /* Print information from the combine pass on dump_file. */
984 print_combine_total_stats (void)
987 dump_combine_total_stats (dump_file
);
990 /* Enable RTL dump for all the RTL passes. */
993 enable_rtl_dump_file (void)
995 gcc::dump_manager
*dumps
= g
->get_dumps ();
997 dumps
->dump_enable_all (TDF_RTL
| TDF_DETAILS
| TDF_BLOCKS
, NULL
);
998 return num_enabled
> 0;