diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-10-04 14:33:47 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-10-04 14:33:47 +0000 |
commit | 5d98e5a6bc715cc865b9110ff0255572ac22570d (patch) | |
tree | 7f7ee75a6d43b65b14261ebf6740d5d18c39f684 /gcc/dumpfile.c | |
parent | c19bc1a0832c01c0162aaba829b24609f60bba91 (diff) |
Fix -fopt-info for plugin passes
Attempts to dump via -fopt-info from a plugin pass fail, due
to the dfi->alt_state for such passes never being set.
This is because the -fopt-info options were being set up per-pass
during option-parsing (via gcc::dump_manager::opt_info_enable_passes),
but this data was not retained or used it for passes created later
(for plugins and target-specific passes).
This patch fixes the issue by storing the -fopt-info options into
gcc::dump_manager, refactoring the dfi-setup code out of
opt_info_enable_passes, and reusing it for such passes, fixing the
issue. The patch adds a demo plugin to test that dumping from a
plugin works.
gcc/ChangeLog:
* dumpfile.c (gcc::dump_manager::dump_manager): Initialize new
fields.
(gcc::dump_manager::~dump_manager): Free m_optinfo_filename.
(gcc::dump_manager::register_pass): New member function, adapted
from loop body in gcc::pass_manager::register_pass, adding a
call to update_dfi_for_opt_info.
(gcc::dump_manager::opt_info_enable_passes): Store the
-fopt-info options into the new fields. Move the loop
bodies into...
(gcc::dump_manager::update_dfi_for_opt_info): ...this new member
function.
* dumpfile.h (struct opt_pass): New forward decl.
(gcc::dump_manager::register_pass): New decl.
(gcc::dump_manager::update_dfi_for_opt_info): New decl.
(class gcc::dump_manager): Add fields "m_optgroup_flags",
"m_optinfo_flags", and "m_optinfo_filename".
* passes.c (gcc::pass_manager::register_pass): Move all of the
dump-handling code to gcc::dump_manager::register_pass.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/dump-1.c: New test.
* gcc.dg/plugin/dump_plugin.c: New test plugin.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add the above.
From-SVN: r264844
Diffstat (limited to 'gcc/dumpfile.c')
-rw-r--r-- | gcc/dumpfile.c | 120 |
1 files changed, 84 insertions, 36 deletions
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c index d430ea3ff9c..d359e41f750 100644 --- a/gcc/dumpfile.c +++ b/gcc/dumpfile.c @@ -177,12 +177,16 @@ gcc::dump_manager::dump_manager (): m_next_dump (FIRST_AUTO_NUMBERED_DUMP), m_extra_dump_files (NULL), m_extra_dump_files_in_use (0), - m_extra_dump_files_alloced (0) + m_extra_dump_files_alloced (0), + m_optgroup_flags (OPTGROUP_NONE), + m_optinfo_flags (TDF_NONE), + m_optinfo_filename (NULL) { } gcc::dump_manager::~dump_manager () { + free (m_optinfo_filename); for (size_t i = 0; i < m_extra_dump_files_in_use; i++) { dump_file_info *dfi = &m_extra_dump_files[i]; @@ -1512,6 +1516,50 @@ dump_flag_name (int phase) const return dfi->swtch; } +/* Handle -fdump-* and -fopt-info for a pass added after + command-line options are parsed (those from plugins and + those from backends). + + Because the registration of plugin/backend passes happens after the + command-line options are parsed, the options that specify single + pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new + passes. Therefore we currently can only enable dumping of + new passes when the 'dump-all' flags (e.g. -fdump-tree-all) + are specified. This is done here. + + Similarly, the saved -fopt-info options are wired up to the new pass. */ + +void +gcc::dump_manager::register_pass (opt_pass *pass) +{ + gcc_assert (pass); + + register_one_dump_file (pass); + + dump_file_info *pass_dfi = get_dump_file_info (pass->static_pass_number); + gcc_assert (pass_dfi); + + enum tree_dump_index tdi; + if (pass->type == SIMPLE_IPA_PASS + || pass->type == IPA_PASS) + tdi = TDI_ipa_all; + else if (pass->type == GIMPLE_PASS) + tdi = TDI_tree_all; + else + tdi = TDI_rtl_all; + const dump_file_info *tdi_dfi = get_dump_file_info (tdi); + gcc_assert (tdi_dfi); + + /* Check if dump-all flag is specified. */ + if (tdi_dfi->pstate) + { + pass_dfi->pstate = tdi_dfi->pstate; + pass_dfi->pflags = tdi_dfi->pflags; + } + + update_dfi_for_opt_info (pass_dfi); +} + /* Finish a tree dump for PHASE. STREAM is the stream created by dump_begin. */ @@ -1587,47 +1635,47 @@ opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags, const char *filename) { int n = 0; - size_t i; - for (i = TDI_none + 1; i < (size_t) TDI_end; i++) - { - if ((dump_files[i].optgroup_flags & optgroup_flags)) - { - const char *old_filename = dump_files[i].alt_filename; - /* Since this file is shared among different passes, it - should be opened in append mode. */ - dump_files[i].alt_state = 1; - dump_files[i].alt_flags |= flags; - n++; - /* Override the existing filename. */ - if (filename) - dump_files[i].alt_filename = xstrdup (filename); - if (old_filename && filename != old_filename) - free (CONST_CAST (char *, old_filename)); - } - } + m_optgroup_flags = optgroup_flags; + m_optinfo_flags = flags; + m_optinfo_filename = xstrdup (filename); - for (i = 0; i < m_extra_dump_files_in_use; i++) - { - if ((m_extra_dump_files[i].optgroup_flags & optgroup_flags)) - { - const char *old_filename = m_extra_dump_files[i].alt_filename; - /* Since this file is shared among different passes, it - should be opened in append mode. */ - m_extra_dump_files[i].alt_state = 1; - m_extra_dump_files[i].alt_flags |= flags; - n++; - /* Override the existing filename. */ - if (filename) - m_extra_dump_files[i].alt_filename = xstrdup (filename); - if (old_filename && filename != old_filename) - free (CONST_CAST (char *, old_filename)); - } - } + for (size_t i = TDI_none + 1; i < (size_t) TDI_end; i++) + if (update_dfi_for_opt_info (&dump_files[i])) + n++; + + for (size_t i = 0; i < m_extra_dump_files_in_use; i++) + if (update_dfi_for_opt_info (&m_extra_dump_files[i])) + n++; return n; } +/* Use the saved -fopt-info options to update DFI. + Return true if the dump is enabled. */ + +bool +gcc::dump_manager::update_dfi_for_opt_info (dump_file_info *dfi) const +{ + gcc_assert (dfi); + + if (!(dfi->optgroup_flags & m_optgroup_flags)) + return false; + + const char *old_filename = dfi->alt_filename; + /* Since this file is shared among different passes, it + should be opened in append mode. */ + dfi->alt_state = 1; + dfi->alt_flags |= m_optinfo_flags; + /* Override the existing filename. */ + if (m_optinfo_filename) + dfi->alt_filename = xstrdup (m_optinfo_filename); + if (old_filename && m_optinfo_filename != old_filename) + free (CONST_CAST (char *, old_filename)); + + return true; +} + /* Parse ARG as a dump switch. Return nonzero if it is, and store the relevant details in the dump_files array. */ |