aboutsummaryrefslogtreecommitdiff
path: root/gcc/dumpfile.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-07-19 20:49:25 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-07-19 20:49:25 +0000
commit4df3629eb775ef9a4578c0bed3194565ca30e690 (patch)
tree6a3d9241b9f22c4142966a40b77cd934a1fc00e3 /gcc/dumpfile.c
parent30c460535576882863fe4e0db740b4ac4bcfaba9 (diff)
downloadgcc-4df3629eb775ef9a4578c0bed3194565ca30e690.zip
gcc-4df3629eb775ef9a4578c0bed3194565ca30e690.tar.gz
gcc-4df3629eb775ef9a4578c0bed3194565ca30e690.tar.bz2
Add "optinfo" framework
This patch implements a way to consolidate dump_* calls into optinfo objects, as enabling work towards being able to write out optimization records to a file. The patch adds the support for building optinfo instances from dump_* calls, but leaves implementing any *users* of them to followup patches. gcc/ChangeLog: * Makefile.in (OBJS): Add optinfo.o. * coretypes.h (class symtab_node): New forward decl. (struct cgraph_node): New forward decl. (class varpool_node): New forward decl. * dump-context.h: New file. * dumpfile.c: Include "optinfo.h", "dump-context.h", "cgraph.h", "tree-pass.h". (refresh_dumps_are_enabled): Use optinfo_enabled_p. (set_dump_file): Call dumpfile_ensure_any_optinfo_are_flushed. (set_alt_dump_file): Likewise. (dump_context::~dump_context): New dtor. (dump_gimple_stmt): Move implementation to... (dump_context::dump_gimple_stmt): ...this new member function. Add the stmt to any pending optinfo, creating one if need be. (dump_gimple_stmt_loc): Move implementation to... (dump_context::dump_gimple_stmt_loc): ...this new member function. Start a new optinfo and add the stmt to it. (dump_gimple_expr): Move implementation to... (dump_context::dump_gimple_expr): ...this new member function. Add the stmt to any pending optinfo, creating one if need be. (dump_gimple_expr_loc): Move implementation to... (dump_context::dump_gimple_expr_loc): ...this new member function. Start a new optinfo and add the stmt to it. (dump_generic_expr): Move implementation to... (dump_context::dump_generic_expr): ...this new member function. Add the tree to any pending optinfo, creating one if need be. (dump_generic_expr_loc): Move implementation to... (dump_context::dump_generic_expr_loc): ...this new member function. Add the tree to any pending optinfo, creating one if need be. (dump_printf): Move implementation to... (dump_context::dump_printf_va): ...this new member function. Add the text to any pending optinfo, creating one if need be. (dump_printf_loc): Move implementation to... (dump_context::dump_printf_loc_va): ...this new member function. Start a new optinfo and add the stmt to it. (dump_dec): Move implementation to... (dump_context::dump_dec): ...this new member function. Add the value to any pending optinfo, creating one if need be. (dump_context::dump_symtab_node): New member function. (dump_context::get_scope_depth): New member function. (dump_context::begin_scope): New member function. (dump_context::end_scope): New member function. (dump_context::ensure_pending_optinfo): New member function. (dump_context::begin_next_optinfo): New member function. (dump_context::end_any_optinfo): New member function. (dump_context::s_current): New global. (dump_context::s_default): New global. (dump_scope_depth): Delete global. (dumpfile_ensure_any_optinfo_are_flushed): New function. (dump_symtab_node): New function. (get_dump_scope_depth): Reimplement in terms of dump_context. (dump_begin_scope): Likewise. (dump_end_scope): Likewise. (selftest::temp_dump_context::temp_dump_context): New ctor. (selftest::temp_dump_context::~temp_dump_context): New dtor. (selftest::verify_item): New function. (ASSERT_IS_TEXT): New macro. (ASSERT_IS_TREE): New macro. (ASSERT_IS_GIMPLE): New macro. (selftest::test_capture_of_dump_calls): New test. (selftest::dumpfile_c_tests): Call it. * dumpfile.h (dump_printf, dump_printf_loc, dump_basic_block) (dump_generic_expr_loc, dump_generic_expr, dump_gimple_stmt_loc) (dump_gimple_stmt, dump_dec): Gather these related decls and add a descriptive comment. (dump_function, print_combine_total_stats, enable_rtl_dump_file) (dump_node, dump_bb): Move these unrelated decls. (class dump_manager): Add leading comment. * optinfo.cc: New file. * optinfo.h: New file. From-SVN: r262891
Diffstat (limited to 'gcc/dumpfile.c')
-rw-r--r--gcc/dumpfile.c597
1 files changed, 556 insertions, 41 deletions
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 4de7d28..74b5855 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -33,6 +33,10 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h" /* for dump_user_location_t ctor. */
#include "rtl.h" /* for dump_user_location_t ctor. */
#include "selftest.h"
+#include "optinfo.h"
+#include "dump-context.h"
+#include "cgraph.h"
+#include "tree-pass.h" /* for "current_pass". */
/* If non-NULL, return one past-the-end of the matching SUBPART of
the WHOLE string. */
@@ -64,7 +68,7 @@ bool dumps_are_enabled = false;
static void
refresh_dumps_are_enabled ()
{
- dumps_are_enabled = (dump_file || alt_dump_file);
+ dumps_are_enabled = (dump_file || alt_dump_file || optinfo_enabled_p ());
}
/* Set global "dump_file" to NEW_DUMP_FILE, refreshing the "dumps_are_enabled"
@@ -73,6 +77,7 @@ refresh_dumps_are_enabled ()
void
set_dump_file (FILE *new_dump_file)
{
+ dumpfile_ensure_any_optinfo_are_flushed ();
dump_file = new_dump_file;
refresh_dumps_are_enabled ();
}
@@ -83,6 +88,7 @@ set_dump_file (FILE *new_dump_file)
static void
set_alt_dump_file (FILE *new_alt_dump_file)
{
+ dumpfile_ensure_any_optinfo_are_flushed ();
alt_dump_file = new_alt_dump_file;
refresh_dumps_are_enabled ();
}
@@ -465,25 +471,44 @@ dump_loc (dump_flags_t dump_kind, FILE *dfile, source_location loc)
}
}
+/* Implementation of dump_context member functions. */
+
+/* dump_context's dtor. */
+
+dump_context::~dump_context ()
+{
+ delete m_pending;
+}
+
/* Dump gimple statement GS with SPC indentation spaces and
EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
void
-dump_gimple_stmt (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
- gimple *gs, int spc)
+dump_context::dump_gimple_stmt (dump_flags_t dump_kind,
+ dump_flags_t extra_dump_flags,
+ gimple *gs, int spc)
{
if (dump_file && (dump_kind & pflags))
print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
if (alt_dump_file && (dump_kind & alt_flags))
print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = ensure_pending_optinfo ();
+ info.handle_dump_file_kind (dump_kind);
+ info.add_gimple_stmt (gs, spc, dump_flags | extra_dump_flags);
+ }
}
/* Similar to dump_gimple_stmt, except additionally print source location. */
void
-dump_gimple_stmt_loc (dump_flags_t dump_kind, const dump_location_t &loc,
- dump_flags_t extra_dump_flags, gimple *gs, int spc)
+dump_context::dump_gimple_stmt_loc (dump_flags_t dump_kind,
+ const dump_location_t &loc,
+ dump_flags_t extra_dump_flags,
+ gimple *gs, int spc)
{
location_t srcloc = loc.get_location_t ();
if (dump_file && (dump_kind & pflags))
@@ -497,6 +522,13 @@ dump_gimple_stmt_loc (dump_flags_t dump_kind, const dump_location_t &loc,
dump_loc (dump_kind, alt_dump_file, srcloc);
print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
}
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = begin_next_optinfo (loc);
+ info.handle_dump_file_kind (dump_kind);
+ info.add_gimple_stmt (gs, spc, dump_flags | extra_dump_flags);
+ }
}
/* Dump gimple statement GS with SPC indentation spaces and
@@ -504,21 +536,32 @@ dump_gimple_stmt_loc (dump_flags_t dump_kind, const dump_location_t &loc,
Do not terminate with a newline or semicolon. */
void
-dump_gimple_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
- gimple *gs, int spc)
+dump_context::dump_gimple_expr (dump_flags_t dump_kind,
+ dump_flags_t extra_dump_flags,
+ gimple *gs, int spc)
{
if (dump_file && (dump_kind & pflags))
print_gimple_expr (dump_file, gs, spc, dump_flags | extra_dump_flags);
if (alt_dump_file && (dump_kind & alt_flags))
print_gimple_expr (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = ensure_pending_optinfo ();
+ info.handle_dump_file_kind (dump_kind);
+ info.add_gimple_expr (gs, spc, dump_flags | extra_dump_flags);
+ }
}
/* Similar to dump_gimple_expr, except additionally print source location. */
void
-dump_gimple_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
- dump_flags_t extra_dump_flags, gimple *gs, int spc)
+dump_context::dump_gimple_expr_loc (dump_flags_t dump_kind,
+ const dump_location_t &loc,
+ dump_flags_t extra_dump_flags,
+ gimple *gs,
+ int spc)
{
location_t srcloc = loc.get_location_t ();
if (dump_file && (dump_kind & pflags))
@@ -532,6 +575,13 @@ dump_gimple_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
dump_loc (dump_kind, alt_dump_file, srcloc);
print_gimple_expr (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
}
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = begin_next_optinfo (loc);
+ info.handle_dump_file_kind (dump_kind);
+ info.add_gimple_expr (gs, spc, dump_flags | extra_dump_flags);
+ }
}
@@ -539,14 +589,22 @@ dump_gimple_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
DUMP_KIND is enabled. */
void
-dump_generic_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
- tree t)
+dump_context::dump_generic_expr (dump_flags_t dump_kind,
+ dump_flags_t extra_dump_flags,
+ tree t)
{
if (dump_file && (dump_kind & pflags))
print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
if (alt_dump_file && (dump_kind & alt_flags))
print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = ensure_pending_optinfo ();
+ info.handle_dump_file_kind (dump_kind);
+ info.add_tree (t, dump_flags | extra_dump_flags);
+ }
}
@@ -554,8 +612,10 @@ dump_generic_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
location. */
void
-dump_generic_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
- dump_flags_t extra_dump_flags, tree t)
+dump_context::dump_generic_expr_loc (dump_flags_t dump_kind,
+ const dump_location_t &loc,
+ dump_flags_t extra_dump_flags,
+ tree t)
{
location_t srcloc = loc.get_location_t ();
if (dump_file && (dump_kind & pflags))
@@ -569,53 +629,83 @@ dump_generic_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
dump_loc (dump_kind, alt_dump_file, srcloc);
print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
}
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = begin_next_optinfo (loc);
+ info.handle_dump_file_kind (dump_kind);
+ info.add_tree (t, dump_flags | extra_dump_flags);
+ }
}
/* Output a formatted message using FORMAT on appropriate dump streams. */
void
-dump_printf (dump_flags_t dump_kind, const char *format, ...)
+dump_context::dump_printf_va (dump_flags_t dump_kind, const char *format,
+ va_list ap)
{
if (dump_file && (dump_kind & pflags))
{
- va_list ap;
- va_start (ap, format);
- vfprintf (dump_file, format, ap);
- va_end (ap);
+ va_list aq;
+ va_copy (aq, ap);
+ vfprintf (dump_file, format, aq);
+ va_end (aq);
}
if (alt_dump_file && (dump_kind & alt_flags))
{
- va_list ap;
- va_start (ap, format);
- vfprintf (alt_dump_file, format, ap);
- va_end (ap);
+ va_list aq;
+ va_copy (aq, ap);
+ vfprintf (alt_dump_file, format, aq);
+ va_end (aq);
+ }
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = ensure_pending_optinfo ();
+ va_list aq;
+ va_copy (aq, ap);
+ info.add_printf_va (format, aq);
+ va_end (aq);
}
}
-/* Similar to dump_printf, except source location is also printed. */
+/* Similar to dump_printf, except source location is also printed, and
+ dump location captured. */
void
-dump_printf_loc (dump_flags_t dump_kind, const dump_location_t &loc,
- const char *format, ...)
+dump_context::dump_printf_loc_va (dump_flags_t dump_kind,
+ const dump_location_t &loc,
+ const char *format, va_list ap)
{
location_t srcloc = loc.get_location_t ();
+
if (dump_file && (dump_kind & pflags))
{
- va_list ap;
dump_loc (dump_kind, dump_file, srcloc);
- va_start (ap, format);
- vfprintf (dump_file, format, ap);
- va_end (ap);
+ va_list aq;
+ va_copy (aq, ap);
+ vfprintf (dump_file, format, aq);
+ va_end (aq);
}
if (alt_dump_file && (dump_kind & alt_flags))
{
- va_list ap;
dump_loc (dump_kind, alt_dump_file, srcloc);
- va_start (ap, format);
- vfprintf (alt_dump_file, format, ap);
- va_end (ap);
+ va_list aq;
+ va_copy (aq, ap);
+ vfprintf (alt_dump_file, format, aq);
+ va_end (aq);
+ }
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = begin_next_optinfo (loc);
+ info.handle_dump_file_kind (dump_kind);
+ va_list aq;
+ va_copy (aq, ap);
+ info.add_printf_va (format, aq);
+ va_end (aq);
}
}
@@ -623,7 +713,7 @@ dump_printf_loc (dump_flags_t dump_kind, const dump_location_t &loc,
template<unsigned int N, typename C>
void
-dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value)
+dump_context::dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value)
{
STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
signop sgn = poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED;
@@ -632,6 +722,224 @@ dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value)
if (alt_dump_file && (dump_kind & alt_flags))
print_dec (value, alt_dump_file, sgn);
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = ensure_pending_optinfo ();
+ info.handle_dump_file_kind (dump_kind);
+ info.add_poly_int<N,C> (value);
+ }
+}
+
+/* Output the name of NODE on appropriate dump streams. */
+
+void
+dump_context::dump_symtab_node (dump_flags_t dump_kind, symtab_node *node)
+{
+ if (dump_file && (dump_kind & pflags))
+ fprintf (dump_file, "%s", node->dump_name ());
+
+ if (alt_dump_file && (dump_kind & alt_flags))
+ fprintf (alt_dump_file, "%s", node->dump_name ());
+
+ if (optinfo_enabled_p ())
+ {
+ optinfo &info = ensure_pending_optinfo ();
+ info.handle_dump_file_kind (dump_kind);
+ info.add_symtab_node (node);
+ }
+}
+
+/* Get the current dump scope-nesting depth.
+ For use by -fopt-info (for showing nesting via indentation). */
+
+unsigned int
+dump_context::get_scope_depth () const
+{
+ return m_scope_depth;
+}
+
+/* Push a nested dump scope.
+ Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
+ destination, if any.
+ Emit a "scope" optinfo if optinfos are enabled.
+ Increment the scope depth. */
+
+void
+dump_context::begin_scope (const char *name, const dump_location_t &loc)
+{
+ /* Specialcase, to avoid going through dump_printf_loc,
+ so that we can create a optinfo of kind OPTINFO_KIND_SCOPE. */
+
+ if (dump_file)
+ {
+ dump_loc (MSG_NOTE, dump_file, loc.get_location_t ());
+ fprintf (dump_file, "=== %s ===\n", name);
+ }
+
+ if (alt_dump_file)
+ {
+ dump_loc (MSG_NOTE, alt_dump_file, loc.get_location_t ());
+ fprintf (alt_dump_file, "=== %s ===\n", name);
+ }
+
+ if (optinfo_enabled_p ())
+ {
+ end_any_optinfo ();
+ optinfo info (loc, OPTINFO_KIND_SCOPE, current_pass);
+ info.add_printf ("=== %s ===", name);
+ info.emit ();
+ }
+
+ m_scope_depth++;
+}
+
+/* Pop a nested dump scope. */
+
+void
+dump_context::end_scope ()
+{
+ end_any_optinfo ();
+ m_scope_depth--;
+}
+
+/* Return the optinfo currently being accumulated, creating one if
+ necessary. */
+
+optinfo &
+dump_context::ensure_pending_optinfo ()
+{
+ if (!m_pending)
+ return begin_next_optinfo (dump_location_t (dump_user_location_t ()));
+ return *m_pending;
+}
+
+/* Start a new optinfo and return it, ending any optinfo that was already
+ accumulated. */
+
+optinfo &
+dump_context::begin_next_optinfo (const dump_location_t &loc)
+{
+ end_any_optinfo ();
+ gcc_assert (m_pending == NULL);
+ m_pending = new optinfo (loc, OPTINFO_KIND_NOTE, current_pass);
+ return *m_pending;
+}
+
+/* End any optinfo that has been accumulated within this context; emitting
+ it to any destinations as appropriate - though none have currently been
+ implemented. */
+
+void
+dump_context::end_any_optinfo ()
+{
+ if (m_pending)
+ m_pending->emit ();
+ delete m_pending;
+ m_pending = NULL;
+}
+
+/* The current singleton dump_context, and its default. */
+
+dump_context *dump_context::s_current = &dump_context::s_default;
+dump_context dump_context::s_default;
+
+/* Implementation of dump_* API calls, calling into dump_context
+ member functions. */
+
+/* Dump gimple statement GS with SPC indentation spaces and
+ EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
+
+void
+dump_gimple_stmt (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
+ gimple *gs, int spc)
+{
+ dump_context::get ().dump_gimple_stmt (dump_kind, extra_dump_flags, gs, spc);
+}
+
+/* Similar to dump_gimple_stmt, except additionally print source location. */
+
+void
+dump_gimple_stmt_loc (dump_flags_t dump_kind, const dump_location_t &loc,
+ dump_flags_t extra_dump_flags, gimple *gs, int spc)
+{
+ dump_context::get ().dump_gimple_stmt_loc (dump_kind, loc, extra_dump_flags,
+ gs, spc);
+}
+
+/* Dump gimple statement GS with SPC indentation spaces and
+ EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.
+ Do not terminate with a newline or semicolon. */
+
+void
+dump_gimple_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
+ gimple *gs, int spc)
+{
+ dump_context::get ().dump_gimple_expr (dump_kind, extra_dump_flags, gs, spc);
+}
+
+/* Similar to dump_gimple_expr, except additionally print source location. */
+
+void
+dump_gimple_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
+ dump_flags_t extra_dump_flags, gimple *gs, int spc)
+{
+ dump_context::get ().dump_gimple_expr_loc (dump_kind, loc, extra_dump_flags,
+ gs, spc);
+}
+
+/* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
+ DUMP_KIND is enabled. */
+
+void
+dump_generic_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
+ tree t)
+{
+ dump_context::get ().dump_generic_expr (dump_kind, extra_dump_flags, t);
+}
+
+/* Similar to dump_generic_expr, except additionally print the source
+ location. */
+
+void
+dump_generic_expr_loc (dump_flags_t dump_kind, const dump_location_t &loc,
+ dump_flags_t extra_dump_flags, tree t)
+{
+ dump_context::get ().dump_generic_expr_loc (dump_kind, loc, extra_dump_flags,
+ t);
+}
+
+/* Output a formatted message using FORMAT on appropriate dump streams. */
+
+void
+dump_printf (dump_flags_t dump_kind, const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ dump_context::get ().dump_printf_va (dump_kind, format, ap);
+ va_end (ap);
+}
+
+/* Similar to dump_printf, except source location is also printed, and
+ dump location captured. */
+
+void
+dump_printf_loc (dump_flags_t dump_kind, const dump_location_t &loc,
+ const char *format, ...)
+{
+ va_list ap;
+ va_start (ap, format);
+ dump_context::get ().dump_printf_loc_va (dump_kind, loc, format, ap);
+ va_end (ap);
+}
+
+/* Output VALUE in decimal to appropriate dump streams. */
+
+template<unsigned int N, typename C>
+void
+dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value)
+{
+ dump_context::get ().dump_dec (dump_kind, value);
}
template void dump_dec (dump_flags_t, const poly_uint16 &);
@@ -662,29 +970,42 @@ dump_hex (dump_flags_t dump_kind, const poly_wide_int &value)
print_hex (value, alt_dump_file);
}
-/* The current dump scope-nesting depth. */
+/* Emit and delete the currently pending optinfo, if there is one,
+ without the caller needing to know about class dump_context. */
+
+void
+dumpfile_ensure_any_optinfo_are_flushed ()
+{
+ dump_context::get().end_any_optinfo ();
+}
+
+/* Output the name of NODE on appropriate dump streams. */
-static int dump_scope_depth;
+void
+dump_symtab_node (dump_flags_t dump_kind, symtab_node *node)
+{
+ dump_context::get ().dump_symtab_node (dump_kind, node);
+}
/* Get the current dump scope-nesting depth.
- For use by dump_*_loc (for showing nesting via indentation). */
+ For use by -fopt-info (for showing nesting via indentation). */
unsigned int
get_dump_scope_depth ()
{
- return dump_scope_depth;
+ return dump_context::get ().get_scope_depth ();
}
/* Push a nested dump scope.
Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
destination, if any.
+ Emit a "scope" opinfo if optinfos are enabled.
Increment the scope depth. */
void
dump_begin_scope (const char *name, const dump_location_t &loc)
{
- dump_printf_loc (MSG_NOTE, loc, "=== %s ===\n", name);
- dump_scope_depth++;
+ dump_context::get ().begin_scope (name, loc);
}
/* Pop a nested dump scope. */
@@ -692,7 +1013,7 @@ dump_begin_scope (const char *name, const dump_location_t &loc)
void
dump_end_scope ()
{
- dump_scope_depth--;
+ dump_context::get ().end_scope ();
}
/* Start a dump for PHASE. Store user-supplied dump flags in
@@ -1249,6 +1570,24 @@ enable_rtl_dump_file (void)
#if CHECKING_P
+/* temp_dump_context's ctor. Temporarily override the dump_context
+ (to forcibly enable optinfo-generation). */
+
+temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo)
+: m_context (),
+ m_saved (&dump_context ().get ())
+{
+ dump_context::s_current = &m_context;
+ m_context.m_forcibly_enable_optinfo = forcibly_enable_optinfo;
+}
+
+/* temp_dump_context's dtor. Restore the saved dump_context. */
+
+temp_dump_context::~temp_dump_context ()
+{
+ dump_context::s_current = m_saved;
+}
+
namespace selftest {
/* Verify that the dump_location_t constructors capture the source location
@@ -1285,12 +1624,188 @@ test_impl_location ()
#endif
}
+/* Verify that ITEM has the expected values. */
+
+static void
+verify_item (const location &loc,
+ const optinfo_item *item,
+ enum optinfo_item_kind expected_kind,
+ location_t expected_location,
+ const char *expected_text)
+{
+ ASSERT_EQ_AT (loc, item->get_kind (), expected_kind);
+ ASSERT_EQ_AT (loc, item->get_location (), expected_location);
+ ASSERT_STREQ_AT (loc, item->get_text (), expected_text);
+}
+
+/* Verify that ITEM is a text item, with EXPECTED_TEXT. */
+
+#define ASSERT_IS_TEXT(ITEM, EXPECTED_TEXT) \
+ SELFTEST_BEGIN_STMT \
+ verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_TEXT, \
+ UNKNOWN_LOCATION, (EXPECTED_TEXT)); \
+ SELFTEST_END_STMT
+
+/* Verify that ITEM is a tree item, with the expected values. */
+
+#define ASSERT_IS_TREE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
+ SELFTEST_BEGIN_STMT \
+ verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_TREE, \
+ (EXPECTED_LOCATION), (EXPECTED_TEXT)); \
+ SELFTEST_END_STMT
+
+/* Verify that ITEM is a gimple item, with the expected values. */
+
+#define ASSERT_IS_GIMPLE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
+ SELFTEST_BEGIN_STMT \
+ verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_GIMPLE, \
+ (EXPECTED_LOCATION), (EXPECTED_TEXT)); \
+ SELFTEST_END_STMT
+
+/* Verify that calls to the dump_* API are captured and consolidated into
+ optimization records. */
+
+static void
+test_capture_of_dump_calls (const line_table_case &case_)
+{
+ /* Generate a location_t for testing. */
+ line_table_test ltt (case_);
+ linemap_add (line_table, LC_ENTER, false, "test.txt", 0);
+ linemap_line_start (line_table, 5, 100);
+ linemap_add (line_table, LC_LEAVE, false, NULL, 0);
+ location_t where = linemap_position_for_column (line_table, 10);
+
+ dump_location_t loc = dump_location_t::from_location_t (where);
+
+ /* Test of dump_printf. */
+ {
+ temp_dump_context tmp (true);
+ dump_printf (MSG_NOTE, "int: %i str: %s", 42, "foo");
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
+ ASSERT_EQ (info->num_items (), 1);
+ ASSERT_IS_TEXT (info->get_item (0), "int: 42 str: foo");
+ }
+
+ /* Tree, via dump_generic_expr. */
+ {
+ temp_dump_context tmp (true);
+ dump_printf_loc (MSG_NOTE, loc, "test of tree: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, integer_zero_node);
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->get_location_t (), where);
+ ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
+ ASSERT_EQ (info->num_items (), 2);
+ ASSERT_IS_TEXT (info->get_item (0), "test of tree: ");
+ ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
+ }
+
+ /* Tree, via dump_generic_expr_loc. */
+ {
+ temp_dump_context tmp (true);
+ dump_generic_expr_loc (MSG_NOTE, loc, TDF_SLIM, integer_one_node);
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->get_location_t (), where);
+ ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
+ ASSERT_EQ (info->num_items (), 1);
+ ASSERT_IS_TREE (info->get_item (0), UNKNOWN_LOCATION, "1");
+ }
+
+ /* Gimple. */
+ {
+ greturn *stmt = gimple_build_return (NULL);
+ gimple_set_location (stmt, where);
+
+ /* dump_gimple_stmt_loc. */
+ {
+ temp_dump_context tmp (true);
+ dump_gimple_stmt_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->num_items (), 1);
+ ASSERT_IS_GIMPLE (info->get_item (0), where, "return;\n");
+ }
+
+ /* dump_gimple_stmt. */
+ {
+ temp_dump_context tmp (true);
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 2);
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->num_items (), 1);
+ ASSERT_IS_GIMPLE (info->get_item (0), where, "return;\n");
+ }
+
+ /* dump_gimple_expr_loc. */
+ {
+ temp_dump_context tmp (true);
+ dump_gimple_expr_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->num_items (), 1);
+ ASSERT_IS_GIMPLE (info->get_item (0), where, "return;");
+ }
+
+ /* dump_gimple_expr. */
+ {
+ temp_dump_context tmp (true);
+ dump_gimple_expr (MSG_NOTE, TDF_SLIM, stmt, 2);
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->num_items (), 1);
+ ASSERT_IS_GIMPLE (info->get_item (0), where, "return;");
+ }
+ }
+
+ /* poly_int. */
+ {
+ temp_dump_context tmp (true);
+ dump_dec (MSG_NOTE, poly_int64 (42));
+
+ optinfo *info = tmp.get_pending_optinfo ();
+ ASSERT_TRUE (info != NULL);
+ ASSERT_EQ (info->num_items (), 1);
+ ASSERT_IS_TEXT (info->get_item (0), "42");
+ }
+
+ /* Verify that MSG_* affects optinfo->get_kind (); we tested MSG_NOTE
+ above. */
+ {
+ /* MSG_OPTIMIZED_LOCATIONS. */
+ {
+ temp_dump_context tmp (true);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, "test");
+ ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
+ OPTINFO_KIND_SUCCESS);
+ }
+
+ /* MSG_MISSED_OPTIMIZATION. */
+ {
+ temp_dump_context tmp (true);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, "test");
+ ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
+ OPTINFO_KIND_FAILURE);
+ }
+ }
+}
+
/* Run all of the selftests within this file. */
void
dumpfile_c_tests ()
{
test_impl_location ();
+ for_each_line_table_case (test_capture_of_dump_calls);
}
} // namespace selftest