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 /* Open a dump file called FILENAME. Some filenames are special and
316 refer to the standard streams. TRUNC indicates whether this is the
317 first open (so the file should be truncated, rather than appended).
318 An error message is emitted in the event of failure. */
321 dump_open (const char *filename
, bool trunc
)
323 if (strcmp ("stderr", filename
) == 0)
326 if (strcmp ("stdout", filename
) == 0
327 || strcmp ("-", filename
) == 0)
330 FILE *stream
= fopen (filename
, trunc
? "w" : "a");
333 error ("could not open dump file %qs: %m", filename
);
337 /* For a given DFI, open an alternate dump filename (which could also
338 be a standard stream such as stdout/stderr). If the alternate dump
339 file cannot be opened, return NULL. */
342 dump_open_alternate_stream (struct dump_file_info
*dfi
)
344 if (!dfi
->alt_filename
)
348 return dfi
->alt_stream
;
350 FILE *stream
= dump_open (dfi
->alt_filename
, dfi
->alt_state
< 0);
358 /* Print source location on DFILE if enabled. */
361 dump_loc (dump_flags_t dump_kind
, FILE *dfile
, source_location loc
)
365 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
366 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
367 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
368 else if (current_function_decl
)
369 fprintf (dfile
, "%s:%d:%d: note: ",
370 DECL_SOURCE_FILE (current_function_decl
),
371 DECL_SOURCE_LINE (current_function_decl
),
372 DECL_SOURCE_COLUMN (current_function_decl
));
376 /* Dump gimple statement GS with SPC indentation spaces and
377 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
380 dump_gimple_stmt (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
383 if (dump_file
&& (dump_kind
& pflags
))
384 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
386 if (alt_dump_file
&& (dump_kind
& alt_flags
))
387 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
390 /* Similar to dump_gimple_stmt, except additionally print source location. */
393 dump_gimple_stmt_loc (dump_flags_t dump_kind
, source_location loc
,
394 dump_flags_t extra_dump_flags
, gimple
*gs
, int spc
)
396 if (dump_file
&& (dump_kind
& pflags
))
398 dump_loc (dump_kind
, dump_file
, loc
);
399 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
402 if (alt_dump_file
&& (dump_kind
& alt_flags
))
404 dump_loc (dump_kind
, alt_dump_file
, loc
);
405 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
409 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
410 DUMP_KIND is enabled. */
413 dump_generic_expr (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
416 if (dump_file
&& (dump_kind
& pflags
))
417 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
419 if (alt_dump_file
&& (dump_kind
& alt_flags
))
420 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
424 /* Similar to dump_generic_expr, except additionally print the source
428 dump_generic_expr_loc (int dump_kind
, source_location loc
,
429 dump_flags_t extra_dump_flags
, tree t
)
431 if (dump_file
&& (dump_kind
& pflags
))
433 dump_loc (dump_kind
, dump_file
, loc
);
434 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
437 if (alt_dump_file
&& (dump_kind
& alt_flags
))
439 dump_loc (dump_kind
, alt_dump_file
, loc
);
440 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
444 /* Output a formatted message using FORMAT on appropriate dump streams. */
447 dump_printf (dump_flags_t dump_kind
, const char *format
, ...)
449 if (dump_file
&& (dump_kind
& pflags
))
452 va_start (ap
, format
);
453 vfprintf (dump_file
, format
, ap
);
457 if (alt_dump_file
&& (dump_kind
& alt_flags
))
460 va_start (ap
, format
);
461 vfprintf (alt_dump_file
, format
, ap
);
466 /* Similar to dump_printf, except source location is also printed. */
469 dump_printf_loc (dump_flags_t dump_kind
, source_location loc
,
470 const char *format
, ...)
472 if (dump_file
&& (dump_kind
& pflags
))
475 dump_loc (dump_kind
, dump_file
, loc
);
476 va_start (ap
, format
);
477 vfprintf (dump_file
, format
, ap
);
481 if (alt_dump_file
&& (dump_kind
& alt_flags
))
484 dump_loc (dump_kind
, alt_dump_file
, loc
);
485 va_start (ap
, format
);
486 vfprintf (alt_dump_file
, format
, ap
);
491 /* Output VALUE in decimal to appropriate dump streams. */
493 template<unsigned int N
, typename C
>
495 dump_dec (int dump_kind
, const poly_int
<N
, C
> &value
)
497 STATIC_ASSERT (poly_coeff_traits
<C
>::signedness
>= 0);
498 signop sgn
= poly_coeff_traits
<C
>::signedness
? SIGNED
: UNSIGNED
;
499 if (dump_file
&& (dump_kind
& pflags
))
500 print_dec (value
, dump_file
, sgn
);
502 if (alt_dump_file
&& (dump_kind
& alt_flags
))
503 print_dec (value
, alt_dump_file
, sgn
);
506 template void dump_dec (int, const poly_uint16
&);
507 template void dump_dec (int, const poly_int64
&);
508 template void dump_dec (int, const poly_uint64
&);
509 template void dump_dec (int, const poly_offset_int
&);
510 template void dump_dec (int, const poly_widest_int
&);
512 /* Start a dump for PHASE. Store user-supplied dump flags in
513 *FLAG_PTR. Return the number of streams opened. Set globals
514 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
515 set dump_flags appropriately for both pass dump stream and
516 -fopt-info stream. */
520 dump_start (int phase
, dump_flags_t
*flag_ptr
)
524 struct dump_file_info
*dfi
;
526 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
529 dfi
= get_dump_file_info (phase
);
530 name
= get_dump_file_name (phase
);
533 stream
= dump_open (name
, dfi
->pstate
< 0);
540 dfi
->pstream
= stream
;
541 dump_file
= dfi
->pstream
;
542 /* Initialize current dump flags. */
543 pflags
= dfi
->pflags
;
546 stream
= dump_open_alternate_stream (dfi
);
549 dfi
->alt_stream
= stream
;
551 alt_dump_file
= dfi
->alt_stream
;
552 /* Initialize current -fopt-info flags. */
553 alt_flags
= dfi
->alt_flags
;
557 *flag_ptr
= dfi
->pflags
;
562 /* Finish a tree dump for PHASE and close associated dump streams. Also
563 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
567 dump_finish (int phase
)
569 struct dump_file_info
*dfi
;
573 dfi
= get_dump_file_info (phase
);
574 if (dfi
->pstream
&& dfi
->pstream
!= stdout
&& dfi
->pstream
!= stderr
)
575 fclose (dfi
->pstream
);
577 if (dfi
->alt_stream
&& dfi
->alt_stream
!= stdout
&& dfi
->alt_stream
!= stderr
)
578 fclose (dfi
->alt_stream
);
580 dfi
->alt_stream
= NULL
;
583 alt_dump_file
= NULL
;
584 dump_flags
= TDI_none
;
589 /* Begin a tree dump for PHASE. Stores any user supplied flag in
590 *FLAG_PTR and returns a stream to write to. If the dump is not
591 enabled, returns NULL.
592 Multiple calls will reopen and append to the dump file. */
595 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
597 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
602 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
605 struct dump_file_info
*dfi
;
608 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
611 name
= get_dump_file_name (phase
);
614 dfi
= get_dump_file_info (phase
);
616 stream
= dump_open (name
, dfi
->pstate
< 0);
622 *flag_ptr
= dfi
->pflags
;
624 /* Initialize current flags */
625 pflags
= dfi
->pflags
;
629 /* Returns nonzero if dump PHASE is enabled for at least one stream.
630 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
635 dump_phase_enabled_p (int phase
) const
637 if (phase
== TDI_tree_all
)
640 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
641 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
643 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
644 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
650 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
651 return dfi
->pstate
|| dfi
->alt_state
;
655 /* Returns nonzero if tree dump PHASE has been initialized. */
659 dump_initialized_p (int phase
) const
661 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
662 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
665 /* Returns the switch name of PHASE. */
668 dump_flag_name (int phase
)
670 return g
->get_dumps ()->dump_flag_name (phase
);
675 dump_flag_name (int phase
) const
677 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
681 /* Finish a tree dump for PHASE. STREAM is the stream created by
685 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
687 if (stream
!= stderr
&& stream
!= stdout
)
691 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
692 enabled tree dumps. */
696 dump_enable_all (dump_kind dkind
, dump_flags_t flags
, const char *filename
)
701 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
703 if ((dump_files
[i
].dkind
== dkind
))
705 const char *old_filename
= dump_files
[i
].pfilename
;
706 dump_files
[i
].pstate
= -1;
707 dump_files
[i
].pflags
|= flags
;
709 /* Override the existing filename. */
712 dump_files
[i
].pfilename
= xstrdup (filename
);
713 /* Since it is a command-line provided file, which is
714 common to all the phases, use it in append mode. */
715 dump_files
[i
].pstate
= 1;
717 if (old_filename
&& filename
!= old_filename
)
718 free (CONST_CAST (char *, old_filename
));
722 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
724 if ((m_extra_dump_files
[i
].dkind
== dkind
))
726 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
727 m_extra_dump_files
[i
].pstate
= -1;
728 m_extra_dump_files
[i
].pflags
|= flags
;
730 /* Override the existing filename. */
733 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
734 /* Since it is a command-line provided file, which is
735 common to all the phases, use it in append mode. */
736 m_extra_dump_files
[i
].pstate
= 1;
738 if (old_filename
&& filename
!= old_filename
)
739 free (CONST_CAST (char *, old_filename
));
746 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
747 Enable dumps with FLAGS on FILENAME. Return the number of enabled
752 opt_info_enable_passes (int optgroup_flags
, dump_flags_t flags
,
753 const char *filename
)
758 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
760 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
762 const char *old_filename
= dump_files
[i
].alt_filename
;
763 /* Since this file is shared among different passes, it
764 should be opened in append mode. */
765 dump_files
[i
].alt_state
= 1;
766 dump_files
[i
].alt_flags
|= flags
;
768 /* Override the existing filename. */
770 dump_files
[i
].alt_filename
= xstrdup (filename
);
771 if (old_filename
&& filename
!= old_filename
)
772 free (CONST_CAST (char *, old_filename
));
776 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
778 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
780 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
781 /* Since this file is shared among different passes, it
782 should be opened in append mode. */
783 m_extra_dump_files
[i
].alt_state
= 1;
784 m_extra_dump_files
[i
].alt_flags
|= flags
;
786 /* Override the existing filename. */
788 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
789 if (old_filename
&& filename
!= old_filename
)
790 free (CONST_CAST (char *, old_filename
));
797 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
798 relevant details in the dump_files array. */
802 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
804 const char *option_value
;
808 if (doglob
&& !dfi
->glob
)
811 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
815 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
823 const struct dump_option_value_info
*option_ptr
;
830 end_ptr
= strchr (ptr
, '-');
831 eq_ptr
= strchr (ptr
, '=');
833 if (eq_ptr
&& !end_ptr
)
837 end_ptr
= ptr
+ strlen (ptr
);
838 length
= end_ptr
- ptr
;
840 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
841 if (strlen (option_ptr
->name
) == length
842 && !memcmp (option_ptr
->name
, ptr
, length
))
844 flags
|= option_ptr
->value
;
850 /* Interpret rest of the argument as a dump filename. This
851 filename overrides other command line filenames. */
853 free (CONST_CAST (char *, dfi
->pfilename
));
854 dfi
->pfilename
= xstrdup (ptr
+ 1);
858 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
859 length
, ptr
, dfi
->swtch
);
865 dfi
->pflags
|= flags
;
867 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
869 if (dfi
->suffix
== NULL
)
870 dump_enable_all (dfi
->dkind
, dfi
->pflags
, dfi
->pfilename
);
877 dump_switch_p (const char *arg
)
882 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
883 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
885 /* Don't glob if we got a hit already */
887 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
888 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
890 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
891 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
894 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
895 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
901 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
902 and filename. Return non-zero if it is a recognized switch. */
905 opt_info_switch_p_1 (const char *arg
, dump_flags_t
*flags
, int *optgroup_flags
,
908 const char *option_value
;
919 return 1; /* Handle '-fopt-info' without any additional options. */
923 const struct dump_option_value_info
*option_ptr
;
930 end_ptr
= strchr (ptr
, '-');
931 eq_ptr
= strchr (ptr
, '=');
933 if (eq_ptr
&& !end_ptr
)
937 end_ptr
= ptr
+ strlen (ptr
);
938 length
= end_ptr
- ptr
;
940 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
942 if (strlen (option_ptr
->name
) == length
943 && !memcmp (option_ptr
->name
, ptr
, length
))
945 *flags
|= option_ptr
->value
;
949 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
950 if (strlen (option_ptr
->name
) == length
951 && !memcmp (option_ptr
->name
, ptr
, length
))
953 *optgroup_flags
|= option_ptr
->value
;
959 /* Interpret rest of the argument as a dump filename. This
960 filename overrides other command line filenames. */
961 *filename
= xstrdup (ptr
+ 1);
966 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
977 /* Return non-zero if ARG is a recognized switch for
978 -fopt-info. Return zero otherwise. */
981 opt_info_switch_p (const char *arg
)
986 static char *file_seen
= NULL
;
987 gcc::dump_manager
*dumps
= g
->get_dumps ();
989 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
993 filename
= xstrdup ("stderr");
995 /* Bail out if a different filename has been specified. */
996 if (file_seen
&& strcmp (file_seen
, filename
))
998 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
1003 file_seen
= xstrdup (filename
);
1005 flags
= MSG_OPTIMIZED_LOCATIONS
;
1006 if (!optgroup_flags
)
1007 optgroup_flags
= OPTGROUP_ALL
;
1009 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
1012 /* Print basic block on the dump streams. */
1015 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
1017 if (dump_file
&& (dump_kind
& pflags
))
1018 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
1019 if (alt_dump_file
&& (dump_kind
& alt_flags
))
1020 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
1023 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
1026 dump_function (int phase
, tree fn
)
1031 stream
= dump_begin (phase
, &flags
);
1034 dump_function_to_file (fn
, stream
, flags
);
1035 dump_end (phase
, stream
);
1039 /* Print information from the combine pass on dump_file. */
1042 print_combine_total_stats (void)
1045 dump_combine_total_stats (dump_file
);
1048 /* Enable RTL dump for all the RTL passes. */
1051 enable_rtl_dump_file (void)
1053 gcc::dump_manager
*dumps
= g
->get_dumps ();
1055 dumps
->dump_enable_all (DK_rtl
, dump_flags_t (TDF_DETAILS
) | TDF_BLOCKS
,
1057 return num_enabled
> 0;