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
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"
26 #include "gimple-pretty-print.h"
29 /* If non-NULL, return one past-the-end of the matching SUBPART of
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
;
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, false},
53 {".cgraph", "ipa-cgraph", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
54 0, 0, 0, 0, 0, false},
55 {".type-inheritance", "ipa-type-inheritance", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
56 0, 0, 0, 0, 0, false},
57 {".tu", "translation-unit", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
58 0, 0, 0, 0, 1, false},
59 {".class", "class-hierarchy", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
60 0, 0, 0, 0, 2, false},
61 {".original", "tree-original", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
62 0, 0, 0, 0, 3, false},
63 {".gimple", "tree-gimple", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
64 0, 0, 0, 0, 4, false},
65 {".nested", "tree-nested", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
66 0, 0, 0, 0, 5, false},
67 #define FIRST_AUTO_NUMBERED_DUMP 6
69 {NULL
, "tree-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_TREE
,
70 0, 0, 0, 0, 0, false},
71 {NULL
, "rtl-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_RTL
,
72 0, 0, 0, 0, 0, false},
73 {NULL
, "ipa-all", NULL
, NULL
, NULL
, NULL
, NULL
, TDF_IPA
,
74 0, 0, 0, 0, 0, false},
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
},
93 {"details", (TDF_DETAILS
| MSG_OPTIMIZED_LOCATIONS
94 | MSG_MISSED_OPTIMIZATION
96 {"cselib", TDF_CSELIB
},
98 {"blocks", TDF_BLOCKS
},
100 {"lineno", TDF_LINENO
},
102 {"stmtaddr", TDF_STMTADDR
},
103 {"memsyms", TDF_MEMSYMS
},
104 {"verbose", TDF_VERBOSE
},
106 {"alias", TDF_ALIAS
},
107 {"nouid", TDF_NOUID
},
108 {"enumerate_locals", TDF_ENUMERATE_LOCALS
},
110 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
111 {"missed", MSG_MISSED_OPTIMIZATION
},
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
)},
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
},
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
},
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 gcc::dump_manager::~dump_manager ()
153 for (size_t i
= 0; i
< m_extra_dump_files_in_use
; i
++)
155 dump_file_info
*dfi
= &m_extra_dump_files
[i
];
156 /* suffix, swtch, glob are statically allocated for the entries
157 in dump_files, and for statistics, but are dynamically allocated
158 for those for passes. */
159 if (dfi
->owns_strings
)
161 XDELETEVEC (const_cast <char *> (dfi
->suffix
));
162 XDELETEVEC (const_cast <char *> (dfi
->swtch
));
163 XDELETEVEC (const_cast <char *> (dfi
->glob
));
165 /* These, if non-NULL, are always dynamically allocated. */
166 XDELETEVEC (const_cast <char *> (dfi
->pfilename
));
167 XDELETEVEC (const_cast <char *> (dfi
->alt_filename
));
169 XDELETEVEC (m_extra_dump_files
);
174 dump_register (const char *suffix
, const char *swtch
, const char *glob
,
175 int flags
, int optgroup_flags
,
178 int num
= m_next_dump
++;
180 size_t count
= m_extra_dump_files_in_use
++;
182 if (count
>= m_extra_dump_files_alloced
)
184 if (m_extra_dump_files_alloced
== 0)
185 m_extra_dump_files_alloced
= 32;
187 m_extra_dump_files_alloced
*= 2;
188 m_extra_dump_files
= XRESIZEVEC (struct dump_file_info
,
190 m_extra_dump_files_alloced
);
193 memset (&m_extra_dump_files
[count
], 0, sizeof (struct dump_file_info
));
194 m_extra_dump_files
[count
].suffix
= suffix
;
195 m_extra_dump_files
[count
].swtch
= swtch
;
196 m_extra_dump_files
[count
].glob
= glob
;
197 m_extra_dump_files
[count
].pflags
= flags
;
198 m_extra_dump_files
[count
].optgroup_flags
= optgroup_flags
;
199 m_extra_dump_files
[count
].num
= num
;
200 m_extra_dump_files
[count
].owns_strings
= take_ownership
;
202 return count
+ TDI_end
;
206 /* Return the dump_file_info for the given phase. */
208 struct dump_file_info
*
210 get_dump_file_info (int phase
) const
213 return &dump_files
[phase
];
214 else if ((size_t) (phase
- TDI_end
) >= m_extra_dump_files_in_use
)
217 return m_extra_dump_files
+ (phase
- TDI_end
);
220 /* Locate the dump_file_info with swtch equal to SWTCH,
221 or return NULL if no such dump_file_info exists. */
223 struct dump_file_info
*
225 get_dump_file_info_by_switch (const char *swtch
) const
227 for (unsigned i
= 0; i
< m_extra_dump_files_in_use
; i
++)
228 if (0 == strcmp (m_extra_dump_files
[i
].swtch
, swtch
))
229 return &m_extra_dump_files
[i
];
236 /* Return the name of the dump file for the given phase.
237 The caller is responsible for calling free on the returned
239 If the dump is not enabled, returns NULL. */
243 get_dump_file_name (int phase
) const
245 struct dump_file_info
*dfi
;
247 if (phase
== TDI_none
)
250 dfi
= get_dump_file_info (phase
);
252 return get_dump_file_name (dfi
);
255 /* Return the name of the dump file for the given dump_file_info.
256 The caller is responsible for calling free on the returned
258 If the dump is not enabled, returns NULL. */
262 get_dump_file_name (struct dump_file_info
*dfi
) const
268 if (dfi
->pstate
== 0)
271 /* If available, use the command line dump filename. */
273 return xstrdup (dfi
->pfilename
);
280 if (dfi
->pflags
& TDF_TREE
)
282 else if (dfi
->pflags
& TDF_IPA
)
287 if (snprintf (dump_id
, sizeof (dump_id
), ".%03d%c", dfi
->num
, suffix
) < 0)
291 return concat (dump_base_name
, dump_id
, dfi
->suffix
, NULL
);
294 /* For a given DFI, open an alternate dump filename (which could also
295 be a standard stream such as stdout/stderr). If the alternate dump
296 file cannot be opened, return NULL. */
299 dump_open_alternate_stream (struct dump_file_info
*dfi
)
302 if (!dfi
->alt_filename
)
306 return dfi
->alt_stream
;
308 stream
= strcmp ("stderr", dfi
->alt_filename
) == 0
310 : strcmp ("stdout", dfi
->alt_filename
) == 0
312 : fopen (dfi
->alt_filename
, dfi
->alt_state
< 0 ? "w" : "a");
315 error ("could not open dump file %qs: %m", dfi
->alt_filename
);
322 /* Print source location on DFILE if enabled. */
325 dump_loc (int dump_kind
, FILE *dfile
, source_location loc
)
329 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
330 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
331 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
332 else if (current_function_decl
)
333 fprintf (dfile
, "%s:%d:%d: note: ",
334 DECL_SOURCE_FILE (current_function_decl
),
335 DECL_SOURCE_LINE (current_function_decl
),
336 DECL_SOURCE_COLUMN (current_function_decl
));
340 /* Dump gimple statement GS with SPC indentation spaces and
341 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
344 dump_gimple_stmt (int dump_kind
, int extra_dump_flags
, gimple gs
, int spc
)
346 if (dump_file
&& (dump_kind
& pflags
))
347 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
349 if (alt_dump_file
&& (dump_kind
& alt_flags
))
350 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
353 /* Similar to dump_gimple_stmt, except additionally print source location. */
356 dump_gimple_stmt_loc (int dump_kind
, source_location loc
, int extra_dump_flags
,
359 if (dump_file
&& (dump_kind
& pflags
))
361 dump_loc (dump_kind
, dump_file
, loc
);
362 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
365 if (alt_dump_file
&& (dump_kind
& alt_flags
))
367 dump_loc (dump_kind
, alt_dump_file
, loc
);
368 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
372 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
373 DUMP_KIND is enabled. */
376 dump_generic_expr (int dump_kind
, int extra_dump_flags
, tree t
)
378 if (dump_file
&& (dump_kind
& pflags
))
379 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
381 if (alt_dump_file
&& (dump_kind
& alt_flags
))
382 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
386 /* Similar to dump_generic_expr, except additionally print the source
390 dump_generic_expr_loc (int dump_kind
, source_location loc
,
391 int extra_dump_flags
, tree t
)
393 if (dump_file
&& (dump_kind
& pflags
))
395 dump_loc (dump_kind
, dump_file
, loc
);
396 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
399 if (alt_dump_file
&& (dump_kind
& alt_flags
))
401 dump_loc (dump_kind
, alt_dump_file
, loc
);
402 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
406 /* Output a formatted message using FORMAT on appropriate dump streams. */
409 dump_printf (int dump_kind
, const char *format
, ...)
411 if (dump_file
&& (dump_kind
& pflags
))
414 va_start (ap
, format
);
415 vfprintf (dump_file
, format
, ap
);
419 if (alt_dump_file
&& (dump_kind
& alt_flags
))
422 va_start (ap
, format
);
423 vfprintf (alt_dump_file
, format
, ap
);
428 /* Similar to dump_printf, except source location is also printed. */
431 dump_printf_loc (int dump_kind
, source_location loc
, const char *format
, ...)
433 if (dump_file
&& (dump_kind
& pflags
))
436 dump_loc (dump_kind
, dump_file
, loc
);
437 va_start (ap
, format
);
438 vfprintf (dump_file
, format
, ap
);
442 if (alt_dump_file
&& (dump_kind
& alt_flags
))
445 dump_loc (dump_kind
, alt_dump_file
, loc
);
446 va_start (ap
, format
);
447 vfprintf (alt_dump_file
, format
, ap
);
452 /* Start a dump for PHASE. Store user-supplied dump flags in
453 *FLAG_PTR. Return the number of streams opened. Set globals
454 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
455 set dump_flags appropriately for both pass dump stream and
456 -fopt-info stream. */
460 dump_start (int phase
, int *flag_ptr
)
464 struct dump_file_info
*dfi
;
466 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
469 dfi
= get_dump_file_info (phase
);
470 name
= get_dump_file_name (phase
);
473 stream
= strcmp ("stderr", name
) == 0
475 : strcmp ("stdout", name
) == 0
477 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
479 error ("could not open dump file %qs: %m", name
);
486 dfi
->pstream
= stream
;
487 dump_file
= dfi
->pstream
;
488 /* Initialize current dump flags. */
489 pflags
= dfi
->pflags
;
492 stream
= dump_open_alternate_stream (dfi
);
495 dfi
->alt_stream
= stream
;
497 alt_dump_file
= dfi
->alt_stream
;
498 /* Initialize current -fopt-info flags. */
499 alt_flags
= dfi
->alt_flags
;
503 *flag_ptr
= dfi
->pflags
;
508 /* Finish a tree dump for PHASE and close associated dump streams. Also
509 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
513 dump_finish (int phase
)
515 struct dump_file_info
*dfi
;
519 dfi
= get_dump_file_info (phase
);
520 if (dfi
->pstream
&& (!dfi
->pfilename
521 || (strcmp ("stderr", dfi
->pfilename
) != 0
522 && strcmp ("stdout", dfi
->pfilename
) != 0)))
523 fclose (dfi
->pstream
);
525 if (dfi
->alt_stream
&& strcmp ("stderr", dfi
->alt_filename
) != 0
526 && strcmp ("stdout", dfi
->alt_filename
) != 0)
527 fclose (dfi
->alt_stream
);
529 dfi
->alt_stream
= NULL
;
532 alt_dump_file
= NULL
;
533 dump_flags
= TDI_none
;
538 /* Begin a tree dump for PHASE. Stores any user supplied flag in
539 *FLAG_PTR and returns a stream to write to. If the dump is not
540 enabled, returns NULL.
541 Multiple calls will reopen and append to the dump file. */
544 dump_begin (int phase
, int *flag_ptr
)
546 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
551 dump_begin (int phase
, int *flag_ptr
)
554 struct dump_file_info
*dfi
;
557 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
560 name
= get_dump_file_name (phase
);
563 dfi
= get_dump_file_info (phase
);
565 stream
= strcmp ("stderr", name
) == 0
567 : strcmp ("stdout", name
) == 0
569 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
572 error ("could not open dump file %qs: %m", name
);
578 *flag_ptr
= dfi
->pflags
;
580 /* Initialize current flags */
581 pflags
= dfi
->pflags
;
585 /* Returns nonzero if dump PHASE is enabled for at least one stream.
586 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
591 dump_phase_enabled_p (int phase
) const
593 if (phase
== TDI_tree_all
)
596 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
597 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
599 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
600 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
606 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
607 return dfi
->pstate
|| dfi
->alt_state
;
611 /* Returns nonzero if tree dump PHASE has been initialized. */
615 dump_initialized_p (int phase
) const
617 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
618 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
621 /* Returns the switch name of PHASE. */
624 dump_flag_name (int phase
)
626 return g
->get_dumps ()->dump_flag_name (phase
);
631 dump_flag_name (int phase
) const
633 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
637 /* Finish a tree dump for PHASE. STREAM is the stream created by
641 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
643 if (stream
!= stderr
&& stream
!= stdout
)
647 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
648 enabled tree dumps. */
652 dump_enable_all (int flags
, const char *filename
)
654 int ir_dump_type
= (flags
& (TDF_TREE
| TDF_RTL
| TDF_IPA
));
658 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
660 if ((dump_files
[i
].pflags
& ir_dump_type
))
662 const char *old_filename
= dump_files
[i
].pfilename
;
663 dump_files
[i
].pstate
= -1;
664 dump_files
[i
].pflags
|= flags
;
666 /* Override the existing filename. */
669 dump_files
[i
].pfilename
= xstrdup (filename
);
670 /* Since it is a command-line provided file, which is
671 common to all the phases, use it in append mode. */
672 dump_files
[i
].pstate
= 1;
674 if (old_filename
&& filename
!= old_filename
)
675 free (CONST_CAST (char *, old_filename
));
679 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
681 if ((m_extra_dump_files
[i
].pflags
& ir_dump_type
))
683 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
684 m_extra_dump_files
[i
].pstate
= -1;
685 m_extra_dump_files
[i
].pflags
|= flags
;
687 /* Override the existing filename. */
690 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
691 /* Since it is a command-line provided file, which is
692 common to all the phases, use it in append mode. */
693 m_extra_dump_files
[i
].pstate
= 1;
695 if (old_filename
&& filename
!= old_filename
)
696 free (CONST_CAST (char *, old_filename
));
703 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
704 Enable dumps with FLAGS on FILENAME. Return the number of enabled
709 opt_info_enable_passes (int optgroup_flags
, int flags
, const char *filename
)
714 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
716 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
718 const char *old_filename
= dump_files
[i
].alt_filename
;
719 /* Since this file is shared among different passes, it
720 should be opened in append mode. */
721 dump_files
[i
].alt_state
= 1;
722 dump_files
[i
].alt_flags
|= flags
;
724 /* Override the existing filename. */
726 dump_files
[i
].alt_filename
= xstrdup (filename
);
727 if (old_filename
&& filename
!= old_filename
)
728 free (CONST_CAST (char *, old_filename
));
732 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
734 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
736 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
737 /* Since this file is shared among different passes, it
738 should be opened in append mode. */
739 m_extra_dump_files
[i
].alt_state
= 1;
740 m_extra_dump_files
[i
].alt_flags
|= flags
;
742 /* Override the existing filename. */
744 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
745 if (old_filename
&& filename
!= old_filename
)
746 free (CONST_CAST (char *, old_filename
));
753 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
754 relevant details in the dump_files array. */
758 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
760 const char *option_value
;
764 if (doglob
&& !dfi
->glob
)
767 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
771 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
779 const struct dump_option_value_info
*option_ptr
;
786 end_ptr
= strchr (ptr
, '-');
787 eq_ptr
= strchr (ptr
, '=');
789 if (eq_ptr
&& !end_ptr
)
793 end_ptr
= ptr
+ strlen (ptr
);
794 length
= end_ptr
- ptr
;
796 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
797 if (strlen (option_ptr
->name
) == length
798 && !memcmp (option_ptr
->name
, ptr
, length
))
800 flags
|= option_ptr
->value
;
806 /* Interpret rest of the argument as a dump filename. This
807 filename overrides other command line filenames. */
809 free (CONST_CAST (char *, dfi
->pfilename
));
810 dfi
->pfilename
= xstrdup (ptr
+ 1);
814 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
815 length
, ptr
, dfi
->swtch
);
821 dfi
->pflags
|= flags
;
823 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
825 if (dfi
->suffix
== NULL
)
826 dump_enable_all (dfi
->pflags
, dfi
->pfilename
);
833 dump_switch_p (const char *arg
)
838 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
839 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
841 /* Don't glob if we got a hit already */
843 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
844 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
846 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
847 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
850 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
851 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
857 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
858 and filename. Return non-zero if it is a recognized switch. */
861 opt_info_switch_p_1 (const char *arg
, int *flags
, int *optgroup_flags
,
864 const char *option_value
;
875 return 1; /* Handle '-fopt-info' without any additional options. */
879 const struct dump_option_value_info
*option_ptr
;
886 end_ptr
= strchr (ptr
, '-');
887 eq_ptr
= strchr (ptr
, '=');
889 if (eq_ptr
&& !end_ptr
)
893 end_ptr
= ptr
+ strlen (ptr
);
894 length
= end_ptr
- ptr
;
896 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
898 if (strlen (option_ptr
->name
) == length
899 && !memcmp (option_ptr
->name
, ptr
, length
))
901 *flags
|= option_ptr
->value
;
905 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
906 if (strlen (option_ptr
->name
) == length
907 && !memcmp (option_ptr
->name
, ptr
, length
))
909 *optgroup_flags
|= option_ptr
->value
;
915 /* Interpret rest of the argument as a dump filename. This
916 filename overrides other command line filenames. */
917 *filename
= xstrdup (ptr
+ 1);
922 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
933 /* Return non-zero if ARG is a recognized switch for
934 -fopt-info. Return zero otherwise. */
937 opt_info_switch_p (const char *arg
)
942 static char *file_seen
= NULL
;
943 gcc::dump_manager
*dumps
= g
->get_dumps ();
945 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
949 filename
= xstrdup ("stderr");
951 /* Bail out if a different filename has been specified. */
952 if (file_seen
&& strcmp (file_seen
, filename
))
954 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
959 file_seen
= xstrdup (filename
);
961 flags
= MSG_OPTIMIZED_LOCATIONS
;
963 optgroup_flags
= OPTGROUP_ALL
;
965 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
968 /* Print basic block on the dump streams. */
971 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
973 if (dump_file
&& (dump_kind
& pflags
))
974 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
975 if (alt_dump_file
&& (dump_kind
& alt_flags
))
976 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
979 /* Print information from the combine pass on dump_file. */
982 print_combine_total_stats (void)
985 dump_combine_total_stats (dump_file
);
988 /* Enable RTL dump for all the RTL passes. */
991 enable_rtl_dump_file (void)
993 gcc::dump_manager
*dumps
= g
->get_dumps ();
995 dumps
->dump_enable_all (TDF_RTL
| TDF_DETAILS
| TDF_BLOCKS
, NULL
);
996 return num_enabled
> 0;