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
);
221 /* Return the name of the dump file for the given phase.
222 If the dump is not enabled, returns NULL. */
226 get_dump_file_name (int phase
) const
229 struct dump_file_info
*dfi
;
231 if (phase
== TDI_none
)
234 dfi
= get_dump_file_info (phase
);
235 if (dfi
->pstate
== 0)
238 /* If available, use the command line dump filename. */
240 return xstrdup (dfi
->pfilename
);
247 if (dfi
->pflags
& TDF_TREE
)
249 else if (dfi
->pflags
& TDF_IPA
)
254 if (snprintf (dump_id
, sizeof (dump_id
), ".%03d%c", dfi
->num
, suffix
) < 0)
258 return concat (dump_base_name
, dump_id
, dfi
->suffix
, NULL
);
261 /* For a given DFI, open an alternate dump filename (which could also
262 be a standard stream such as stdout/stderr). If the alternate dump
263 file cannot be opened, return NULL. */
266 dump_open_alternate_stream (struct dump_file_info
*dfi
)
269 if (!dfi
->alt_filename
)
273 return dfi
->alt_stream
;
275 stream
= strcmp ("stderr", dfi
->alt_filename
) == 0
277 : strcmp ("stdout", dfi
->alt_filename
) == 0
279 : fopen (dfi
->alt_filename
, dfi
->alt_state
< 0 ? "w" : "a");
282 error ("could not open dump file %qs: %m", dfi
->alt_filename
);
289 /* Print source location on DFILE if enabled. */
292 dump_loc (int dump_kind
, FILE *dfile
, source_location loc
)
296 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
297 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
298 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
299 else if (current_function_decl
)
300 fprintf (dfile
, "%s:%d:%d: note: ",
301 DECL_SOURCE_FILE (current_function_decl
),
302 DECL_SOURCE_LINE (current_function_decl
),
303 DECL_SOURCE_COLUMN (current_function_decl
));
307 /* Dump gimple statement GS with SPC indentation spaces and
308 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
311 dump_gimple_stmt (int dump_kind
, int extra_dump_flags
, gimple gs
, int spc
)
313 if (dump_file
&& (dump_kind
& pflags
))
314 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
316 if (alt_dump_file
&& (dump_kind
& alt_flags
))
317 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
320 /* Similar to dump_gimple_stmt, except additionally print source location. */
323 dump_gimple_stmt_loc (int dump_kind
, source_location loc
, int extra_dump_flags
,
326 if (dump_file
&& (dump_kind
& pflags
))
328 dump_loc (dump_kind
, dump_file
, loc
);
329 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
332 if (alt_dump_file
&& (dump_kind
& alt_flags
))
334 dump_loc (dump_kind
, alt_dump_file
, loc
);
335 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
339 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
340 DUMP_KIND is enabled. */
343 dump_generic_expr (int dump_kind
, int extra_dump_flags
, tree t
)
345 if (dump_file
&& (dump_kind
& pflags
))
346 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
348 if (alt_dump_file
&& (dump_kind
& alt_flags
))
349 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
353 /* Similar to dump_generic_expr, except additionally print the source
357 dump_generic_expr_loc (int dump_kind
, source_location loc
,
358 int extra_dump_flags
, tree t
)
360 if (dump_file
&& (dump_kind
& pflags
))
362 dump_loc (dump_kind
, dump_file
, loc
);
363 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
366 if (alt_dump_file
&& (dump_kind
& alt_flags
))
368 dump_loc (dump_kind
, alt_dump_file
, loc
);
369 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
373 /* Output a formatted message using FORMAT on appropriate dump streams. */
376 dump_printf (int dump_kind
, const char *format
, ...)
378 if (dump_file
&& (dump_kind
& pflags
))
381 va_start (ap
, format
);
382 vfprintf (dump_file
, format
, ap
);
386 if (alt_dump_file
&& (dump_kind
& alt_flags
))
389 va_start (ap
, format
);
390 vfprintf (alt_dump_file
, format
, ap
);
395 /* Similar to dump_printf, except source location is also printed. */
398 dump_printf_loc (int dump_kind
, source_location loc
, const char *format
, ...)
400 if (dump_file
&& (dump_kind
& pflags
))
403 dump_loc (dump_kind
, dump_file
, loc
);
404 va_start (ap
, format
);
405 vfprintf (dump_file
, format
, ap
);
409 if (alt_dump_file
&& (dump_kind
& alt_flags
))
412 dump_loc (dump_kind
, alt_dump_file
, loc
);
413 va_start (ap
, format
);
414 vfprintf (alt_dump_file
, format
, ap
);
419 /* Start a dump for PHASE. Store user-supplied dump flags in
420 *FLAG_PTR. Return the number of streams opened. Set globals
421 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
422 set dump_flags appropriately for both pass dump stream and
423 -fopt-info stream. */
427 dump_start (int phase
, int *flag_ptr
)
431 struct dump_file_info
*dfi
;
433 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
436 dfi
= get_dump_file_info (phase
);
437 name
= get_dump_file_name (phase
);
440 stream
= strcmp ("stderr", name
) == 0
442 : strcmp ("stdout", name
) == 0
444 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
446 error ("could not open dump file %qs: %m", name
);
453 dfi
->pstream
= stream
;
454 dump_file
= dfi
->pstream
;
455 /* Initialize current dump flags. */
456 pflags
= dfi
->pflags
;
459 stream
= dump_open_alternate_stream (dfi
);
462 dfi
->alt_stream
= stream
;
464 alt_dump_file
= dfi
->alt_stream
;
465 /* Initialize current -fopt-info flags. */
466 alt_flags
= dfi
->alt_flags
;
470 *flag_ptr
= dfi
->pflags
;
475 /* Finish a tree dump for PHASE and close associated dump streams. Also
476 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
480 dump_finish (int phase
)
482 struct dump_file_info
*dfi
;
486 dfi
= get_dump_file_info (phase
);
487 if (dfi
->pstream
&& (!dfi
->pfilename
488 || (strcmp ("stderr", dfi
->pfilename
) != 0
489 && strcmp ("stdout", dfi
->pfilename
) != 0)))
490 fclose (dfi
->pstream
);
492 if (dfi
->alt_stream
&& strcmp ("stderr", dfi
->alt_filename
) != 0
493 && strcmp ("stdout", dfi
->alt_filename
) != 0)
494 fclose (dfi
->alt_stream
);
496 dfi
->alt_stream
= NULL
;
499 alt_dump_file
= NULL
;
500 dump_flags
= TDI_none
;
505 /* Begin a tree dump for PHASE. Stores any user supplied flag in
506 *FLAG_PTR and returns a stream to write to. If the dump is not
507 enabled, returns NULL.
508 Multiple calls will reopen and append to the dump file. */
511 dump_begin (int phase
, int *flag_ptr
)
513 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
518 dump_begin (int phase
, int *flag_ptr
)
521 struct dump_file_info
*dfi
;
524 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
527 name
= get_dump_file_name (phase
);
530 dfi
= get_dump_file_info (phase
);
532 stream
= strcmp ("stderr", name
) == 0
534 : strcmp ("stdout", name
) == 0
536 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
539 error ("could not open dump file %qs: %m", name
);
545 *flag_ptr
= dfi
->pflags
;
547 /* Initialize current flags */
548 pflags
= dfi
->pflags
;
552 /* Returns nonzero if dump PHASE is enabled for at least one stream.
553 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
558 dump_phase_enabled_p (int phase
) const
560 if (phase
== TDI_tree_all
)
563 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
564 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
566 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
567 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
573 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
574 return dfi
->pstate
|| dfi
->alt_state
;
578 /* Returns nonzero if tree dump PHASE has been initialized. */
582 dump_initialized_p (int phase
) const
584 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
585 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
588 /* Returns the switch name of PHASE. */
591 dump_flag_name (int phase
)
593 return g
->get_dumps ()->dump_flag_name (phase
);
598 dump_flag_name (int phase
) const
600 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
604 /* Finish a tree dump for PHASE. STREAM is the stream created by
608 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
610 if (stream
!= stderr
&& stream
!= stdout
)
614 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
615 enabled tree dumps. */
619 dump_enable_all (int flags
, const char *filename
)
621 int ir_dump_type
= (flags
& (TDF_TREE
| TDF_RTL
| TDF_IPA
));
625 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
627 if ((dump_files
[i
].pflags
& ir_dump_type
))
629 const char *old_filename
= dump_files
[i
].pfilename
;
630 dump_files
[i
].pstate
= -1;
631 dump_files
[i
].pflags
|= flags
;
633 /* Override the existing filename. */
636 dump_files
[i
].pfilename
= xstrdup (filename
);
637 /* Since it is a command-line provided file, which is
638 common to all the phases, use it in append mode. */
639 dump_files
[i
].pstate
= 1;
641 if (old_filename
&& filename
!= old_filename
)
642 free (CONST_CAST (char *, old_filename
));
646 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
648 if ((m_extra_dump_files
[i
].pflags
& ir_dump_type
))
650 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
651 m_extra_dump_files
[i
].pstate
= -1;
652 m_extra_dump_files
[i
].pflags
|= flags
;
654 /* Override the existing filename. */
657 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
658 /* Since it is a command-line provided file, which is
659 common to all the phases, use it in append mode. */
660 m_extra_dump_files
[i
].pstate
= 1;
662 if (old_filename
&& filename
!= old_filename
)
663 free (CONST_CAST (char *, old_filename
));
670 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
671 Enable dumps with FLAGS on FILENAME. Return the number of enabled
676 opt_info_enable_passes (int optgroup_flags
, int flags
, const char *filename
)
681 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
683 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
685 const char *old_filename
= dump_files
[i
].alt_filename
;
686 /* Since this file is shared among different passes, it
687 should be opened in append mode. */
688 dump_files
[i
].alt_state
= 1;
689 dump_files
[i
].alt_flags
|= flags
;
691 /* Override the existing filename. */
693 dump_files
[i
].alt_filename
= xstrdup (filename
);
694 if (old_filename
&& filename
!= old_filename
)
695 free (CONST_CAST (char *, old_filename
));
699 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
701 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
703 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
704 /* Since this file is shared among different passes, it
705 should be opened in append mode. */
706 m_extra_dump_files
[i
].alt_state
= 1;
707 m_extra_dump_files
[i
].alt_flags
|= flags
;
709 /* Override the existing filename. */
711 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
712 if (old_filename
&& filename
!= old_filename
)
713 free (CONST_CAST (char *, old_filename
));
720 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
721 relevant details in the dump_files array. */
725 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
727 const char *option_value
;
731 if (doglob
&& !dfi
->glob
)
734 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
738 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
746 const struct dump_option_value_info
*option_ptr
;
753 end_ptr
= strchr (ptr
, '-');
754 eq_ptr
= strchr (ptr
, '=');
756 if (eq_ptr
&& !end_ptr
)
760 end_ptr
= ptr
+ strlen (ptr
);
761 length
= end_ptr
- ptr
;
763 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
764 if (strlen (option_ptr
->name
) == length
765 && !memcmp (option_ptr
->name
, ptr
, length
))
767 flags
|= option_ptr
->value
;
773 /* Interpret rest of the argument as a dump filename. This
774 filename overrides other command line filenames. */
776 free (CONST_CAST (char *, dfi
->pfilename
));
777 dfi
->pfilename
= xstrdup (ptr
+ 1);
781 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
782 length
, ptr
, dfi
->swtch
);
788 dfi
->pflags
|= flags
;
790 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
792 if (dfi
->suffix
== NULL
)
793 dump_enable_all (dfi
->pflags
, dfi
->pfilename
);
800 dump_switch_p (const char *arg
)
805 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
806 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
808 /* Don't glob if we got a hit already */
810 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
811 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
813 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
814 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
817 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
818 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
824 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
825 and filename. Return non-zero if it is a recognized switch. */
828 opt_info_switch_p_1 (const char *arg
, int *flags
, int *optgroup_flags
,
831 const char *option_value
;
842 return 1; /* Handle '-fopt-info' without any additional options. */
846 const struct dump_option_value_info
*option_ptr
;
853 end_ptr
= strchr (ptr
, '-');
854 eq_ptr
= strchr (ptr
, '=');
856 if (eq_ptr
&& !end_ptr
)
860 end_ptr
= ptr
+ strlen (ptr
);
861 length
= end_ptr
- ptr
;
863 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
865 if (strlen (option_ptr
->name
) == length
866 && !memcmp (option_ptr
->name
, ptr
, length
))
868 *flags
|= option_ptr
->value
;
872 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
873 if (strlen (option_ptr
->name
) == length
874 && !memcmp (option_ptr
->name
, ptr
, length
))
876 *optgroup_flags
|= option_ptr
->value
;
882 /* Interpret rest of the argument as a dump filename. This
883 filename overrides other command line filenames. */
884 *filename
= xstrdup (ptr
+ 1);
889 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
900 /* Return non-zero if ARG is a recognized switch for
901 -fopt-info. Return zero otherwise. */
904 opt_info_switch_p (const char *arg
)
909 static char *file_seen
= NULL
;
910 gcc::dump_manager
*dumps
= g
->get_dumps ();
912 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
916 filename
= xstrdup ("stderr");
918 /* Bail out if a different filename has been specified. */
919 if (file_seen
&& strcmp (file_seen
, filename
))
921 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
926 file_seen
= xstrdup (filename
);
928 flags
= MSG_OPTIMIZED_LOCATIONS
;
930 optgroup_flags
= OPTGROUP_ALL
;
932 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
935 /* Print basic block on the dump streams. */
938 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
940 if (dump_file
&& (dump_kind
& pflags
))
941 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
942 if (alt_dump_file
&& (dump_kind
& alt_flags
))
943 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
946 /* Print information from the combine pass on dump_file. */
949 print_combine_total_stats (void)
952 dump_combine_total_stats (dump_file
);
955 /* Enable RTL dump for all the RTL passes. */
958 enable_rtl_dump_file (void)
960 gcc::dump_manager
*dumps
= g
->get_dumps ();
962 dumps
->dump_enable_all (TDF_RTL
| TDF_DETAILS
| TDF_BLOCKS
, NULL
);
963 return num_enabled
> 0;