1 /* Dump infrastructure for optimizations and intermediate representation.
2 Copyright (C) 2012-2018 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"
29 #include "profile-count.h"
31 #include "langhooks.h"
33 /* If non-NULL, return one past-the-end of the matching SUBPART of
35 #define skip_leading_substring(whole, part) \
36 (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
38 static dump_flags_t pflags
; /* current dump_flags */
39 static dump_flags_t alt_flags
; /* current opt_info flags */
41 static void dump_loc (dump_flags_t
, FILE *, source_location
);
42 static FILE *dump_open_alternate_stream (struct dump_file_info
*);
44 /* These are currently used for communicating between passes.
45 However, instead of accessing them directly, the passes can use
46 dump_printf () for dumps. */
47 FILE *dump_file
= NULL
;
48 FILE *alt_dump_file
= NULL
;
49 const char *dump_file_name
;
50 dump_flags_t dump_flags
;
52 #define DUMP_FILE_INFO(suffix, swtch, dkind, num) \
53 {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, 0, 0, 0, 0, 0, num, \
56 /* Table of tree dump switches. This must be consistent with the
57 TREE_DUMP_INDEX enumeration in dumpfile.h. */
58 static struct dump_file_info dump_files
[TDI_end
] =
60 DUMP_FILE_INFO (NULL
, NULL
, DK_none
, 0),
61 DUMP_FILE_INFO (".cgraph", "ipa-cgraph", DK_ipa
, 0),
62 DUMP_FILE_INFO (".type-inheritance", "ipa-type-inheritance", DK_ipa
, 0),
63 DUMP_FILE_INFO (".ipa-clones", "ipa-clones", DK_ipa
, 0),
64 DUMP_FILE_INFO (".original", "tree-original", DK_tree
, 0),
65 DUMP_FILE_INFO (".gimple", "tree-gimple", DK_tree
, 0),
66 DUMP_FILE_INFO (".nested", "tree-nested", DK_tree
, 0),
67 #define FIRST_AUTO_NUMBERED_DUMP 1
68 #define FIRST_ME_AUTO_NUMBERED_DUMP 3
70 DUMP_FILE_INFO (NULL
, "lang-all", DK_lang
, 0),
71 DUMP_FILE_INFO (NULL
, "tree-all", DK_tree
, 0),
72 DUMP_FILE_INFO (NULL
, "rtl-all", DK_rtl
, 0),
73 DUMP_FILE_INFO (NULL
, "ipa-all", DK_ipa
, 0),
76 /* Define a name->number mapping for a dump flag value. */
77 struct dump_option_value_info
79 const char *const name
; /* the name of the value */
80 const dump_flags_t value
; /* the value of the name */
83 /* Table of dump options. This must be consistent with the TDF_* flags
84 in dumpfile.h and opt_info_options below. */
85 static const struct dump_option_value_info dump_options
[] =
87 {"address", TDF_ADDRESS
},
88 {"asmname", TDF_ASMNAME
},
92 {"details", (TDF_DETAILS
| MSG_OPTIMIZED_LOCATIONS
93 | MSG_MISSED_OPTIMIZATION
95 {"cselib", TDF_CSELIB
},
97 {"blocks", TDF_BLOCKS
},
99 {"lineno", TDF_LINENO
},
101 {"stmtaddr", TDF_STMTADDR
},
102 {"memsyms", TDF_MEMSYMS
},
104 {"alias", TDF_ALIAS
},
105 {"nouid", TDF_NOUID
},
106 {"enumerate_locals", TDF_ENUMERATE_LOCALS
},
108 {"gimple", TDF_GIMPLE
},
109 {"folding", TDF_FOLDING
},
110 {"optimized", MSG_OPTIMIZED_LOCATIONS
},
111 {"missed", MSG_MISSED_OPTIMIZATION
},
114 {"all", dump_flags_t (~(TDF_RAW
| TDF_SLIM
| TDF_LINENO
| TDF_GRAPH
115 | TDF_STMTADDR
| TDF_RHS_ONLY
| TDF_NOUID
116 | TDF_ENUMERATE_LOCALS
| TDF_SCEV
| TDF_GIMPLE
))},
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 {"omp", OPTGROUP_OMP
},
139 {"vec", OPTGROUP_VEC
},
140 {"optall", OPTGROUP_ALL
},
144 gcc::dump_manager::dump_manager ():
145 m_next_dump (FIRST_AUTO_NUMBERED_DUMP
),
146 m_extra_dump_files (NULL
),
147 m_extra_dump_files_in_use (0),
148 m_extra_dump_files_alloced (0)
152 gcc::dump_manager::~dump_manager ()
154 for (size_t i
= 0; i
< m_extra_dump_files_in_use
; i
++)
156 dump_file_info
*dfi
= &m_extra_dump_files
[i
];
157 /* suffix, swtch, glob are statically allocated for the entries
158 in dump_files, and for statistics, but are dynamically allocated
159 for those for passes. */
160 if (dfi
->owns_strings
)
162 XDELETEVEC (const_cast <char *> (dfi
->suffix
));
163 XDELETEVEC (const_cast <char *> (dfi
->swtch
));
164 XDELETEVEC (const_cast <char *> (dfi
->glob
));
166 /* These, if non-NULL, are always dynamically allocated. */
167 XDELETEVEC (const_cast <char *> (dfi
->pfilename
));
168 XDELETEVEC (const_cast <char *> (dfi
->alt_filename
));
170 XDELETEVEC (m_extra_dump_files
);
175 dump_register (const char *suffix
, const char *swtch
, const char *glob
,
176 dump_kind dkind
, int optgroup_flags
, bool take_ownership
)
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
= 512;
187 m_extra_dump_files_alloced
*= 2;
188 m_extra_dump_files
= XRESIZEVEC (struct dump_file_info
,
190 m_extra_dump_files_alloced
);
192 /* Construct a new object in the space allocated above. */
193 new (m_extra_dump_files
+ count
) dump_file_info ();
197 /* Zero out the already constructed object. */
198 m_extra_dump_files
[count
] = dump_file_info ();
201 m_extra_dump_files
[count
].suffix
= suffix
;
202 m_extra_dump_files
[count
].swtch
= swtch
;
203 m_extra_dump_files
[count
].glob
= glob
;
204 m_extra_dump_files
[count
].dkind
= dkind
;
205 m_extra_dump_files
[count
].optgroup_flags
= optgroup_flags
;
206 m_extra_dump_files
[count
].num
= num
;
207 m_extra_dump_files
[count
].owns_strings
= take_ownership
;
209 return count
+ TDI_end
;
213 /* Allow languages and middle-end to register their dumps before the
214 optimization passes. */
220 lang_hooks
.register_dumps (this);
221 /* If this assert fails, some FE registered more than
222 FIRST_ME_AUTO_NUMBERED_DUMP - FIRST_AUTO_NUMBERED_DUMP
223 dump files. Bump FIRST_ME_AUTO_NUMBERED_DUMP accordingly. */
224 gcc_assert (m_next_dump
<= FIRST_ME_AUTO_NUMBERED_DUMP
);
225 m_next_dump
= FIRST_ME_AUTO_NUMBERED_DUMP
;
226 dump_files
[TDI_original
].num
= m_next_dump
++;
227 dump_files
[TDI_gimple
].num
= m_next_dump
++;
228 dump_files
[TDI_nested
].num
= m_next_dump
++;
232 /* Return the dump_file_info for the given phase. */
234 struct dump_file_info
*
236 get_dump_file_info (int phase
) const
239 return &dump_files
[phase
];
240 else if ((size_t) (phase
- TDI_end
) >= m_extra_dump_files_in_use
)
243 return m_extra_dump_files
+ (phase
- TDI_end
);
246 /* Locate the dump_file_info with swtch equal to SWTCH,
247 or return NULL if no such dump_file_info exists. */
249 struct dump_file_info
*
251 get_dump_file_info_by_switch (const char *swtch
) const
253 for (unsigned i
= 0; i
< m_extra_dump_files_in_use
; i
++)
254 if (strcmp (m_extra_dump_files
[i
].swtch
, swtch
) == 0)
255 return &m_extra_dump_files
[i
];
262 /* Return the name of the dump file for the given phase.
263 The caller is responsible for calling free on the returned
265 If the dump is not enabled, returns NULL. */
269 get_dump_file_name (int phase
) const
271 struct dump_file_info
*dfi
;
273 if (phase
== TDI_none
)
276 dfi
= get_dump_file_info (phase
);
278 return get_dump_file_name (dfi
);
281 /* Return the name of the dump file for the given dump_file_info.
282 The caller is responsible for calling free on the returned
284 If the dump is not enabled, returns NULL. */
288 get_dump_file_name (struct dump_file_info
*dfi
) const
294 if (dfi
->pstate
== 0)
297 /* If available, use the command line dump filename. */
299 return xstrdup (dfi
->pfilename
);
305 /* (null), LANG, TREE, RTL, IPA. */
306 char suffix
= " ltri"[dfi
->dkind
];
308 if (snprintf (dump_id
, sizeof (dump_id
), ".%03d%c", dfi
->num
, suffix
) < 0)
312 return concat (dump_base_name
, dump_id
, dfi
->suffix
, NULL
);
315 /* For a given DFI, open an alternate dump filename (which could also
316 be a standard stream such as stdout/stderr). If the alternate dump
317 file cannot be opened, return NULL. */
320 dump_open_alternate_stream (struct dump_file_info
*dfi
)
323 if (!dfi
->alt_filename
)
327 return dfi
->alt_stream
;
329 stream
= strcmp ("stderr", dfi
->alt_filename
) == 0
331 : strcmp ("stdout", dfi
->alt_filename
) == 0
333 : fopen (dfi
->alt_filename
, dfi
->alt_state
< 0 ? "w" : "a");
336 error ("could not open dump file %qs: %m", dfi
->alt_filename
);
343 /* Print source location on DFILE if enabled. */
346 dump_loc (dump_flags_t dump_kind
, FILE *dfile
, source_location loc
)
350 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
351 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
352 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
353 else if (current_function_decl
)
354 fprintf (dfile
, "%s:%d:%d: note: ",
355 DECL_SOURCE_FILE (current_function_decl
),
356 DECL_SOURCE_LINE (current_function_decl
),
357 DECL_SOURCE_COLUMN (current_function_decl
));
361 /* Dump gimple statement GS with SPC indentation spaces and
362 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
365 dump_gimple_stmt (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
368 if (dump_file
&& (dump_kind
& pflags
))
369 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
371 if (alt_dump_file
&& (dump_kind
& alt_flags
))
372 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
375 /* Similar to dump_gimple_stmt, except additionally print source location. */
378 dump_gimple_stmt_loc (dump_flags_t dump_kind
, source_location loc
,
379 dump_flags_t extra_dump_flags
, gimple
*gs
, int spc
)
381 if (dump_file
&& (dump_kind
& pflags
))
383 dump_loc (dump_kind
, dump_file
, loc
);
384 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
387 if (alt_dump_file
&& (dump_kind
& alt_flags
))
389 dump_loc (dump_kind
, alt_dump_file
, loc
);
390 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
394 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
395 DUMP_KIND is enabled. */
398 dump_generic_expr (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
401 if (dump_file
&& (dump_kind
& pflags
))
402 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
404 if (alt_dump_file
&& (dump_kind
& alt_flags
))
405 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
409 /* Similar to dump_generic_expr, except additionally print the source
413 dump_generic_expr_loc (int dump_kind
, source_location loc
,
414 dump_flags_t extra_dump_flags
, tree t
)
416 if (dump_file
&& (dump_kind
& pflags
))
418 dump_loc (dump_kind
, dump_file
, loc
);
419 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
422 if (alt_dump_file
&& (dump_kind
& alt_flags
))
424 dump_loc (dump_kind
, alt_dump_file
, loc
);
425 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
429 /* Output a formatted message using FORMAT on appropriate dump streams. */
432 dump_printf (dump_flags_t dump_kind
, const char *format
, ...)
434 if (dump_file
&& (dump_kind
& pflags
))
437 va_start (ap
, format
);
438 vfprintf (dump_file
, format
, ap
);
442 if (alt_dump_file
&& (dump_kind
& alt_flags
))
445 va_start (ap
, format
);
446 vfprintf (alt_dump_file
, format
, ap
);
451 /* Similar to dump_printf, except source location is also printed. */
454 dump_printf_loc (dump_flags_t dump_kind
, source_location loc
,
455 const char *format
, ...)
457 if (dump_file
&& (dump_kind
& pflags
))
460 dump_loc (dump_kind
, dump_file
, loc
);
461 va_start (ap
, format
);
462 vfprintf (dump_file
, format
, ap
);
466 if (alt_dump_file
&& (dump_kind
& alt_flags
))
469 dump_loc (dump_kind
, alt_dump_file
, loc
);
470 va_start (ap
, format
);
471 vfprintf (alt_dump_file
, format
, ap
);
476 /* Output VALUE in decimal to appropriate dump streams. */
478 template<unsigned int N
, typename C
>
480 dump_dec (int dump_kind
, const poly_int
<N
, C
> &value
)
482 STATIC_ASSERT (poly_coeff_traits
<C
>::signedness
>= 0);
483 signop sgn
= poly_coeff_traits
<C
>::signedness
? SIGNED
: UNSIGNED
;
484 if (dump_file
&& (dump_kind
& pflags
))
485 print_dec (value
, dump_file
, sgn
);
487 if (alt_dump_file
&& (dump_kind
& alt_flags
))
488 print_dec (value
, alt_dump_file
, sgn
);
491 template void dump_dec (int, const poly_uint16
&);
492 template void dump_dec (int, const poly_int64
&);
493 template void dump_dec (int, const poly_uint64
&);
494 template void dump_dec (int, const poly_offset_int
&);
495 template void dump_dec (int, const poly_widest_int
&);
497 /* Start a dump for PHASE. Store user-supplied dump flags in
498 *FLAG_PTR. Return the number of streams opened. Set globals
499 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
500 set dump_flags appropriately for both pass dump stream and
501 -fopt-info stream. */
505 dump_start (int phase
, dump_flags_t
*flag_ptr
)
509 struct dump_file_info
*dfi
;
511 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
514 dfi
= get_dump_file_info (phase
);
515 name
= get_dump_file_name (phase
);
518 stream
= strcmp ("stderr", name
) == 0
520 : strcmp ("stdout", name
) == 0
522 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
524 error ("could not open dump file %qs: %m", name
);
531 dfi
->pstream
= stream
;
532 dump_file
= dfi
->pstream
;
533 /* Initialize current dump flags. */
534 pflags
= dfi
->pflags
;
537 stream
= dump_open_alternate_stream (dfi
);
540 dfi
->alt_stream
= stream
;
542 alt_dump_file
= dfi
->alt_stream
;
543 /* Initialize current -fopt-info flags. */
544 alt_flags
= dfi
->alt_flags
;
548 *flag_ptr
= dfi
->pflags
;
553 /* Finish a tree dump for PHASE and close associated dump streams. Also
554 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
558 dump_finish (int phase
)
560 struct dump_file_info
*dfi
;
564 dfi
= get_dump_file_info (phase
);
565 if (dfi
->pstream
&& (!dfi
->pfilename
566 || (strcmp ("stderr", dfi
->pfilename
) != 0
567 && strcmp ("stdout", dfi
->pfilename
) != 0)))
568 fclose (dfi
->pstream
);
570 if (dfi
->alt_stream
&& strcmp ("stderr", dfi
->alt_filename
) != 0
571 && strcmp ("stdout", dfi
->alt_filename
) != 0)
572 fclose (dfi
->alt_stream
);
574 dfi
->alt_stream
= NULL
;
577 alt_dump_file
= NULL
;
578 dump_flags
= TDI_none
;
583 /* Begin a tree dump for PHASE. Stores any user supplied flag in
584 *FLAG_PTR and returns a stream to write to. If the dump is not
585 enabled, returns NULL.
586 Multiple calls will reopen and append to the dump file. */
589 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
591 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
596 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
599 struct dump_file_info
*dfi
;
602 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
605 name
= get_dump_file_name (phase
);
608 dfi
= get_dump_file_info (phase
);
610 stream
= strcmp ("stderr", name
) == 0
612 : strcmp ("stdout", name
) == 0
614 : fopen (name
, dfi
->pstate
< 0 ? "w" : "a");
617 error ("could not open dump file %qs: %m", name
);
623 *flag_ptr
= dfi
->pflags
;
625 /* Initialize current flags */
626 pflags
= dfi
->pflags
;
630 /* Returns nonzero if dump PHASE is enabled for at least one stream.
631 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
636 dump_phase_enabled_p (int phase
) const
638 if (phase
== TDI_tree_all
)
641 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
642 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
644 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
645 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
651 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
652 return dfi
->pstate
|| dfi
->alt_state
;
656 /* Returns nonzero if tree dump PHASE has been initialized. */
660 dump_initialized_p (int phase
) const
662 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
663 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
666 /* Returns the switch name of PHASE. */
669 dump_flag_name (int phase
)
671 return g
->get_dumps ()->dump_flag_name (phase
);
676 dump_flag_name (int phase
) const
678 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
682 /* Finish a tree dump for PHASE. STREAM is the stream created by
686 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
688 if (stream
!= stderr
&& stream
!= stdout
)
692 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
693 enabled tree dumps. */
697 dump_enable_all (dump_kind dkind
, dump_flags_t flags
, const char *filename
)
702 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
704 if ((dump_files
[i
].dkind
== dkind
))
706 const char *old_filename
= dump_files
[i
].pfilename
;
707 dump_files
[i
].pstate
= -1;
708 dump_files
[i
].pflags
|= flags
;
710 /* Override the existing filename. */
713 dump_files
[i
].pfilename
= xstrdup (filename
);
714 /* Since it is a command-line provided file, which is
715 common to all the phases, use it in append mode. */
716 dump_files
[i
].pstate
= 1;
718 if (old_filename
&& filename
!= old_filename
)
719 free (CONST_CAST (char *, old_filename
));
723 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
725 if ((m_extra_dump_files
[i
].dkind
== dkind
))
727 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
728 m_extra_dump_files
[i
].pstate
= -1;
729 m_extra_dump_files
[i
].pflags
|= flags
;
731 /* Override the existing filename. */
734 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
735 /* Since it is a command-line provided file, which is
736 common to all the phases, use it in append mode. */
737 m_extra_dump_files
[i
].pstate
= 1;
739 if (old_filename
&& filename
!= old_filename
)
740 free (CONST_CAST (char *, old_filename
));
747 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
748 Enable dumps with FLAGS on FILENAME. Return the number of enabled
753 opt_info_enable_passes (int optgroup_flags
, dump_flags_t flags
,
754 const char *filename
)
759 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
761 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
763 const char *old_filename
= dump_files
[i
].alt_filename
;
764 /* Since this file is shared among different passes, it
765 should be opened in append mode. */
766 dump_files
[i
].alt_state
= 1;
767 dump_files
[i
].alt_flags
|= flags
;
769 /* Override the existing filename. */
771 dump_files
[i
].alt_filename
= xstrdup (filename
);
772 if (old_filename
&& filename
!= old_filename
)
773 free (CONST_CAST (char *, old_filename
));
777 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
779 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
781 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
782 /* Since this file is shared among different passes, it
783 should be opened in append mode. */
784 m_extra_dump_files
[i
].alt_state
= 1;
785 m_extra_dump_files
[i
].alt_flags
|= flags
;
787 /* Override the existing filename. */
789 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
790 if (old_filename
&& filename
!= old_filename
)
791 free (CONST_CAST (char *, old_filename
));
798 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
799 relevant details in the dump_files array. */
803 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
805 const char *option_value
;
809 if (doglob
&& !dfi
->glob
)
812 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
816 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
824 const struct dump_option_value_info
*option_ptr
;
831 end_ptr
= strchr (ptr
, '-');
832 eq_ptr
= strchr (ptr
, '=');
834 if (eq_ptr
&& !end_ptr
)
838 end_ptr
= ptr
+ strlen (ptr
);
839 length
= end_ptr
- ptr
;
841 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
842 if (strlen (option_ptr
->name
) == length
843 && !memcmp (option_ptr
->name
, ptr
, length
))
845 flags
|= option_ptr
->value
;
851 /* Interpret rest of the argument as a dump filename. This
852 filename overrides other command line filenames. */
854 free (CONST_CAST (char *, dfi
->pfilename
));
855 dfi
->pfilename
= xstrdup (ptr
+ 1);
859 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
860 length
, ptr
, dfi
->swtch
);
866 dfi
->pflags
|= flags
;
868 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
870 if (dfi
->suffix
== NULL
)
871 dump_enable_all (dfi
->dkind
, dfi
->pflags
, dfi
->pfilename
);
878 dump_switch_p (const char *arg
)
883 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
884 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
886 /* Don't glob if we got a hit already */
888 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
889 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
891 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
892 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
895 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
896 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
902 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
903 and filename. Return non-zero if it is a recognized switch. */
906 opt_info_switch_p_1 (const char *arg
, dump_flags_t
*flags
, int *optgroup_flags
,
909 const char *option_value
;
920 return 1; /* Handle '-fopt-info' without any additional options. */
924 const struct dump_option_value_info
*option_ptr
;
931 end_ptr
= strchr (ptr
, '-');
932 eq_ptr
= strchr (ptr
, '=');
934 if (eq_ptr
&& !end_ptr
)
938 end_ptr
= ptr
+ strlen (ptr
);
939 length
= end_ptr
- ptr
;
941 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
943 if (strlen (option_ptr
->name
) == length
944 && !memcmp (option_ptr
->name
, ptr
, length
))
946 *flags
|= option_ptr
->value
;
950 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
951 if (strlen (option_ptr
->name
) == length
952 && !memcmp (option_ptr
->name
, ptr
, length
))
954 *optgroup_flags
|= option_ptr
->value
;
960 /* Interpret rest of the argument as a dump filename. This
961 filename overrides other command line filenames. */
962 *filename
= xstrdup (ptr
+ 1);
967 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
978 /* Return non-zero if ARG is a recognized switch for
979 -fopt-info. Return zero otherwise. */
982 opt_info_switch_p (const char *arg
)
987 static char *file_seen
= NULL
;
988 gcc::dump_manager
*dumps
= g
->get_dumps ();
990 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
994 filename
= xstrdup ("stderr");
996 /* Bail out if a different filename has been specified. */
997 if (file_seen
&& strcmp (file_seen
, filename
))
999 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
1004 file_seen
= xstrdup (filename
);
1006 flags
= MSG_OPTIMIZED_LOCATIONS
;
1007 if (!optgroup_flags
)
1008 optgroup_flags
= OPTGROUP_ALL
;
1010 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
1013 /* Print basic block on the dump streams. */
1016 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
1018 if (dump_file
&& (dump_kind
& pflags
))
1019 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
1020 if (alt_dump_file
&& (dump_kind
& alt_flags
))
1021 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
1024 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
1027 dump_function (int phase
, tree fn
)
1032 stream
= dump_begin (phase
, &flags
);
1035 dump_function_to_file (fn
, stream
, flags
);
1036 dump_end (phase
, stream
);
1040 /* Print information from the combine pass on dump_file. */
1043 print_combine_total_stats (void)
1046 dump_combine_total_stats (dump_file
);
1049 /* Enable RTL dump for all the RTL passes. */
1052 enable_rtl_dump_file (void)
1054 gcc::dump_manager
*dumps
= g
->get_dumps ();
1056 dumps
->dump_enable_all (DK_rtl
, dump_flags_t (TDF_DETAILS
) | TDF_BLOCKS
,
1058 return num_enabled
> 0;