1 /* Dump infrastructure for optimizations and intermediate representation.
2 Copyright (C) 2012-2017 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"
25 #include "gimple-pretty-print.h"
26 #include "diagnostic-core.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 dump_flags_t pflags
; /* current dump_flags */
37 static dump_flags_t alt_flags
; /* current opt_info flags */
39 static void dump_loc (dump_flags_t
, 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
;
48 dump_flags_t dump_flags
;
50 CONSTEXPR
dump_file_info::dump_file_info (): suffix (NULL
), swtch (NULL
),
51 glob (NULL
), pfilename (NULL
), alt_filename (NULL
), pstream (NULL
),
52 alt_stream (NULL
), dkind (DK_none
), pflags (), alt_flags (0),
53 optgroup_flags (0), pstate (0), alt_state (0), num (0), owns_strings (false),
54 graph_dump_initialized (false)
58 dump_file_info::dump_file_info (const char *_suffix
, const char *_swtch
,
59 dump_kind _dkind
, int _num
):
60 suffix (_suffix
), swtch (_swtch
), glob (NULL
),
61 pfilename (NULL
), alt_filename (NULL
), pstream (NULL
), alt_stream (NULL
),
62 dkind (_dkind
), pflags (), alt_flags (0), optgroup_flags (0),
63 pstate (0), alt_state (0), num (_num
), owns_strings (false),
64 graph_dump_initialized (false)
68 /* Table of tree dump switches. This must be consistent with the
69 TREE_DUMP_INDEX enumeration in dumpfile.h. */
70 static struct dump_file_info dump_files
[TDI_end
] =
73 dump_file_info (".cgraph", "ipa-cgraph", DK_ipa
, 0),
74 dump_file_info (".type-inheritance", "ipa-type-inheritance", DK_ipa
, 0),
75 dump_file_info (".ipa-clones", "ipa-clones", DK_ipa
, 0),
76 dump_file_info (".original", "tree-original", DK_tree
, 3),
77 dump_file_info (".gimple", "tree-gimple", DK_tree
, 4),
78 dump_file_info (".nested", "tree-nested", DK_tree
, 5),
79 #define FIRST_AUTO_NUMBERED_DUMP 3
81 dump_file_info (NULL
, "lang-all", DK_lang
, 0),
82 dump_file_info (NULL
, "tree-all", DK_tree
, 0),
83 dump_file_info (NULL
, "rtl-all", DK_rtl
, 0),
84 dump_file_info (NULL
, "ipa-all", DK_ipa
, 0),
87 /* Define a name->number mapping for a dump flag value. */
88 struct dump_option_value_info
90 const char *const name
; /* the name of the value */
91 const dump_flags_t value
; /* the value of the name */
94 /* Table of dump options. This must be consistent with the TDF_* flags
95 in dumpfile.h and opt_info_options below. */
96 static const struct dump_option_value_info dump_options
[] =
98 {"address", TDF_ADDRESS
},
99 {"asmname", TDF_ASMNAME
},
102 {"graph", TDF_GRAPH
},
103 {"details", (TDF_DETAILS
| MSG_OPTIMIZED_LOCATIONS
104 | MSG_MISSED_OPTIMIZATION
106 {"cselib", TDF_CSELIB
},
107 {"stats", TDF_STATS
},
108 {"blocks", TDF_BLOCKS
},
110 {"lineno", TDF_LINENO
},
112 {"stmtaddr", TDF_STMTADDR
},
113 {"memsyms", TDF_MEMSYMS
},
115 {"alias", TDF_ALIAS
},
116 {"nouid", TDF_NOUID
},
117 {"enumerate_locals", TDF_ENUMERATE_LOCALS
},
119 {"gimple", TDF_GIMPLE
},
120 {"folding", TDF_FOLDING
},
121 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
122 {"missed", MSG_MISSED_OPTIMIZATION
},
125 {"all", ~(TDF_RAW
| TDF_SLIM
| TDF_LINENO
| TDF_GRAPH
| TDF_STMTADDR
126 | TDF_RHS_ONLY
| TDF_NOUID
| TDF_ENUMERATE_LOCALS
| TDF_SCEV
131 /* A subset of the dump_options table which is used for -fopt-info
132 types. This must be consistent with the MSG_* flags in dumpfile.h.
134 static const struct dump_option_value_info optinfo_verbosity_options
[] =
136 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
137 {"missed", MSG_MISSED_OPTIMIZATION
},
143 /* Flags used for -fopt-info groups. */
144 static const struct dump_option_value_info optgroup_options
[] =
146 {"ipa", OPTGROUP_IPA
},
147 {"loop", OPTGROUP_LOOP
},
148 {"inline", OPTGROUP_INLINE
},
149 {"omp", OPTGROUP_OMP
},
150 {"vec", OPTGROUP_VEC
},
151 {"optall", OPTGROUP_ALL
},
155 gcc::dump_manager::dump_manager ():
156 m_next_dump (FIRST_AUTO_NUMBERED_DUMP
),
157 m_extra_dump_files (NULL
),
158 m_extra_dump_files_in_use (0),
159 m_extra_dump_files_alloced (0)
163 gcc::dump_manager::~dump_manager ()
165 for (size_t i
= 0; i
< m_extra_dump_files_in_use
; i
++)
167 dump_file_info
*dfi
= &m_extra_dump_files
[i
];
168 /* suffix, swtch, glob are statically allocated for the entries
169 in dump_files, and for statistics, but are dynamically allocated
170 for those for passes. */
171 if (dfi
->owns_strings
)
173 XDELETEVEC (const_cast <char *> (dfi
->suffix
));
174 XDELETEVEC (const_cast <char *> (dfi
->swtch
));
175 XDELETEVEC (const_cast <char *> (dfi
->glob
));
177 /* These, if non-NULL, are always dynamically allocated. */
178 XDELETEVEC (const_cast <char *> (dfi
->pfilename
));
179 XDELETEVEC (const_cast <char *> (dfi
->alt_filename
));
181 XDELETEVEC (m_extra_dump_files
);
186 dump_register (const char *suffix
, const char *swtch
, const char *glob
,
187 dump_kind dkind
, int optgroup_flags
, bool take_ownership
)
189 int num
= m_next_dump
++;
191 size_t count
= m_extra_dump_files_in_use
++;
193 if (count
>= m_extra_dump_files_alloced
)
195 if (m_extra_dump_files_alloced
== 0)
196 m_extra_dump_files_alloced
= 32;
198 m_extra_dump_files_alloced
*= 2;
199 m_extra_dump_files
= XRESIZEVEC (struct dump_file_info
,
201 m_extra_dump_files_alloced
);
204 memset (&m_extra_dump_files
[count
], 0, sizeof (struct dump_file_info
));
205 m_extra_dump_files
[count
].suffix
= suffix
;
206 m_extra_dump_files
[count
].swtch
= swtch
;
207 m_extra_dump_files
[count
].glob
= glob
;
208 m_extra_dump_files
[count
].dkind
= dkind
;
209 m_extra_dump_files
[count
].optgroup_flags
= optgroup_flags
;
210 m_extra_dump_files
[count
].num
= num
;
211 m_extra_dump_files
[count
].owns_strings
= take_ownership
;
213 return count
+ TDI_end
;
217 /* Return the dump_file_info for the given phase. */
219 struct dump_file_info
*
221 get_dump_file_info (int phase
) const
224 return &dump_files
[phase
];
225 else if ((size_t) (phase
- TDI_end
) >= m_extra_dump_files_in_use
)
228 return m_extra_dump_files
+ (phase
- TDI_end
);
231 /* Locate the dump_file_info with swtch equal to SWTCH,
232 or return NULL if no such dump_file_info exists. */
234 struct dump_file_info
*
236 get_dump_file_info_by_switch (const char *swtch
) const
238 for (unsigned i
= 0; i
< m_extra_dump_files_in_use
; i
++)
239 if (0 == strcmp (m_extra_dump_files
[i
].swtch
, swtch
))
240 return &m_extra_dump_files
[i
];
247 /* Return the name of the dump file for the given phase.
248 The caller is responsible for calling free on the returned
250 If the dump is not enabled, returns NULL. */
254 get_dump_file_name (int phase
) const
256 struct dump_file_info
*dfi
;
258 if (phase
== TDI_none
)
261 dfi
= get_dump_file_info (phase
);
263 return get_dump_file_name (dfi
);
266 /* Return the name of the dump file for the given dump_file_info.
267 The caller is responsible for calling free on the returned
269 If the dump is not enabled, returns NULL. */
273 get_dump_file_name (struct dump_file_info
*dfi
) const
279 if (dfi
->pstate
== 0)
282 /* If available, use the command line dump filename. */
284 return xstrdup (dfi
->pfilename
);
290 /* (null), LANG, TREE, RTL, IPA. */
291 char suffix
= " ltri"[dfi
->dkind
];
293 if (snprintf (dump_id
, sizeof (dump_id
), ".%03d%c", dfi
->num
, suffix
) < 0)
297 return concat (dump_base_name
, dump_id
, dfi
->suffix
, NULL
);
300 /* For a given DFI, open an alternate dump filename (which could also
301 be a standard stream such as stdout/stderr). If the alternate dump
302 file cannot be opened, return NULL. */
305 dump_open_alternate_stream (struct dump_file_info
*dfi
)
308 if (!dfi
->alt_filename
)
312 return dfi
->alt_stream
;
314 stream
= strcmp ("stderr", dfi
->alt_filename
) == 0
316 : strcmp ("stdout", dfi
->alt_filename
) == 0
318 : fopen (dfi
->alt_filename
, dfi
->alt_state
< 0 ? "w" : "a");
321 error ("could not open dump file %qs: %m", dfi
->alt_filename
);
328 /* Print source location on DFILE if enabled. */
331 dump_loc (dump_flags_t dump_kind
, FILE *dfile
, source_location loc
)
335 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
336 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
337 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
338 else if (current_function_decl
)
339 fprintf (dfile
, "%s:%d:%d: note: ",
340 DECL_SOURCE_FILE (current_function_decl
),
341 DECL_SOURCE_LINE (current_function_decl
),
342 DECL_SOURCE_COLUMN (current_function_decl
));
346 /* Dump gimple statement GS with SPC indentation spaces and
347 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
350 dump_gimple_stmt (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
353 if (dump_file
&& (dump_kind
& pflags
))
354 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
356 if (alt_dump_file
&& (dump_kind
& alt_flags
))
357 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
360 /* Similar to dump_gimple_stmt, except additionally print source location. */
363 dump_gimple_stmt_loc (dump_flags_t dump_kind
, source_location loc
,
364 dump_flags_t extra_dump_flags
, gimple
*gs
, int spc
)
366 if (dump_file
&& (dump_kind
& pflags
))
368 dump_loc (dump_kind
, dump_file
, loc
);
369 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
372 if (alt_dump_file
&& (dump_kind
& alt_flags
))
374 dump_loc (dump_kind
, alt_dump_file
, loc
);
375 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
379 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
380 DUMP_KIND is enabled. */
383 dump_generic_expr (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
386 if (dump_file
&& (dump_kind
& pflags
))
387 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
389 if (alt_dump_file
&& (dump_kind
& alt_flags
))
390 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
394 /* Similar to dump_generic_expr, except additionally print the source
398 dump_generic_expr_loc (int dump_kind
, source_location loc
,
399 dump_flags_t extra_dump_flags
, tree t
)
401 if (dump_file
&& (dump_kind
& pflags
))
403 dump_loc (dump_kind
, dump_file
, loc
);
404 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
407 if (alt_dump_file
&& (dump_kind
& alt_flags
))
409 dump_loc (dump_kind
, alt_dump_file
, loc
);
410 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
414 /* Output a formatted message using FORMAT on appropriate dump streams. */
417 dump_printf (dump_flags_t dump_kind
, const char *format
, ...)
419 if (dump_file
&& (dump_kind
& pflags
))
422 va_start (ap
, format
);
423 vfprintf (dump_file
, format
, ap
);
427 if (alt_dump_file
&& (dump_kind
& alt_flags
))
430 va_start (ap
, format
);
431 vfprintf (alt_dump_file
, format
, ap
);
436 /* Similar to dump_printf, except source location is also printed. */
439 dump_printf_loc (dump_flags_t dump_kind
, source_location loc
,
440 const char *format
, ...)
442 if (dump_file
&& (dump_kind
& pflags
))
445 dump_loc (dump_kind
, dump_file
, loc
);
446 va_start (ap
, format
);
447 vfprintf (dump_file
, format
, ap
);
451 if (alt_dump_file
&& (dump_kind
& alt_flags
))
454 dump_loc (dump_kind
, alt_dump_file
, loc
);
455 va_start (ap
, format
);
456 vfprintf (alt_dump_file
, format
, ap
);
461 /* Start a dump for PHASE. Store user-supplied dump flags in
462 *FLAG_PTR. Return the number of streams opened. Set globals
463 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
464 set dump_flags appropriately for both pass dump stream and
465 -fopt-info stream. */
469 dump_start (int phase
, dump_flags_t
*flag_ptr
)
473 struct dump_file_info
*dfi
;
475 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
478 dfi
= get_dump_file_info (phase
);
479 name
= get_dump_file_name (phase
);
482 stream
= strcmp ("stderr", name
) == 0
484 : strcmp ("stdout", name
) == 0
486 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
488 error ("could not open dump file %qs: %m", name
);
495 dfi
->pstream
= stream
;
496 dump_file
= dfi
->pstream
;
497 /* Initialize current dump flags. */
498 pflags
= dfi
->pflags
;
501 stream
= dump_open_alternate_stream (dfi
);
504 dfi
->alt_stream
= stream
;
506 alt_dump_file
= dfi
->alt_stream
;
507 /* Initialize current -fopt-info flags. */
508 alt_flags
= dfi
->alt_flags
;
512 *flag_ptr
= dfi
->pflags
;
517 /* Finish a tree dump for PHASE and close associated dump streams. Also
518 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
522 dump_finish (int phase
)
524 struct dump_file_info
*dfi
;
528 dfi
= get_dump_file_info (phase
);
529 if (dfi
->pstream
&& (!dfi
->pfilename
530 || (strcmp ("stderr", dfi
->pfilename
) != 0
531 && strcmp ("stdout", dfi
->pfilename
) != 0)))
532 fclose (dfi
->pstream
);
534 if (dfi
->alt_stream
&& strcmp ("stderr", dfi
->alt_filename
) != 0
535 && strcmp ("stdout", dfi
->alt_filename
) != 0)
536 fclose (dfi
->alt_stream
);
538 dfi
->alt_stream
= NULL
;
541 alt_dump_file
= NULL
;
542 dump_flags
= TDI_none
;
547 /* Begin a tree dump for PHASE. Stores any user supplied flag in
548 *FLAG_PTR and returns a stream to write to. If the dump is not
549 enabled, returns NULL.
550 Multiple calls will reopen and append to the dump file. */
553 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
555 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
560 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
563 struct dump_file_info
*dfi
;
566 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
569 name
= get_dump_file_name (phase
);
572 dfi
= get_dump_file_info (phase
);
574 stream
= strcmp ("stderr", name
) == 0
576 : strcmp ("stdout", name
) == 0
578 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
581 error ("could not open dump file %qs: %m", name
);
587 *flag_ptr
= dfi
->pflags
;
589 /* Initialize current flags */
590 pflags
= dfi
->pflags
;
594 /* Returns nonzero if dump PHASE is enabled for at least one stream.
595 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
600 dump_phase_enabled_p (int phase
) const
602 if (phase
== TDI_tree_all
)
605 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
606 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
608 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
609 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
615 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
616 return dfi
->pstate
|| dfi
->alt_state
;
620 /* Returns nonzero if tree dump PHASE has been initialized. */
624 dump_initialized_p (int phase
) const
626 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
627 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
630 /* Returns the switch name of PHASE. */
633 dump_flag_name (int phase
)
635 return g
->get_dumps ()->dump_flag_name (phase
);
640 dump_flag_name (int phase
) const
642 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
646 /* Finish a tree dump for PHASE. STREAM is the stream created by
650 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
652 if (stream
!= stderr
&& stream
!= stdout
)
656 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
657 enabled tree dumps. */
661 dump_enable_all (dump_kind dkind
, dump_flags_t flags
, const char *filename
)
666 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
668 if ((dump_files
[i
].dkind
== dkind
))
670 const char *old_filename
= dump_files
[i
].pfilename
;
671 dump_files
[i
].pstate
= -1;
672 dump_files
[i
].pflags
|= flags
;
674 /* Override the existing filename. */
677 dump_files
[i
].pfilename
= xstrdup (filename
);
678 /* Since it is a command-line provided file, which is
679 common to all the phases, use it in append mode. */
680 dump_files
[i
].pstate
= 1;
682 if (old_filename
&& filename
!= old_filename
)
683 free (CONST_CAST (char *, old_filename
));
687 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
689 if ((m_extra_dump_files
[i
].dkind
== dkind
))
691 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
692 m_extra_dump_files
[i
].pstate
= -1;
693 m_extra_dump_files
[i
].pflags
|= flags
;
695 /* Override the existing filename. */
698 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
699 /* Since it is a command-line provided file, which is
700 common to all the phases, use it in append mode. */
701 m_extra_dump_files
[i
].pstate
= 1;
703 if (old_filename
&& filename
!= old_filename
)
704 free (CONST_CAST (char *, old_filename
));
711 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
712 Enable dumps with FLAGS on FILENAME. Return the number of enabled
717 opt_info_enable_passes (int optgroup_flags
, dump_flags_t flags
,
718 const char *filename
)
723 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
725 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
727 const char *old_filename
= dump_files
[i
].alt_filename
;
728 /* Since this file is shared among different passes, it
729 should be opened in append mode. */
730 dump_files
[i
].alt_state
= 1;
731 dump_files
[i
].alt_flags
|= flags
;
733 /* Override the existing filename. */
735 dump_files
[i
].alt_filename
= xstrdup (filename
);
736 if (old_filename
&& filename
!= old_filename
)
737 free (CONST_CAST (char *, old_filename
));
741 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
743 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
745 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
746 /* Since this file is shared among different passes, it
747 should be opened in append mode. */
748 m_extra_dump_files
[i
].alt_state
= 1;
749 m_extra_dump_files
[i
].alt_flags
|= flags
;
751 /* Override the existing filename. */
753 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
754 if (old_filename
&& filename
!= old_filename
)
755 free (CONST_CAST (char *, old_filename
));
762 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
763 relevant details in the dump_files array. */
767 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
769 const char *option_value
;
773 if (doglob
&& !dfi
->glob
)
776 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
780 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
788 const struct dump_option_value_info
*option_ptr
;
795 end_ptr
= strchr (ptr
, '-');
796 eq_ptr
= strchr (ptr
, '=');
798 if (eq_ptr
&& !end_ptr
)
802 end_ptr
= ptr
+ strlen (ptr
);
803 length
= end_ptr
- ptr
;
805 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
806 if (strlen (option_ptr
->name
) == length
807 && !memcmp (option_ptr
->name
, ptr
, length
))
809 flags
|= option_ptr
->value
;
815 /* Interpret rest of the argument as a dump filename. This
816 filename overrides other command line filenames. */
818 free (CONST_CAST (char *, dfi
->pfilename
));
819 dfi
->pfilename
= xstrdup (ptr
+ 1);
823 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
824 length
, ptr
, dfi
->swtch
);
830 dfi
->pflags
|= flags
;
832 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
834 if (dfi
->suffix
== NULL
)
835 dump_enable_all (dfi
->dkind
, dfi
->pflags
, dfi
->pfilename
);
842 dump_switch_p (const char *arg
)
847 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
848 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
850 /* Don't glob if we got a hit already */
852 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
853 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
855 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
856 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
859 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
860 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
866 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
867 and filename. Return non-zero if it is a recognized switch. */
870 opt_info_switch_p_1 (const char *arg
, dump_flags_t
*flags
, int *optgroup_flags
,
873 const char *option_value
;
884 return 1; /* Handle '-fopt-info' without any additional options. */
888 const struct dump_option_value_info
*option_ptr
;
895 end_ptr
= strchr (ptr
, '-');
896 eq_ptr
= strchr (ptr
, '=');
898 if (eq_ptr
&& !end_ptr
)
902 end_ptr
= ptr
+ strlen (ptr
);
903 length
= end_ptr
- ptr
;
905 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
907 if (strlen (option_ptr
->name
) == length
908 && !memcmp (option_ptr
->name
, ptr
, length
))
910 *flags
|= option_ptr
->value
;
914 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
915 if (strlen (option_ptr
->name
) == length
916 && !memcmp (option_ptr
->name
, ptr
, length
))
918 *optgroup_flags
|= option_ptr
->value
;
924 /* Interpret rest of the argument as a dump filename. This
925 filename overrides other command line filenames. */
926 *filename
= xstrdup (ptr
+ 1);
931 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
942 /* Return non-zero if ARG is a recognized switch for
943 -fopt-info. Return zero otherwise. */
946 opt_info_switch_p (const char *arg
)
951 static char *file_seen
= NULL
;
952 gcc::dump_manager
*dumps
= g
->get_dumps ();
954 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
958 filename
= xstrdup ("stderr");
960 /* Bail out if a different filename has been specified. */
961 if (file_seen
&& strcmp (file_seen
, filename
))
963 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
968 file_seen
= xstrdup (filename
);
970 flags
= MSG_OPTIMIZED_LOCATIONS
;
972 optgroup_flags
= OPTGROUP_ALL
;
974 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
977 /* Print basic block on the dump streams. */
980 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
982 if (dump_file
&& (dump_kind
& pflags
))
983 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
984 if (alt_dump_file
&& (dump_kind
& alt_flags
))
985 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
988 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
991 dump_function (int phase
, tree fn
)
996 stream
= dump_begin (phase
, &flags
);
999 dump_function_to_file (fn
, stream
, flags
);
1000 dump_end (phase
, stream
);
1004 /* Print information from the combine pass on dump_file. */
1007 print_combine_total_stats (void)
1010 dump_combine_total_stats (dump_file
);
1013 /* Enable RTL dump for all the RTL passes. */
1016 enable_rtl_dump_file (void)
1018 gcc::dump_manager
*dumps
= g
->get_dumps ();
1020 dumps
->dump_enable_all (DK_rtl
, dump_flags_t (TDF_DETAILS
) | TDF_BLOCKS
,
1022 return num_enabled
> 0;