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 #define DUMP_FILE_INFO(suffix, swtch, dkind, num) \
51 {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, 0, 0, 0, 0, 0, num, \
54 /* Table of tree dump switches. This must be consistent with the
55 TREE_DUMP_INDEX enumeration in dumpfile.h. */
56 static struct dump_file_info dump_files
[TDI_end
] =
58 DUMP_FILE_INFO (NULL
, NULL
, DK_none
, 0),
59 DUMP_FILE_INFO (".cgraph", "ipa-cgraph", DK_ipa
, 0),
60 DUMP_FILE_INFO (".type-inheritance", "ipa-type-inheritance", DK_ipa
, 0),
61 DUMP_FILE_INFO (".ipa-clones", "ipa-clones", DK_ipa
, 0),
62 DUMP_FILE_INFO (".original", "tree-original", DK_tree
, 3),
63 DUMP_FILE_INFO (".gimple", "tree-gimple", DK_tree
, 4),
64 DUMP_FILE_INFO (".nested", "tree-nested", DK_tree
, 5),
65 #define FIRST_AUTO_NUMBERED_DUMP 3
67 DUMP_FILE_INFO (NULL
, "lang-all", DK_lang
, 0),
68 DUMP_FILE_INFO (NULL
, "tree-all", DK_tree
, 0),
69 DUMP_FILE_INFO (NULL
, "rtl-all", DK_rtl
, 0),
70 DUMP_FILE_INFO (NULL
, "ipa-all", DK_ipa
, 0),
73 /* Define a name->number mapping for a dump flag value. */
74 struct dump_option_value_info
76 const char *const name
; /* the name of the value */
77 const dump_flags_t value
; /* the value of the name */
80 /* Table of dump options. This must be consistent with the TDF_* flags
81 in dumpfile.h and opt_info_options below. */
82 static const struct dump_option_value_info dump_options
[] =
84 {"address", TDF_ADDRESS
},
85 {"asmname", TDF_ASMNAME
},
89 {"details", (TDF_DETAILS
| MSG_OPTIMIZED_LOCATIONS
90 | MSG_MISSED_OPTIMIZATION
92 {"cselib", TDF_CSELIB
},
94 {"blocks", TDF_BLOCKS
},
96 {"lineno", TDF_LINENO
},
98 {"stmtaddr", TDF_STMTADDR
},
99 {"memsyms", TDF_MEMSYMS
},
101 {"alias", TDF_ALIAS
},
102 {"nouid", TDF_NOUID
},
103 {"enumerate_locals", TDF_ENUMERATE_LOCALS
},
105 {"gimple", TDF_GIMPLE
},
106 {"folding", TDF_FOLDING
},
107 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
108 {"missed", MSG_MISSED_OPTIMIZATION
},
111 {"all", ~(TDF_RAW
| TDF_SLIM
| TDF_LINENO
| TDF_GRAPH
| TDF_STMTADDR
112 | TDF_RHS_ONLY
| TDF_NOUID
| TDF_ENUMERATE_LOCALS
| TDF_SCEV
117 /* A subset of the dump_options table which is used for -fopt-info
118 types. This must be consistent with the MSG_* flags in dumpfile.h.
120 static const struct dump_option_value_info optinfo_verbosity_options
[] =
122 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
123 {"missed", MSG_MISSED_OPTIMIZATION
},
129 /* Flags used for -fopt-info groups. */
130 static const struct dump_option_value_info optgroup_options
[] =
132 {"ipa", OPTGROUP_IPA
},
133 {"loop", OPTGROUP_LOOP
},
134 {"inline", OPTGROUP_INLINE
},
135 {"omp", OPTGROUP_OMP
},
136 {"vec", OPTGROUP_VEC
},
137 {"optall", OPTGROUP_ALL
},
141 gcc::dump_manager::dump_manager ():
142 m_next_dump (FIRST_AUTO_NUMBERED_DUMP
),
143 m_extra_dump_files (NULL
),
144 m_extra_dump_files_in_use (0),
145 m_extra_dump_files_alloced (0)
149 gcc::dump_manager::~dump_manager ()
151 for (size_t i
= 0; i
< m_extra_dump_files_in_use
; i
++)
153 dump_file_info
*dfi
= &m_extra_dump_files
[i
];
154 /* suffix, swtch, glob are statically allocated for the entries
155 in dump_files, and for statistics, but are dynamically allocated
156 for those for passes. */
157 if (dfi
->owns_strings
)
159 XDELETEVEC (const_cast <char *> (dfi
->suffix
));
160 XDELETEVEC (const_cast <char *> (dfi
->swtch
));
161 XDELETEVEC (const_cast <char *> (dfi
->glob
));
163 /* These, if non-NULL, are always dynamically allocated. */
164 XDELETEVEC (const_cast <char *> (dfi
->pfilename
));
165 XDELETEVEC (const_cast <char *> (dfi
->alt_filename
));
167 XDELETEVEC (m_extra_dump_files
);
172 dump_register (const char *suffix
, const char *swtch
, const char *glob
,
173 dump_kind dkind
, int optgroup_flags
, bool take_ownership
)
175 int num
= m_next_dump
++;
177 size_t count
= m_extra_dump_files_in_use
++;
179 if (count
>= m_extra_dump_files_alloced
)
181 if (m_extra_dump_files_alloced
== 0)
182 m_extra_dump_files_alloced
= 32;
184 m_extra_dump_files_alloced
*= 2;
185 m_extra_dump_files
= XRESIZEVEC (struct dump_file_info
,
187 m_extra_dump_files_alloced
);
190 memset (&m_extra_dump_files
[count
], 0, sizeof (struct dump_file_info
));
191 m_extra_dump_files
[count
].suffix
= suffix
;
192 m_extra_dump_files
[count
].swtch
= swtch
;
193 m_extra_dump_files
[count
].glob
= glob
;
194 m_extra_dump_files
[count
].dkind
= dkind
;
195 m_extra_dump_files
[count
].optgroup_flags
= optgroup_flags
;
196 m_extra_dump_files
[count
].num
= num
;
197 m_extra_dump_files
[count
].owns_strings
= take_ownership
;
199 return count
+ TDI_end
;
203 /* Return the dump_file_info for the given phase. */
205 struct dump_file_info
*
207 get_dump_file_info (int phase
) const
210 return &dump_files
[phase
];
211 else if ((size_t) (phase
- TDI_end
) >= m_extra_dump_files_in_use
)
214 return m_extra_dump_files
+ (phase
- TDI_end
);
217 /* Locate the dump_file_info with swtch equal to SWTCH,
218 or return NULL if no such dump_file_info exists. */
220 struct dump_file_info
*
222 get_dump_file_info_by_switch (const char *swtch
) const
224 for (unsigned i
= 0; i
< m_extra_dump_files_in_use
; i
++)
225 if (0 == strcmp (m_extra_dump_files
[i
].swtch
, swtch
))
226 return &m_extra_dump_files
[i
];
233 /* Return the name of the dump file for the given phase.
234 The caller is responsible for calling free on the returned
236 If the dump is not enabled, returns NULL. */
240 get_dump_file_name (int phase
) const
242 struct dump_file_info
*dfi
;
244 if (phase
== TDI_none
)
247 dfi
= get_dump_file_info (phase
);
249 return get_dump_file_name (dfi
);
252 /* Return the name of the dump file for the given dump_file_info.
253 The caller is responsible for calling free on the returned
255 If the dump is not enabled, returns NULL. */
259 get_dump_file_name (struct dump_file_info
*dfi
) const
265 if (dfi
->pstate
== 0)
268 /* If available, use the command line dump filename. */
270 return xstrdup (dfi
->pfilename
);
276 /* (null), LANG, TREE, RTL, IPA. */
277 char suffix
= " ltri"[dfi
->dkind
];
279 if (snprintf (dump_id
, sizeof (dump_id
), ".%03d%c", dfi
->num
, suffix
) < 0)
283 return concat (dump_base_name
, dump_id
, dfi
->suffix
, NULL
);
286 /* For a given DFI, open an alternate dump filename (which could also
287 be a standard stream such as stdout/stderr). If the alternate dump
288 file cannot be opened, return NULL. */
291 dump_open_alternate_stream (struct dump_file_info
*dfi
)
294 if (!dfi
->alt_filename
)
298 return dfi
->alt_stream
;
300 stream
= strcmp ("stderr", dfi
->alt_filename
) == 0
302 : strcmp ("stdout", dfi
->alt_filename
) == 0
304 : fopen (dfi
->alt_filename
, dfi
->alt_state
< 0 ? "w" : "a");
307 error ("could not open dump file %qs: %m", dfi
->alt_filename
);
314 /* Print source location on DFILE if enabled. */
317 dump_loc (dump_flags_t dump_kind
, FILE *dfile
, source_location loc
)
321 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
322 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
323 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
324 else if (current_function_decl
)
325 fprintf (dfile
, "%s:%d:%d: note: ",
326 DECL_SOURCE_FILE (current_function_decl
),
327 DECL_SOURCE_LINE (current_function_decl
),
328 DECL_SOURCE_COLUMN (current_function_decl
));
332 /* Dump gimple statement GS with SPC indentation spaces and
333 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
336 dump_gimple_stmt (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
339 if (dump_file
&& (dump_kind
& pflags
))
340 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
342 if (alt_dump_file
&& (dump_kind
& alt_flags
))
343 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
346 /* Similar to dump_gimple_stmt, except additionally print source location. */
349 dump_gimple_stmt_loc (dump_flags_t dump_kind
, source_location loc
,
350 dump_flags_t extra_dump_flags
, gimple
*gs
, int spc
)
352 if (dump_file
&& (dump_kind
& pflags
))
354 dump_loc (dump_kind
, dump_file
, loc
);
355 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
358 if (alt_dump_file
&& (dump_kind
& alt_flags
))
360 dump_loc (dump_kind
, alt_dump_file
, loc
);
361 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
365 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
366 DUMP_KIND is enabled. */
369 dump_generic_expr (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
372 if (dump_file
&& (dump_kind
& pflags
))
373 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
375 if (alt_dump_file
&& (dump_kind
& alt_flags
))
376 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
380 /* Similar to dump_generic_expr, except additionally print the source
384 dump_generic_expr_loc (int dump_kind
, source_location loc
,
385 dump_flags_t extra_dump_flags
, tree t
)
387 if (dump_file
&& (dump_kind
& pflags
))
389 dump_loc (dump_kind
, dump_file
, loc
);
390 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
393 if (alt_dump_file
&& (dump_kind
& alt_flags
))
395 dump_loc (dump_kind
, alt_dump_file
, loc
);
396 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
400 /* Output a formatted message using FORMAT on appropriate dump streams. */
403 dump_printf (dump_flags_t dump_kind
, const char *format
, ...)
405 if (dump_file
&& (dump_kind
& pflags
))
408 va_start (ap
, format
);
409 vfprintf (dump_file
, format
, ap
);
413 if (alt_dump_file
&& (dump_kind
& alt_flags
))
416 va_start (ap
, format
);
417 vfprintf (alt_dump_file
, format
, ap
);
422 /* Similar to dump_printf, except source location is also printed. */
425 dump_printf_loc (dump_flags_t dump_kind
, source_location loc
,
426 const char *format
, ...)
428 if (dump_file
&& (dump_kind
& pflags
))
431 dump_loc (dump_kind
, dump_file
, loc
);
432 va_start (ap
, format
);
433 vfprintf (dump_file
, format
, ap
);
437 if (alt_dump_file
&& (dump_kind
& alt_flags
))
440 dump_loc (dump_kind
, alt_dump_file
, loc
);
441 va_start (ap
, format
);
442 vfprintf (alt_dump_file
, format
, ap
);
447 /* Start a dump for PHASE. Store user-supplied dump flags in
448 *FLAG_PTR. Return the number of streams opened. Set globals
449 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
450 set dump_flags appropriately for both pass dump stream and
451 -fopt-info stream. */
455 dump_start (int phase
, dump_flags_t
*flag_ptr
)
459 struct dump_file_info
*dfi
;
461 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
464 dfi
= get_dump_file_info (phase
);
465 name
= get_dump_file_name (phase
);
468 stream
= strcmp ("stderr", name
) == 0
470 : strcmp ("stdout", name
) == 0
472 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
474 error ("could not open dump file %qs: %m", name
);
481 dfi
->pstream
= stream
;
482 dump_file
= dfi
->pstream
;
483 /* Initialize current dump flags. */
484 pflags
= dfi
->pflags
;
487 stream
= dump_open_alternate_stream (dfi
);
490 dfi
->alt_stream
= stream
;
492 alt_dump_file
= dfi
->alt_stream
;
493 /* Initialize current -fopt-info flags. */
494 alt_flags
= dfi
->alt_flags
;
498 *flag_ptr
= dfi
->pflags
;
503 /* Finish a tree dump for PHASE and close associated dump streams. Also
504 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
508 dump_finish (int phase
)
510 struct dump_file_info
*dfi
;
514 dfi
= get_dump_file_info (phase
);
515 if (dfi
->pstream
&& (!dfi
->pfilename
516 || (strcmp ("stderr", dfi
->pfilename
) != 0
517 && strcmp ("stdout", dfi
->pfilename
) != 0)))
518 fclose (dfi
->pstream
);
520 if (dfi
->alt_stream
&& strcmp ("stderr", dfi
->alt_filename
) != 0
521 && strcmp ("stdout", dfi
->alt_filename
) != 0)
522 fclose (dfi
->alt_stream
);
524 dfi
->alt_stream
= NULL
;
527 alt_dump_file
= NULL
;
528 dump_flags
= TDI_none
;
533 /* Begin a tree dump for PHASE. Stores any user supplied flag in
534 *FLAG_PTR and returns a stream to write to. If the dump is not
535 enabled, returns NULL.
536 Multiple calls will reopen and append to the dump file. */
539 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
541 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
546 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
549 struct dump_file_info
*dfi
;
552 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
555 name
= get_dump_file_name (phase
);
558 dfi
= get_dump_file_info (phase
);
560 stream
= strcmp ("stderr", name
) == 0
562 : strcmp ("stdout", name
) == 0
564 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
567 error ("could not open dump file %qs: %m", name
);
573 *flag_ptr
= dfi
->pflags
;
575 /* Initialize current flags */
576 pflags
= dfi
->pflags
;
580 /* Returns nonzero if dump PHASE is enabled for at least one stream.
581 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
586 dump_phase_enabled_p (int phase
) const
588 if (phase
== TDI_tree_all
)
591 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
592 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
594 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
595 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
601 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
602 return dfi
->pstate
|| dfi
->alt_state
;
606 /* Returns nonzero if tree dump PHASE has been initialized. */
610 dump_initialized_p (int phase
) const
612 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
613 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
616 /* Returns the switch name of PHASE. */
619 dump_flag_name (int phase
)
621 return g
->get_dumps ()->dump_flag_name (phase
);
626 dump_flag_name (int phase
) const
628 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
632 /* Finish a tree dump for PHASE. STREAM is the stream created by
636 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
638 if (stream
!= stderr
&& stream
!= stdout
)
642 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
643 enabled tree dumps. */
647 dump_enable_all (dump_kind dkind
, dump_flags_t flags
, const char *filename
)
652 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
654 if ((dump_files
[i
].dkind
== dkind
))
656 const char *old_filename
= dump_files
[i
].pfilename
;
657 dump_files
[i
].pstate
= -1;
658 dump_files
[i
].pflags
|= flags
;
660 /* Override the existing filename. */
663 dump_files
[i
].pfilename
= xstrdup (filename
);
664 /* Since it is a command-line provided file, which is
665 common to all the phases, use it in append mode. */
666 dump_files
[i
].pstate
= 1;
668 if (old_filename
&& filename
!= old_filename
)
669 free (CONST_CAST (char *, old_filename
));
673 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
675 if ((m_extra_dump_files
[i
].dkind
== dkind
))
677 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
678 m_extra_dump_files
[i
].pstate
= -1;
679 m_extra_dump_files
[i
].pflags
|= flags
;
681 /* Override the existing filename. */
684 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
685 /* Since it is a command-line provided file, which is
686 common to all the phases, use it in append mode. */
687 m_extra_dump_files
[i
].pstate
= 1;
689 if (old_filename
&& filename
!= old_filename
)
690 free (CONST_CAST (char *, old_filename
));
697 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
698 Enable dumps with FLAGS on FILENAME. Return the number of enabled
703 opt_info_enable_passes (int optgroup_flags
, dump_flags_t flags
,
704 const char *filename
)
709 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
711 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
713 const char *old_filename
= dump_files
[i
].alt_filename
;
714 /* Since this file is shared among different passes, it
715 should be opened in append mode. */
716 dump_files
[i
].alt_state
= 1;
717 dump_files
[i
].alt_flags
|= flags
;
719 /* Override the existing filename. */
721 dump_files
[i
].alt_filename
= xstrdup (filename
);
722 if (old_filename
&& filename
!= old_filename
)
723 free (CONST_CAST (char *, old_filename
));
727 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
729 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
731 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
732 /* Since this file is shared among different passes, it
733 should be opened in append mode. */
734 m_extra_dump_files
[i
].alt_state
= 1;
735 m_extra_dump_files
[i
].alt_flags
|= flags
;
737 /* Override the existing filename. */
739 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
740 if (old_filename
&& filename
!= old_filename
)
741 free (CONST_CAST (char *, old_filename
));
748 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
749 relevant details in the dump_files array. */
753 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
755 const char *option_value
;
759 if (doglob
&& !dfi
->glob
)
762 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
766 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
774 const struct dump_option_value_info
*option_ptr
;
781 end_ptr
= strchr (ptr
, '-');
782 eq_ptr
= strchr (ptr
, '=');
784 if (eq_ptr
&& !end_ptr
)
788 end_ptr
= ptr
+ strlen (ptr
);
789 length
= end_ptr
- ptr
;
791 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
792 if (strlen (option_ptr
->name
) == length
793 && !memcmp (option_ptr
->name
, ptr
, length
))
795 flags
|= option_ptr
->value
;
801 /* Interpret rest of the argument as a dump filename. This
802 filename overrides other command line filenames. */
804 free (CONST_CAST (char *, dfi
->pfilename
));
805 dfi
->pfilename
= xstrdup (ptr
+ 1);
809 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
810 length
, ptr
, dfi
->swtch
);
816 dfi
->pflags
|= flags
;
818 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
820 if (dfi
->suffix
== NULL
)
821 dump_enable_all (dfi
->dkind
, dfi
->pflags
, dfi
->pfilename
);
828 dump_switch_p (const char *arg
)
833 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
834 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
836 /* Don't glob if we got a hit already */
838 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
839 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
841 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
842 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
845 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
846 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
852 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
853 and filename. Return non-zero if it is a recognized switch. */
856 opt_info_switch_p_1 (const char *arg
, dump_flags_t
*flags
, int *optgroup_flags
,
859 const char *option_value
;
870 return 1; /* Handle '-fopt-info' without any additional options. */
874 const struct dump_option_value_info
*option_ptr
;
881 end_ptr
= strchr (ptr
, '-');
882 eq_ptr
= strchr (ptr
, '=');
884 if (eq_ptr
&& !end_ptr
)
888 end_ptr
= ptr
+ strlen (ptr
);
889 length
= end_ptr
- ptr
;
891 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
893 if (strlen (option_ptr
->name
) == length
894 && !memcmp (option_ptr
->name
, ptr
, length
))
896 *flags
|= option_ptr
->value
;
900 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
901 if (strlen (option_ptr
->name
) == length
902 && !memcmp (option_ptr
->name
, ptr
, length
))
904 *optgroup_flags
|= option_ptr
->value
;
910 /* Interpret rest of the argument as a dump filename. This
911 filename overrides other command line filenames. */
912 *filename
= xstrdup (ptr
+ 1);
917 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
928 /* Return non-zero if ARG is a recognized switch for
929 -fopt-info. Return zero otherwise. */
932 opt_info_switch_p (const char *arg
)
937 static char *file_seen
= NULL
;
938 gcc::dump_manager
*dumps
= g
->get_dumps ();
940 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
944 filename
= xstrdup ("stderr");
946 /* Bail out if a different filename has been specified. */
947 if (file_seen
&& strcmp (file_seen
, filename
))
949 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
954 file_seen
= xstrdup (filename
);
956 flags
= MSG_OPTIMIZED_LOCATIONS
;
958 optgroup_flags
= OPTGROUP_ALL
;
960 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
963 /* Print basic block on the dump streams. */
966 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
968 if (dump_file
&& (dump_kind
& pflags
))
969 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
970 if (alt_dump_file
&& (dump_kind
& alt_flags
))
971 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
974 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
977 dump_function (int phase
, tree fn
)
982 stream
= dump_begin (phase
, &flags
);
985 dump_function_to_file (fn
, stream
, flags
);
986 dump_end (phase
, stream
);
990 /* Print information from the combine pass on dump_file. */
993 print_combine_total_stats (void)
996 dump_combine_total_stats (dump_file
);
999 /* Enable RTL dump for all the RTL passes. */
1002 enable_rtl_dump_file (void)
1004 gcc::dump_manager
*dumps
= g
->get_dumps ();
1006 dumps
->dump_enable_all (DK_rtl
, dump_flags_t (TDF_DETAILS
) | TDF_BLOCKS
,
1008 return num_enabled
> 0;