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"
29 #include "gimple-pretty-print.h"
32 /* If non-NULL, return one past-the-end of the matching SUBPART of
34 #define skip_leading_substring(whole, part) \
35 (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
37 static int pflags
; /* current dump_flags */
38 static int alt_flags
; /* current opt_info flags */
40 static void dump_loc (int, FILE *, source_location
);
41 static FILE *dump_open_alternate_stream (struct dump_file_info
*);
43 /* These are currently used for communicating between passes.
44 However, instead of accessing them directly, the passes can use
45 dump_printf () for dumps. */
46 FILE *dump_file
= NULL
;
47 FILE *alt_dump_file
= NULL
;
48 const char *dump_file_name
;
51 /* Table of tree dump switches. This must be consistent with the
52 TREE_DUMP_INDEX enumeration in dumpfile.h. */
53 static struct dump_file_info dump_files
[TDI_end
] =
55 {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, 0, 0, 0, 0, 0, 0, false},
56 {".cgraph", "ipa-cgraph", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
57 0, 0, 0, 0, 0, false},
58 {".type-inheritance", "ipa-type-inheritance", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
59 0, 0, 0, 0, 0, false},
60 {".tu", "translation-unit", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
61 0, 0, 0, 0, 1, false},
62 {".class", "class-hierarchy", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
63 0, 0, 0, 0, 2, false},
64 {".original", "tree-original", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
65 0, 0, 0, 0, 3, false},
66 {".gimple", "tree-gimple", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
67 0, 0, 0, 0, 4, false},
68 {".nested", "tree-nested", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
69 0, 0, 0, 0, 5, false},
70 #define FIRST_AUTO_NUMBERED_DUMP 6
72 {NULL
, "tree-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
73 0, 0, 0, 0, 0, false},
74 {NULL
, "rtl-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_RTL
,
75 0, 0, 0, 0, 0, false},
76 {NULL
, "ipa-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
77 0, 0, 0, 0, 0, false},
80 /* Define a name->number mapping for a dump flag value. */
81 struct dump_option_value_info
83 const char *const name
; /* the name of the value */
84 const int value
; /* the value of the name */
87 /* Table of dump options. This must be consistent with the TDF_* flags
88 in dumpfile.h and opt_info_options below. */
89 static const struct dump_option_value_info dump_options
[] =
91 {"address", TDF_ADDRESS
},
92 {"asmname", TDF_ASMNAME
},
96 {"details", (TDF_DETAILS
| MSG_OPTIMIZED_LOCATIONS
97 | MSG_MISSED_OPTIMIZATION
99 {"cselib", TDF_CSELIB
},
100 {"stats", TDF_STATS
},
101 {"blocks", TDF_BLOCKS
},
103 {"lineno", TDF_LINENO
},
105 {"stmtaddr", TDF_STMTADDR
},
106 {"memsyms", TDF_MEMSYMS
},
107 {"verbose", TDF_VERBOSE
},
109 {"alias", TDF_ALIAS
},
110 {"nouid", TDF_NOUID
},
111 {"enumerate_locals", TDF_ENUMERATE_LOCALS
},
113 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
114 {"missed", MSG_MISSED_OPTIMIZATION
},
117 {"all", ~(TDF_RAW
| TDF_SLIM
| TDF_LINENO
| TDF_TREE
| TDF_RTL
| TDF_IPA
118 | TDF_STMTADDR
| TDF_GRAPH
| TDF_DIAGNOSTIC
| TDF_VERBOSE
119 | TDF_RHS_ONLY
| TDF_NOUID
| TDF_ENUMERATE_LOCALS
| TDF_SCEV
)},
123 /* A subset of the dump_options table which is used for -fopt-info
124 types. This must be consistent with the MSG_* flags in dumpfile.h.
126 static const struct dump_option_value_info optinfo_verbosity_options
[] =
128 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
129 {"missed", MSG_MISSED_OPTIMIZATION
},
135 /* Flags used for -fopt-info groups. */
136 static const struct dump_option_value_info optgroup_options
[] =
138 {"ipa", OPTGROUP_IPA
},
139 {"loop", OPTGROUP_LOOP
},
140 {"inline", OPTGROUP_INLINE
},
141 {"vec", OPTGROUP_VEC
},
142 {"optall", OPTGROUP_ALL
},
146 gcc::dump_manager::dump_manager ():
147 m_next_dump (FIRST_AUTO_NUMBERED_DUMP
),
148 m_extra_dump_files (NULL
),
149 m_extra_dump_files_in_use (0),
150 m_extra_dump_files_alloced (0)
154 gcc::dump_manager::~dump_manager ()
156 for (size_t i
= 0; i
< m_extra_dump_files_in_use
; i
++)
158 dump_file_info
*dfi
= &m_extra_dump_files
[i
];
159 /* suffix, swtch, glob are statically allocated for the entries
160 in dump_files, and for statistics, but are dynamically allocated
161 for those for passes. */
162 if (dfi
->owns_strings
)
164 XDELETEVEC (const_cast <char *> (dfi
->suffix
));
165 XDELETEVEC (const_cast <char *> (dfi
->swtch
));
166 XDELETEVEC (const_cast <char *> (dfi
->glob
));
168 /* These, if non-NULL, are always dynamically allocated. */
169 XDELETEVEC (const_cast <char *> (dfi
->pfilename
));
170 XDELETEVEC (const_cast <char *> (dfi
->alt_filename
));
172 XDELETEVEC (m_extra_dump_files
);
177 dump_register (const char *suffix
, const char *swtch
, const char *glob
,
178 int flags
, int optgroup_flags
,
181 int num
= m_next_dump
++;
183 size_t count
= m_extra_dump_files_in_use
++;
185 if (count
>= m_extra_dump_files_alloced
)
187 if (m_extra_dump_files_alloced
== 0)
188 m_extra_dump_files_alloced
= 32;
190 m_extra_dump_files_alloced
*= 2;
191 m_extra_dump_files
= XRESIZEVEC (struct dump_file_info
,
193 m_extra_dump_files_alloced
);
196 memset (&m_extra_dump_files
[count
], 0, sizeof (struct dump_file_info
));
197 m_extra_dump_files
[count
].suffix
= suffix
;
198 m_extra_dump_files
[count
].swtch
= swtch
;
199 m_extra_dump_files
[count
].glob
= glob
;
200 m_extra_dump_files
[count
].pflags
= flags
;
201 m_extra_dump_files
[count
].optgroup_flags
= optgroup_flags
;
202 m_extra_dump_files
[count
].num
= num
;
203 m_extra_dump_files
[count
].owns_strings
= take_ownership
;
205 return count
+ TDI_end
;
209 /* Return the dump_file_info for the given phase. */
211 struct dump_file_info
*
213 get_dump_file_info (int phase
) const
216 return &dump_files
[phase
];
217 else if ((size_t) (phase
- TDI_end
) >= m_extra_dump_files_in_use
)
220 return m_extra_dump_files
+ (phase
- TDI_end
);
223 /* Locate the dump_file_info with swtch equal to SWTCH,
224 or return NULL if no such dump_file_info exists. */
226 struct dump_file_info
*
228 get_dump_file_info_by_switch (const char *swtch
) const
230 for (unsigned i
= 0; i
< m_extra_dump_files_in_use
; i
++)
231 if (0 == strcmp (m_extra_dump_files
[i
].swtch
, swtch
))
232 return &m_extra_dump_files
[i
];
239 /* Return the name of the dump file for the given phase.
240 The caller is responsible for calling free on the returned
242 If the dump is not enabled, returns NULL. */
246 get_dump_file_name (int phase
) const
248 struct dump_file_info
*dfi
;
250 if (phase
== TDI_none
)
253 dfi
= get_dump_file_info (phase
);
255 return get_dump_file_name (dfi
);
258 /* Return the name of the dump file for the given dump_file_info.
259 The caller is responsible for calling free on the returned
261 If the dump is not enabled, returns NULL. */
265 get_dump_file_name (struct dump_file_info
*dfi
) const
271 if (dfi
->pstate
== 0)
274 /* If available, use the command line dump filename. */
276 return xstrdup (dfi
->pfilename
);
283 if (dfi
->pflags
& TDF_TREE
)
285 else if (dfi
->pflags
& TDF_IPA
)
290 if (snprintf (dump_id
, sizeof (dump_id
), ".%03d%c", dfi
->num
, suffix
) < 0)
294 return concat (dump_base_name
, dump_id
, dfi
->suffix
, NULL
);
297 /* For a given DFI, open an alternate dump filename (which could also
298 be a standard stream such as stdout/stderr). If the alternate dump
299 file cannot be opened, return NULL. */
302 dump_open_alternate_stream (struct dump_file_info
*dfi
)
305 if (!dfi
->alt_filename
)
309 return dfi
->alt_stream
;
311 stream
= strcmp ("stderr", dfi
->alt_filename
) == 0
313 : strcmp ("stdout", dfi
->alt_filename
) == 0
315 : fopen (dfi
->alt_filename
, dfi
->alt_state
< 0 ? "w" : "a");
318 error ("could not open dump file %qs: %m", dfi
->alt_filename
);
325 /* Print source location on DFILE if enabled. */
328 dump_loc (int dump_kind
, FILE *dfile
, source_location loc
)
332 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
333 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
334 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
335 else if (current_function_decl
)
336 fprintf (dfile
, "%s:%d:%d: note: ",
337 DECL_SOURCE_FILE (current_function_decl
),
338 DECL_SOURCE_LINE (current_function_decl
),
339 DECL_SOURCE_COLUMN (current_function_decl
));
343 /* Dump gimple statement GS with SPC indentation spaces and
344 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
347 dump_gimple_stmt (int dump_kind
, int extra_dump_flags
, gimple gs
, int spc
)
349 if (dump_file
&& (dump_kind
& pflags
))
350 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
352 if (alt_dump_file
&& (dump_kind
& alt_flags
))
353 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
356 /* Similar to dump_gimple_stmt, except additionally print source location. */
359 dump_gimple_stmt_loc (int dump_kind
, source_location loc
, int extra_dump_flags
,
362 if (dump_file
&& (dump_kind
& pflags
))
364 dump_loc (dump_kind
, dump_file
, loc
);
365 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
368 if (alt_dump_file
&& (dump_kind
& alt_flags
))
370 dump_loc (dump_kind
, alt_dump_file
, loc
);
371 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
375 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
376 DUMP_KIND is enabled. */
379 dump_generic_expr (int dump_kind
, int extra_dump_flags
, tree t
)
381 if (dump_file
&& (dump_kind
& pflags
))
382 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
384 if (alt_dump_file
&& (dump_kind
& alt_flags
))
385 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
389 /* Similar to dump_generic_expr, except additionally print the source
393 dump_generic_expr_loc (int dump_kind
, source_location loc
,
394 int extra_dump_flags
, tree t
)
396 if (dump_file
&& (dump_kind
& pflags
))
398 dump_loc (dump_kind
, dump_file
, loc
);
399 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
402 if (alt_dump_file
&& (dump_kind
& alt_flags
))
404 dump_loc (dump_kind
, alt_dump_file
, loc
);
405 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
409 /* Output a formatted message using FORMAT on appropriate dump streams. */
412 dump_printf (int dump_kind
, const char *format
, ...)
414 if (dump_file
&& (dump_kind
& pflags
))
417 va_start (ap
, format
);
418 vfprintf (dump_file
, format
, ap
);
422 if (alt_dump_file
&& (dump_kind
& alt_flags
))
425 va_start (ap
, format
);
426 vfprintf (alt_dump_file
, format
, ap
);
431 /* Similar to dump_printf, except source location is also printed. */
434 dump_printf_loc (int dump_kind
, source_location loc
, const char *format
, ...)
436 if (dump_file
&& (dump_kind
& pflags
))
439 dump_loc (dump_kind
, dump_file
, loc
);
440 va_start (ap
, format
);
441 vfprintf (dump_file
, format
, ap
);
445 if (alt_dump_file
&& (dump_kind
& alt_flags
))
448 dump_loc (dump_kind
, alt_dump_file
, loc
);
449 va_start (ap
, format
);
450 vfprintf (alt_dump_file
, format
, ap
);
455 /* Start a dump for PHASE. Store user-supplied dump flags in
456 *FLAG_PTR. Return the number of streams opened. Set globals
457 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
458 set dump_flags appropriately for both pass dump stream and
459 -fopt-info stream. */
463 dump_start (int phase
, int *flag_ptr
)
467 struct dump_file_info
*dfi
;
469 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
472 dfi
= get_dump_file_info (phase
);
473 name
= get_dump_file_name (phase
);
476 stream
= strcmp ("stderr", name
) == 0
478 : strcmp ("stdout", name
) == 0
480 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
482 error ("could not open dump file %qs: %m", name
);
489 dfi
->pstream
= stream
;
490 dump_file
= dfi
->pstream
;
491 /* Initialize current dump flags. */
492 pflags
= dfi
->pflags
;
495 stream
= dump_open_alternate_stream (dfi
);
498 dfi
->alt_stream
= stream
;
500 alt_dump_file
= dfi
->alt_stream
;
501 /* Initialize current -fopt-info flags. */
502 alt_flags
= dfi
->alt_flags
;
506 *flag_ptr
= dfi
->pflags
;
511 /* Finish a tree dump for PHASE and close associated dump streams. Also
512 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
516 dump_finish (int phase
)
518 struct dump_file_info
*dfi
;
522 dfi
= get_dump_file_info (phase
);
523 if (dfi
->pstream
&& (!dfi
->pfilename
524 || (strcmp ("stderr", dfi
->pfilename
) != 0
525 && strcmp ("stdout", dfi
->pfilename
) != 0)))
526 fclose (dfi
->pstream
);
528 if (dfi
->alt_stream
&& strcmp ("stderr", dfi
->alt_filename
) != 0
529 && strcmp ("stdout", dfi
->alt_filename
) != 0)
530 fclose (dfi
->alt_stream
);
532 dfi
->alt_stream
= NULL
;
535 alt_dump_file
= NULL
;
536 dump_flags
= TDI_none
;
541 /* Begin a tree dump for PHASE. Stores any user supplied flag in
542 *FLAG_PTR and returns a stream to write to. If the dump is not
543 enabled, returns NULL.
544 Multiple calls will reopen and append to the dump file. */
547 dump_begin (int phase
, int *flag_ptr
)
549 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
554 dump_begin (int phase
, int *flag_ptr
)
557 struct dump_file_info
*dfi
;
560 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
563 name
= get_dump_file_name (phase
);
566 dfi
= get_dump_file_info (phase
);
568 stream
= strcmp ("stderr", name
) == 0
570 : strcmp ("stdout", name
) == 0
572 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
575 error ("could not open dump file %qs: %m", name
);
581 *flag_ptr
= dfi
->pflags
;
583 /* Initialize current flags */
584 pflags
= dfi
->pflags
;
588 /* Returns nonzero if dump PHASE is enabled for at least one stream.
589 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
594 dump_phase_enabled_p (int phase
) const
596 if (phase
== TDI_tree_all
)
599 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
600 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
602 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
603 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
609 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
610 return dfi
->pstate
|| dfi
->alt_state
;
614 /* Returns nonzero if tree dump PHASE has been initialized. */
618 dump_initialized_p (int phase
) const
620 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
621 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
624 /* Returns the switch name of PHASE. */
627 dump_flag_name (int phase
)
629 return g
->get_dumps ()->dump_flag_name (phase
);
634 dump_flag_name (int phase
) const
636 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
640 /* Finish a tree dump for PHASE. STREAM is the stream created by
644 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
646 if (stream
!= stderr
&& stream
!= stdout
)
650 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
651 enabled tree dumps. */
655 dump_enable_all (int flags
, const char *filename
)
657 int ir_dump_type
= (flags
& (TDF_TREE
| TDF_RTL
| TDF_IPA
));
661 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
663 if ((dump_files
[i
].pflags
& ir_dump_type
))
665 const char *old_filename
= dump_files
[i
].pfilename
;
666 dump_files
[i
].pstate
= -1;
667 dump_files
[i
].pflags
|= flags
;
669 /* Override the existing filename. */
672 dump_files
[i
].pfilename
= xstrdup (filename
);
673 /* Since it is a command-line provided file, which is
674 common to all the phases, use it in append mode. */
675 dump_files
[i
].pstate
= 1;
677 if (old_filename
&& filename
!= old_filename
)
678 free (CONST_CAST (char *, old_filename
));
682 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
684 if ((m_extra_dump_files
[i
].pflags
& ir_dump_type
))
686 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
687 m_extra_dump_files
[i
].pstate
= -1;
688 m_extra_dump_files
[i
].pflags
|= flags
;
690 /* Override the existing filename. */
693 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
694 /* Since it is a command-line provided file, which is
695 common to all the phases, use it in append mode. */
696 m_extra_dump_files
[i
].pstate
= 1;
698 if (old_filename
&& filename
!= old_filename
)
699 free (CONST_CAST (char *, old_filename
));
706 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
707 Enable dumps with FLAGS on FILENAME. Return the number of enabled
712 opt_info_enable_passes (int optgroup_flags
, int flags
, const char *filename
)
717 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
719 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
721 const char *old_filename
= dump_files
[i
].alt_filename
;
722 /* Since this file is shared among different passes, it
723 should be opened in append mode. */
724 dump_files
[i
].alt_state
= 1;
725 dump_files
[i
].alt_flags
|= flags
;
727 /* Override the existing filename. */
729 dump_files
[i
].alt_filename
= xstrdup (filename
);
730 if (old_filename
&& filename
!= old_filename
)
731 free (CONST_CAST (char *, old_filename
));
735 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
737 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
739 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
740 /* Since this file is shared among different passes, it
741 should be opened in append mode. */
742 m_extra_dump_files
[i
].alt_state
= 1;
743 m_extra_dump_files
[i
].alt_flags
|= flags
;
745 /* Override the existing filename. */
747 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
748 if (old_filename
&& filename
!= old_filename
)
749 free (CONST_CAST (char *, old_filename
));
756 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
757 relevant details in the dump_files array. */
761 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
763 const char *option_value
;
767 if (doglob
&& !dfi
->glob
)
770 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
774 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
782 const struct dump_option_value_info
*option_ptr
;
789 end_ptr
= strchr (ptr
, '-');
790 eq_ptr
= strchr (ptr
, '=');
792 if (eq_ptr
&& !end_ptr
)
796 end_ptr
= ptr
+ strlen (ptr
);
797 length
= end_ptr
- ptr
;
799 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
800 if (strlen (option_ptr
->name
) == length
801 && !memcmp (option_ptr
->name
, ptr
, length
))
803 flags
|= option_ptr
->value
;
809 /* Interpret rest of the argument as a dump filename. This
810 filename overrides other command line filenames. */
812 free (CONST_CAST (char *, dfi
->pfilename
));
813 dfi
->pfilename
= xstrdup (ptr
+ 1);
817 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
818 length
, ptr
, dfi
->swtch
);
824 dfi
->pflags
|= flags
;
826 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
828 if (dfi
->suffix
== NULL
)
829 dump_enable_all (dfi
->pflags
, dfi
->pfilename
);
836 dump_switch_p (const char *arg
)
841 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
842 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
844 /* Don't glob if we got a hit already */
846 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
847 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
849 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
850 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
853 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
854 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
860 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
861 and filename. Return non-zero if it is a recognized switch. */
864 opt_info_switch_p_1 (const char *arg
, int *flags
, int *optgroup_flags
,
867 const char *option_value
;
878 return 1; /* Handle '-fopt-info' without any additional options. */
882 const struct dump_option_value_info
*option_ptr
;
889 end_ptr
= strchr (ptr
, '-');
890 eq_ptr
= strchr (ptr
, '=');
892 if (eq_ptr
&& !end_ptr
)
896 end_ptr
= ptr
+ strlen (ptr
);
897 length
= end_ptr
- ptr
;
899 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
901 if (strlen (option_ptr
->name
) == length
902 && !memcmp (option_ptr
->name
, ptr
, length
))
904 *flags
|= option_ptr
->value
;
908 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
909 if (strlen (option_ptr
->name
) == length
910 && !memcmp (option_ptr
->name
, ptr
, length
))
912 *optgroup_flags
|= option_ptr
->value
;
918 /* Interpret rest of the argument as a dump filename. This
919 filename overrides other command line filenames. */
920 *filename
= xstrdup (ptr
+ 1);
925 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
936 /* Return non-zero if ARG is a recognized switch for
937 -fopt-info. Return zero otherwise. */
940 opt_info_switch_p (const char *arg
)
945 static char *file_seen
= NULL
;
946 gcc::dump_manager
*dumps
= g
->get_dumps ();
948 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
952 filename
= xstrdup ("stderr");
954 /* Bail out if a different filename has been specified. */
955 if (file_seen
&& strcmp (file_seen
, filename
))
957 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
962 file_seen
= xstrdup (filename
);
964 flags
= MSG_OPTIMIZED_LOCATIONS
;
966 optgroup_flags
= OPTGROUP_ALL
;
968 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
971 /* Print basic block on the dump streams. */
974 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
976 if (dump_file
&& (dump_kind
& pflags
))
977 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
978 if (alt_dump_file
&& (dump_kind
& alt_flags
))
979 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
982 /* Print information from the combine pass on dump_file. */
985 print_combine_total_stats (void)
988 dump_combine_total_stats (dump_file
);
991 /* Enable RTL dump for all the RTL passes. */
994 enable_rtl_dump_file (void)
996 gcc::dump_manager
*dumps
= g
->get_dumps ();
998 dumps
->dump_enable_all (TDF_RTL
| TDF_DETAILS
| TDF_BLOCKS
, NULL
);
999 return num_enabled
> 0;