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)
329 FILE *stream
= fopen (filename
, trunc
? "w" : "a");
332 error ("could not open dump file %qs: %m", filename
);
336 /* For a given DFI, open an alternate dump filename (which could also
337 be a standard stream such as stdout/stderr). If the alternate dump
338 file cannot be opened, return NULL. */
341 dump_open_alternate_stream (struct dump_file_info
*dfi
)
343 if (!dfi
->alt_filename
)
347 return dfi
->alt_stream
;
349 FILE *stream
= dump_open (dfi
->alt_filename
, dfi
->alt_state
< 0);
357 /* Print source location on DFILE if enabled. */
360 dump_loc (dump_flags_t dump_kind
, FILE *dfile
, source_location loc
)
364 if (LOCATION_LOCUS (loc
) > BUILTINS_LOCATION
)
365 fprintf (dfile
, "%s:%d:%d: note: ", LOCATION_FILE (loc
),
366 LOCATION_LINE (loc
), LOCATION_COLUMN (loc
));
367 else if (current_function_decl
)
368 fprintf (dfile
, "%s:%d:%d: note: ",
369 DECL_SOURCE_FILE (current_function_decl
),
370 DECL_SOURCE_LINE (current_function_decl
),
371 DECL_SOURCE_COLUMN (current_function_decl
));
375 /* Dump gimple statement GS with SPC indentation spaces and
376 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
379 dump_gimple_stmt (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
382 if (dump_file
&& (dump_kind
& pflags
))
383 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
385 if (alt_dump_file
&& (dump_kind
& alt_flags
))
386 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
389 /* Similar to dump_gimple_stmt, except additionally print source location. */
392 dump_gimple_stmt_loc (dump_flags_t dump_kind
, source_location loc
,
393 dump_flags_t extra_dump_flags
, gimple
*gs
, int spc
)
395 if (dump_file
&& (dump_kind
& pflags
))
397 dump_loc (dump_kind
, dump_file
, loc
);
398 print_gimple_stmt (dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
401 if (alt_dump_file
&& (dump_kind
& alt_flags
))
403 dump_loc (dump_kind
, alt_dump_file
, loc
);
404 print_gimple_stmt (alt_dump_file
, gs
, spc
, dump_flags
| extra_dump_flags
);
408 /* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
409 DUMP_KIND is enabled. */
412 dump_generic_expr (dump_flags_t dump_kind
, dump_flags_t extra_dump_flags
,
415 if (dump_file
&& (dump_kind
& pflags
))
416 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
418 if (alt_dump_file
&& (dump_kind
& alt_flags
))
419 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
423 /* Similar to dump_generic_expr, except additionally print the source
427 dump_generic_expr_loc (int dump_kind
, source_location loc
,
428 dump_flags_t extra_dump_flags
, tree t
)
430 if (dump_file
&& (dump_kind
& pflags
))
432 dump_loc (dump_kind
, dump_file
, loc
);
433 print_generic_expr (dump_file
, t
, dump_flags
| extra_dump_flags
);
436 if (alt_dump_file
&& (dump_kind
& alt_flags
))
438 dump_loc (dump_kind
, alt_dump_file
, loc
);
439 print_generic_expr (alt_dump_file
, t
, dump_flags
| extra_dump_flags
);
443 /* Output a formatted message using FORMAT on appropriate dump streams. */
446 dump_printf (dump_flags_t dump_kind
, const char *format
, ...)
448 if (dump_file
&& (dump_kind
& pflags
))
451 va_start (ap
, format
);
452 vfprintf (dump_file
, format
, ap
);
456 if (alt_dump_file
&& (dump_kind
& alt_flags
))
459 va_start (ap
, format
);
460 vfprintf (alt_dump_file
, format
, ap
);
465 /* Similar to dump_printf, except source location is also printed. */
468 dump_printf_loc (dump_flags_t dump_kind
, source_location loc
,
469 const char *format
, ...)
471 if (dump_file
&& (dump_kind
& pflags
))
474 dump_loc (dump_kind
, dump_file
, loc
);
475 va_start (ap
, format
);
476 vfprintf (dump_file
, format
, ap
);
480 if (alt_dump_file
&& (dump_kind
& alt_flags
))
483 dump_loc (dump_kind
, alt_dump_file
, loc
);
484 va_start (ap
, format
);
485 vfprintf (alt_dump_file
, format
, ap
);
490 /* Output VALUE in decimal to appropriate dump streams. */
492 template<unsigned int N
, typename C
>
494 dump_dec (int dump_kind
, const poly_int
<N
, C
> &value
)
496 STATIC_ASSERT (poly_coeff_traits
<C
>::signedness
>= 0);
497 signop sgn
= poly_coeff_traits
<C
>::signedness
? SIGNED
: UNSIGNED
;
498 if (dump_file
&& (dump_kind
& pflags
))
499 print_dec (value
, dump_file
, sgn
);
501 if (alt_dump_file
&& (dump_kind
& alt_flags
))
502 print_dec (value
, alt_dump_file
, sgn
);
505 template void dump_dec (int, const poly_uint16
&);
506 template void dump_dec (int, const poly_int64
&);
507 template void dump_dec (int, const poly_uint64
&);
508 template void dump_dec (int, const poly_offset_int
&);
509 template void dump_dec (int, const poly_widest_int
&);
511 /* Start a dump for PHASE. Store user-supplied dump flags in
512 *FLAG_PTR. Return the number of streams opened. Set globals
513 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
514 set dump_flags appropriately for both pass dump stream and
515 -fopt-info stream. */
519 dump_start (int phase
, dump_flags_t
*flag_ptr
)
523 struct dump_file_info
*dfi
;
525 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
528 dfi
= get_dump_file_info (phase
);
529 name
= get_dump_file_name (phase
);
532 stream
= dump_open (name
, dfi
->pstate
< 0);
539 dfi
->pstream
= stream
;
540 dump_file
= dfi
->pstream
;
541 /* Initialize current dump flags. */
542 pflags
= dfi
->pflags
;
545 stream
= dump_open_alternate_stream (dfi
);
548 dfi
->alt_stream
= stream
;
550 alt_dump_file
= dfi
->alt_stream
;
551 /* Initialize current -fopt-info flags. */
552 alt_flags
= dfi
->alt_flags
;
556 *flag_ptr
= dfi
->pflags
;
561 /* Finish a tree dump for PHASE and close associated dump streams. Also
562 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
566 dump_finish (int phase
)
568 struct dump_file_info
*dfi
;
572 dfi
= get_dump_file_info (phase
);
573 if (dfi
->pstream
&& dfi
->pstream
!= stdout
&& dfi
->pstream
!= stderr
)
574 fclose (dfi
->pstream
);
576 if (dfi
->alt_stream
&& dfi
->alt_stream
!= stdout
&& dfi
->alt_stream
!= stderr
)
577 fclose (dfi
->alt_stream
);
579 dfi
->alt_stream
= NULL
;
582 alt_dump_file
= NULL
;
583 dump_flags
= TDI_none
;
588 /* Begin a tree dump for PHASE. Stores any user supplied flag in
589 *FLAG_PTR and returns a stream to write to. If the dump is not
590 enabled, returns NULL.
591 Multiple calls will reopen and append to the dump file. */
594 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
596 return g
->get_dumps ()->dump_begin (phase
, flag_ptr
);
601 dump_begin (int phase
, dump_flags_t
*flag_ptr
)
604 struct dump_file_info
*dfi
;
607 if (phase
== TDI_none
|| !dump_phase_enabled_p (phase
))
610 name
= get_dump_file_name (phase
);
613 dfi
= get_dump_file_info (phase
);
615 stream
= dump_open (name
, dfi
->pstate
< 0);
621 *flag_ptr
= dfi
->pflags
;
623 /* Initialize current flags */
624 pflags
= dfi
->pflags
;
628 /* Returns nonzero if dump PHASE is enabled for at least one stream.
629 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
634 dump_phase_enabled_p (int phase
) const
636 if (phase
== TDI_tree_all
)
639 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
640 if (dump_files
[i
].pstate
|| dump_files
[i
].alt_state
)
642 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
643 if (m_extra_dump_files
[i
].pstate
|| m_extra_dump_files
[i
].alt_state
)
649 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
650 return dfi
->pstate
|| dfi
->alt_state
;
654 /* Returns nonzero if tree dump PHASE has been initialized. */
658 dump_initialized_p (int phase
) const
660 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
661 return dfi
->pstate
> 0 || dfi
->alt_state
> 0;
664 /* Returns the switch name of PHASE. */
667 dump_flag_name (int phase
)
669 return g
->get_dumps ()->dump_flag_name (phase
);
674 dump_flag_name (int phase
) const
676 struct dump_file_info
*dfi
= get_dump_file_info (phase
);
680 /* Finish a tree dump for PHASE. STREAM is the stream created by
684 dump_end (int phase ATTRIBUTE_UNUSED
, FILE *stream
)
686 if (stream
!= stderr
&& stream
!= stdout
)
690 /* Enable all tree dumps with FLAGS on FILENAME. Return number of
691 enabled tree dumps. */
695 dump_enable_all (dump_kind dkind
, dump_flags_t flags
, const char *filename
)
700 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
702 if ((dump_files
[i
].dkind
== dkind
))
704 const char *old_filename
= dump_files
[i
].pfilename
;
705 dump_files
[i
].pstate
= -1;
706 dump_files
[i
].pflags
|= flags
;
708 /* Override the existing filename. */
711 dump_files
[i
].pfilename
= xstrdup (filename
);
712 /* Since it is a command-line provided file, which is
713 common to all the phases, use it in append mode. */
714 dump_files
[i
].pstate
= 1;
716 if (old_filename
&& filename
!= old_filename
)
717 free (CONST_CAST (char *, old_filename
));
721 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
723 if ((m_extra_dump_files
[i
].dkind
== dkind
))
725 const char *old_filename
= m_extra_dump_files
[i
].pfilename
;
726 m_extra_dump_files
[i
].pstate
= -1;
727 m_extra_dump_files
[i
].pflags
|= flags
;
729 /* Override the existing filename. */
732 m_extra_dump_files
[i
].pfilename
= xstrdup (filename
);
733 /* Since it is a command-line provided file, which is
734 common to all the phases, use it in append mode. */
735 m_extra_dump_files
[i
].pstate
= 1;
737 if (old_filename
&& filename
!= old_filename
)
738 free (CONST_CAST (char *, old_filename
));
745 /* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
746 Enable dumps with FLAGS on FILENAME. Return the number of enabled
751 opt_info_enable_passes (int optgroup_flags
, dump_flags_t flags
,
752 const char *filename
)
757 for (i
= TDI_none
+ 1; i
< (size_t) TDI_end
; i
++)
759 if ((dump_files
[i
].optgroup_flags
& optgroup_flags
))
761 const char *old_filename
= dump_files
[i
].alt_filename
;
762 /* Since this file is shared among different passes, it
763 should be opened in append mode. */
764 dump_files
[i
].alt_state
= 1;
765 dump_files
[i
].alt_flags
|= flags
;
767 /* Override the existing filename. */
769 dump_files
[i
].alt_filename
= xstrdup (filename
);
770 if (old_filename
&& filename
!= old_filename
)
771 free (CONST_CAST (char *, old_filename
));
775 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
777 if ((m_extra_dump_files
[i
].optgroup_flags
& optgroup_flags
))
779 const char *old_filename
= m_extra_dump_files
[i
].alt_filename
;
780 /* Since this file is shared among different passes, it
781 should be opened in append mode. */
782 m_extra_dump_files
[i
].alt_state
= 1;
783 m_extra_dump_files
[i
].alt_flags
|= flags
;
785 /* Override the existing filename. */
787 m_extra_dump_files
[i
].alt_filename
= xstrdup (filename
);
788 if (old_filename
&& filename
!= old_filename
)
789 free (CONST_CAST (char *, old_filename
));
796 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
797 relevant details in the dump_files array. */
801 dump_switch_p_1 (const char *arg
, struct dump_file_info
*dfi
, bool doglob
)
803 const char *option_value
;
807 if (doglob
&& !dfi
->glob
)
810 option_value
= skip_leading_substring (arg
, doglob
? dfi
->glob
: dfi
->swtch
);
814 if (*option_value
&& *option_value
!= '-' && *option_value
!= '=')
822 const struct dump_option_value_info
*option_ptr
;
829 end_ptr
= strchr (ptr
, '-');
830 eq_ptr
= strchr (ptr
, '=');
832 if (eq_ptr
&& !end_ptr
)
836 end_ptr
= ptr
+ strlen (ptr
);
837 length
= end_ptr
- ptr
;
839 for (option_ptr
= dump_options
; option_ptr
->name
; option_ptr
++)
840 if (strlen (option_ptr
->name
) == length
841 && !memcmp (option_ptr
->name
, ptr
, length
))
843 flags
|= option_ptr
->value
;
849 /* Interpret rest of the argument as a dump filename. This
850 filename overrides other command line filenames. */
852 free (CONST_CAST (char *, dfi
->pfilename
));
853 dfi
->pfilename
= xstrdup (ptr
+ 1);
857 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
858 length
, ptr
, dfi
->swtch
);
864 dfi
->pflags
|= flags
;
866 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
868 if (dfi
->suffix
== NULL
)
869 dump_enable_all (dfi
->dkind
, dfi
->pflags
, dfi
->pfilename
);
876 dump_switch_p (const char *arg
)
881 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
882 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], false);
884 /* Don't glob if we got a hit already */
886 for (i
= TDI_none
+ 1; i
!= TDI_end
; i
++)
887 any
|= dump_switch_p_1 (arg
, &dump_files
[i
], true);
889 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
890 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], false);
893 for (i
= 0; i
< m_extra_dump_files_in_use
; i
++)
894 any
|= dump_switch_p_1 (arg
, &m_extra_dump_files
[i
], true);
900 /* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
901 and filename. Return non-zero if it is a recognized switch. */
904 opt_info_switch_p_1 (const char *arg
, dump_flags_t
*flags
, int *optgroup_flags
,
907 const char *option_value
;
918 return 1; /* Handle '-fopt-info' without any additional options. */
922 const struct dump_option_value_info
*option_ptr
;
929 end_ptr
= strchr (ptr
, '-');
930 eq_ptr
= strchr (ptr
, '=');
932 if (eq_ptr
&& !end_ptr
)
936 end_ptr
= ptr
+ strlen (ptr
);
937 length
= end_ptr
- ptr
;
939 for (option_ptr
= optinfo_verbosity_options
; option_ptr
->name
;
941 if (strlen (option_ptr
->name
) == length
942 && !memcmp (option_ptr
->name
, ptr
, length
))
944 *flags
|= option_ptr
->value
;
948 for (option_ptr
= optgroup_options
; option_ptr
->name
; option_ptr
++)
949 if (strlen (option_ptr
->name
) == length
950 && !memcmp (option_ptr
->name
, ptr
, length
))
952 *optgroup_flags
|= option_ptr
->value
;
958 /* Interpret rest of the argument as a dump filename. This
959 filename overrides other command line filenames. */
960 *filename
= xstrdup (ptr
+ 1);
965 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
976 /* Return non-zero if ARG is a recognized switch for
977 -fopt-info. Return zero otherwise. */
980 opt_info_switch_p (const char *arg
)
985 static char *file_seen
= NULL
;
986 gcc::dump_manager
*dumps
= g
->get_dumps ();
988 if (!opt_info_switch_p_1 (arg
, &flags
, &optgroup_flags
, &filename
))
992 filename
= xstrdup ("stderr");
994 /* Bail out if a different filename has been specified. */
995 if (file_seen
&& strcmp (file_seen
, filename
))
997 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
1002 file_seen
= xstrdup (filename
);
1004 flags
= MSG_OPTIMIZED_LOCATIONS
;
1005 if (!optgroup_flags
)
1006 optgroup_flags
= OPTGROUP_ALL
;
1008 return dumps
->opt_info_enable_passes (optgroup_flags
, flags
, filename
);
1011 /* Print basic block on the dump streams. */
1014 dump_basic_block (int dump_kind
, basic_block bb
, int indent
)
1016 if (dump_file
&& (dump_kind
& pflags
))
1017 dump_bb (dump_file
, bb
, indent
, TDF_DETAILS
);
1018 if (alt_dump_file
&& (dump_kind
& alt_flags
))
1019 dump_bb (alt_dump_file
, bb
, indent
, TDF_DETAILS
);
1022 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
1025 dump_function (int phase
, tree fn
)
1030 stream
= dump_begin (phase
, &flags
);
1033 dump_function_to_file (fn
, stream
, flags
);
1034 dump_end (phase
, stream
);
1038 /* Print information from the combine pass on dump_file. */
1041 print_combine_total_stats (void)
1044 dump_combine_total_stats (dump_file
);
1047 /* Enable RTL dump for all the RTL passes. */
1050 enable_rtl_dump_file (void)
1052 gcc::dump_manager
*dumps
= g
->get_dumps ();
1054 dumps
->dump_enable_all (DK_rtl
, dump_flags_t (TDF_DETAILS
) | TDF_BLOCKS
,
1056 return num_enabled
> 0;