summaryrefslogtreecommitdiff
path: root/gcc/dumpfile.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-10-04 14:33:47 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-10-04 14:33:47 +0000
commit5d98e5a6bc715cc865b9110ff0255572ac22570d (patch)
tree7f7ee75a6d43b65b14261ebf6740d5d18c39f684 /gcc/dumpfile.c
parentc19bc1a0832c01c0162aaba829b24609f60bba91 (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.c120
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. */