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
This commit is contained in:
parent
30c4605355
commit
4df3629eb7
|
@ -1,3 +1,77 @@
|
|||
2018-07-19 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2018-07-19 Michael Collison <michael.collison@arm.com>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
|
||||
|
|
|
@ -1427,6 +1427,7 @@ OBJS = \
|
|||
optabs-libfuncs.o \
|
||||
optabs-query.o \
|
||||
optabs-tree.o \
|
||||
optinfo.o \
|
||||
options-save.o \
|
||||
opts-global.o \
|
||||
passes.o \
|
||||
|
|
|
@ -134,6 +134,13 @@ struct gomp_single;
|
|||
struct gomp_target;
|
||||
struct gomp_teams;
|
||||
|
||||
/* Subclasses of symtab_node, using indentation to show the class
|
||||
hierarchy. */
|
||||
|
||||
class symtab_node;
|
||||
struct cgraph_node;
|
||||
class varpool_node;
|
||||
|
||||
union section;
|
||||
typedef union section section;
|
||||
struct gcc_options;
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/* Support code for handling the various dump_* calls in dumpfile.h
|
||||
Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
Contributed by David Malcolm <dmalcolm@redhat.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#ifndef GCC_DUMP_CONTEXT_H
|
||||
#define GCC_DUMP_CONTEXT_H 1
|
||||
|
||||
/* A class for handling the various dump_* calls.
|
||||
|
||||
In particular, this class has responsibility for consolidating
|
||||
the "dump_*" calls into optinfo instances (delimited by "dump_*_loc"
|
||||
calls), and emitting them.
|
||||
|
||||
Putting this in a class (rather than as global state) allows
|
||||
for selftesting of this code. */
|
||||
|
||||
class dump_context
|
||||
{
|
||||
friend class temp_dump_context;
|
||||
public:
|
||||
static dump_context &get () { return *s_current; }
|
||||
|
||||
~dump_context ();
|
||||
|
||||
void dump_gimple_stmt (dump_flags_t dump_kind, dump_flags_t extra_dump_flags,
|
||||
gimple *gs, int spc);
|
||||
|
||||
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);
|
||||
|
||||
void dump_gimple_expr (dump_flags_t dump_kind,
|
||||
dump_flags_t extra_dump_flags,
|
||||
gimple *gs, int spc);
|
||||
|
||||
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);
|
||||
|
||||
void dump_generic_expr (dump_flags_t dump_kind,
|
||||
dump_flags_t extra_dump_flags,
|
||||
tree t);
|
||||
|
||||
void dump_generic_expr_loc (dump_flags_t dump_kind,
|
||||
const dump_location_t &loc,
|
||||
dump_flags_t extra_dump_flags,
|
||||
tree t);
|
||||
|
||||
void dump_printf_va (dump_flags_t dump_kind, const char *format,
|
||||
va_list ap) ATTRIBUTE_PRINTF (3, 0);
|
||||
|
||||
void dump_printf_loc_va (dump_flags_t dump_kind, const dump_location_t &loc,
|
||||
const char *format, va_list ap)
|
||||
ATTRIBUTE_PRINTF (4, 0);
|
||||
|
||||
template<unsigned int N, typename C>
|
||||
void dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value);
|
||||
|
||||
void dump_symtab_node (dump_flags_t dump_kind, symtab_node *node);
|
||||
|
||||
/* Managing nested scopes. */
|
||||
unsigned int get_scope_depth () const;
|
||||
void begin_scope (const char *name, const dump_location_t &loc);
|
||||
void end_scope ();
|
||||
|
||||
/* For use in selftests; if true then optinfo_enabled_p is true. */
|
||||
bool forcibly_enable_optinfo_p () const
|
||||
{
|
||||
return m_forcibly_enable_optinfo;
|
||||
}
|
||||
|
||||
void end_any_optinfo ();
|
||||
|
||||
private:
|
||||
optinfo &ensure_pending_optinfo ();
|
||||
optinfo &begin_next_optinfo (const dump_location_t &loc);
|
||||
|
||||
/* For use in selftests; if true then optinfo_enabled_p is true. */
|
||||
bool m_forcibly_enable_optinfo;
|
||||
|
||||
/* The current nesting depth of dump scopes, for showing nesting
|
||||
via indentation). */
|
||||
unsigned int m_scope_depth;
|
||||
|
||||
/* The optinfo currently being accumulated since the last dump_*_loc call,
|
||||
if any. */
|
||||
optinfo *m_pending;
|
||||
|
||||
/* The currently active dump_context, for use by the dump_* API calls. */
|
||||
static dump_context *s_current;
|
||||
|
||||
/* The default active context. */
|
||||
static dump_context s_default;
|
||||
};
|
||||
|
||||
#if CHECKING_P
|
||||
|
||||
/* An RAII-style class for use in selftests for temporarily using a different
|
||||
dump_context. */
|
||||
|
||||
class temp_dump_context
|
||||
{
|
||||
public:
|
||||
temp_dump_context (bool forcibly_enable_optinfo);
|
||||
~temp_dump_context ();
|
||||
|
||||
/* Support for selftests. */
|
||||
optinfo *get_pending_optinfo () const { return m_context.m_pending; }
|
||||
|
||||
private:
|
||||
dump_context m_context;
|
||||
dump_context *m_saved;
|
||||
bool m_saved_flag_remarks;
|
||||
};
|
||||
|
||||
#endif /* CHECKING_P */
|
||||
|
||||
#endif /* GCC_DUMP_CONTEXT_H */
|
597
gcc/dumpfile.c
597
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. */
|
||||
|
||||
static int dump_scope_depth;
|
||||
void
|
||||
dumpfile_ensure_any_optinfo_are_flushed ()
|
||||
{
|
||||
dump_context::get().end_any_optinfo ();
|
||||
}
|
||||
|
||||
/* Output the name of NODE on appropriate dump streams. */
|
||||
|
||||
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
|
||||
|
|
|
@ -420,35 +420,6 @@ extern FILE *dump_begin (int, dump_flags_t *, int part=-1);
|
|||
extern void dump_end (int, FILE *);
|
||||
extern int opt_info_switch_p (const char *);
|
||||
extern const char *dump_flag_name (int);
|
||||
extern void dump_printf (dump_flags_t, const char *, ...) ATTRIBUTE_PRINTF_2;
|
||||
extern void dump_printf_loc (dump_flags_t, const dump_location_t &,
|
||||
const char *, ...) ATTRIBUTE_PRINTF_3;
|
||||
extern void dump_function (int phase, tree fn);
|
||||
extern void dump_basic_block (dump_flags_t, basic_block, int);
|
||||
extern void dump_generic_expr_loc (dump_flags_t, const dump_location_t &,
|
||||
dump_flags_t, tree);
|
||||
extern void dump_generic_expr (dump_flags_t, dump_flags_t, tree);
|
||||
extern void dump_gimple_stmt_loc (dump_flags_t, const dump_location_t &,
|
||||
dump_flags_t, gimple *, int);
|
||||
extern void dump_gimple_stmt (dump_flags_t, dump_flags_t, gimple *, int);
|
||||
extern void dump_gimple_expr_loc (dump_flags_t, const dump_location_t &,
|
||||
dump_flags_t, gimple *, int);
|
||||
extern void dump_gimple_expr (dump_flags_t, dump_flags_t, gimple *, int);
|
||||
extern void print_combine_total_stats (void);
|
||||
extern bool enable_rtl_dump_file (void);
|
||||
|
||||
template<unsigned int N, typename C>
|
||||
void dump_dec (dump_flags_t, const poly_int<N, C> &);
|
||||
extern void dump_dec (dump_flags_t, const poly_wide_int &, signop);
|
||||
extern void dump_hex (dump_flags_t, const poly_wide_int &);
|
||||
|
||||
/* In tree-dump.c */
|
||||
extern void dump_node (const_tree, dump_flags_t, FILE *);
|
||||
|
||||
/* In combine.c */
|
||||
extern void dump_combine_total_stats (FILE *);
|
||||
/* In cfghooks.c */
|
||||
extern void dump_bb (FILE *, basic_block, int, dump_flags_t);
|
||||
|
||||
/* Global variables used to communicate with passes. */
|
||||
extern FILE *dump_file;
|
||||
|
@ -466,6 +437,54 @@ dump_enabled_p (void)
|
|||
return dumps_are_enabled;
|
||||
}
|
||||
|
||||
/* The following API calls (which *don't* take a "FILE *")
|
||||
write the output to zero or more locations:
|
||||
(a) the active dump_file, if any
|
||||
(b) the -fopt-info destination, if any
|
||||
(c) to the "optinfo" destinations, if any:
|
||||
|
||||
dump_* (MSG_*) --> dumpfile.c --+--> (a) dump_file
|
||||
|
|
||||
+--> (b) alt_dump_file
|
||||
|
|
||||
`--> (c) optinfo
|
||||
`---> optinfo destinations
|
||||
|
||||
For optinfos, the dump_*_loc mark the beginning of an optinfo
|
||||
instance: all subsequent dump_* calls are consolidated into
|
||||
that optinfo, until the next dump_*_loc call (or a change in
|
||||
dump scope, or a call to dumpfile_ensure_any_optinfo_are_flushed).
|
||||
|
||||
A group of dump_* calls should be guarded by:
|
||||
|
||||
if (dump_enabled_p ())
|
||||
|
||||
to minimize the work done for the common case where dumps
|
||||
are disabled. */
|
||||
|
||||
extern void dump_printf (dump_flags_t, const char *, ...) ATTRIBUTE_PRINTF_2;
|
||||
extern void dump_printf_loc (dump_flags_t, const dump_location_t &,
|
||||
const char *, ...) ATTRIBUTE_PRINTF_3;
|
||||
extern void dump_function (int phase, tree fn);
|
||||
extern void dump_basic_block (dump_flags_t, basic_block, int);
|
||||
extern void dump_generic_expr_loc (dump_flags_t, const dump_location_t &,
|
||||
dump_flags_t, tree);
|
||||
extern void dump_generic_expr (dump_flags_t, dump_flags_t, tree);
|
||||
extern void dump_gimple_stmt_loc (dump_flags_t, const dump_location_t &,
|
||||
dump_flags_t, gimple *, int);
|
||||
extern void dump_gimple_stmt (dump_flags_t, dump_flags_t, gimple *, int);
|
||||
extern void dump_gimple_expr_loc (dump_flags_t, const dump_location_t &,
|
||||
dump_flags_t, gimple *, int);
|
||||
extern void dump_gimple_expr (dump_flags_t, dump_flags_t, gimple *, int);
|
||||
extern void dump_symtab_node (dump_flags_t, symtab_node *);
|
||||
|
||||
template<unsigned int N, typename C>
|
||||
void dump_dec (dump_flags_t, const poly_int<N, C> &);
|
||||
extern void dump_dec (dump_flags_t, const poly_wide_int &, signop);
|
||||
extern void dump_hex (dump_flags_t, const poly_wide_int &);
|
||||
|
||||
extern void dumpfile_ensure_any_optinfo_are_flushed ();
|
||||
|
||||
/* Managing nested scopes, so that dumps can express the call chain
|
||||
leading to a dump message. */
|
||||
|
||||
|
@ -505,8 +524,23 @@ class auto_dump_scope
|
|||
#define AUTO_DUMP_SCOPE(NAME, LOC) \
|
||||
auto_dump_scope scope (NAME, LOC)
|
||||
|
||||
extern void dump_function (int phase, tree fn);
|
||||
extern void print_combine_total_stats (void);
|
||||
extern bool enable_rtl_dump_file (void);
|
||||
|
||||
/* In tree-dump.c */
|
||||
extern void dump_node (const_tree, dump_flags_t, FILE *);
|
||||
|
||||
/* In combine.c */
|
||||
extern void dump_combine_total_stats (FILE *);
|
||||
/* In cfghooks.c */
|
||||
extern void dump_bb (FILE *, basic_block, int, dump_flags_t);
|
||||
|
||||
namespace gcc {
|
||||
|
||||
/* A class for managing all of the various dump files used by the
|
||||
optimization passes. */
|
||||
|
||||
class dump_manager
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
/* Optimization information.
|
||||
Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
Contributed by David Malcolm <dmalcolm@redhat.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
|
||||
#include "backend.h"
|
||||
#include "tree.h"
|
||||
#include "gimple.h"
|
||||
|
||||
#include "optinfo.h"
|
||||
#include "dump-context.h"
|
||||
#include "pretty-print.h"
|
||||
#include "gimple-pretty-print.h"
|
||||
#include "cgraph.h"
|
||||
#include "selftest.h"
|
||||
|
||||
/* optinfo_item's ctor. */
|
||||
|
||||
optinfo_item::optinfo_item (enum optinfo_item_kind kind, location_t location,
|
||||
char *text, bool owned)
|
||||
: m_kind (kind), m_location (location), m_text (text), m_owned (owned)
|
||||
{
|
||||
}
|
||||
|
||||
/* optinfo_item's dtor. */
|
||||
|
||||
optinfo_item::~optinfo_item ()
|
||||
{
|
||||
if (m_owned)
|
||||
free (m_text);
|
||||
}
|
||||
|
||||
/* Get a string from KIND. */
|
||||
|
||||
const char *
|
||||
optinfo_kind_to_string (enum optinfo_kind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
case OPTINFO_KIND_SUCCESS:
|
||||
return "success";
|
||||
case OPTINFO_KIND_FAILURE:
|
||||
return "failure";
|
||||
case OPTINFO_KIND_NOTE:
|
||||
return "note";
|
||||
case OPTINFO_KIND_SCOPE:
|
||||
return "scope";
|
||||
}
|
||||
}
|
||||
|
||||
/* optinfo's dtor. */
|
||||
|
||||
optinfo::~optinfo ()
|
||||
{
|
||||
/* Cleanup. */
|
||||
unsigned i;
|
||||
optinfo_item *item;
|
||||
FOR_EACH_VEC_ELT (m_items, i, item)
|
||||
delete item;
|
||||
}
|
||||
|
||||
/* Emit the optinfo to all of the active destinations. */
|
||||
|
||||
void
|
||||
optinfo::emit ()
|
||||
{
|
||||
/* currently this is a no-op. */
|
||||
}
|
||||
|
||||
/* Update the optinfo's kind based on DUMP_KIND. */
|
||||
|
||||
void
|
||||
optinfo::handle_dump_file_kind (dump_flags_t dump_kind)
|
||||
{
|
||||
if (dump_kind & MSG_OPTIMIZED_LOCATIONS)
|
||||
m_kind = OPTINFO_KIND_SUCCESS;
|
||||
else if (dump_kind & MSG_MISSED_OPTIMIZATION)
|
||||
m_kind = OPTINFO_KIND_FAILURE;
|
||||
else if (dump_kind & MSG_NOTE)
|
||||
m_kind = OPTINFO_KIND_NOTE;
|
||||
}
|
||||
|
||||
/* Append a string literal to this optinfo. */
|
||||
|
||||
void
|
||||
optinfo::add_string (const char *str)
|
||||
{
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
|
||||
const_cast <char *> (str), false);
|
||||
m_items.safe_push (item);
|
||||
}
|
||||
|
||||
/* Append printf-formatted text to this optinfo. */
|
||||
|
||||
void
|
||||
optinfo::add_printf (const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, format);
|
||||
add_printf_va (format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
/* Append printf-formatted text to this optinfo. */
|
||||
|
||||
void
|
||||
optinfo::add_printf_va (const char *format, va_list ap)
|
||||
{
|
||||
char *formatted_text = xvasprintf (format, ap);
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
|
||||
formatted_text, true);
|
||||
m_items.safe_push (item);
|
||||
}
|
||||
|
||||
/* Append a gimple statement to this optinfo, equivalent to
|
||||
print_gimple_stmt. */
|
||||
|
||||
void
|
||||
optinfo::add_gimple_stmt (gimple *stmt, int spc, dump_flags_t dump_flags)
|
||||
{
|
||||
pretty_printer pp;
|
||||
pp_needs_newline (&pp) = true;
|
||||
pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);
|
||||
pp_newline (&pp);
|
||||
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_GIMPLE, gimple_location (stmt),
|
||||
xstrdup (pp_formatted_text (&pp)), true);
|
||||
m_items.safe_push (item);
|
||||
}
|
||||
|
||||
/* Append a gimple statement to this optinfo, equivalent to
|
||||
print_gimple_expr. */
|
||||
|
||||
void
|
||||
optinfo::add_gimple_expr (gimple *stmt, int spc, dump_flags_t dump_flags)
|
||||
{
|
||||
dump_flags |= TDF_RHS_ONLY;
|
||||
pretty_printer pp;
|
||||
pp_needs_newline (&pp) = true;
|
||||
pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);
|
||||
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_GIMPLE, gimple_location (stmt),
|
||||
xstrdup (pp_formatted_text (&pp)), true);
|
||||
m_items.safe_push (item);
|
||||
}
|
||||
|
||||
/* Append a tree node to this optinfo, equivalent to print_generic_expr. */
|
||||
|
||||
void
|
||||
optinfo::add_tree (tree node, dump_flags_t dump_flags)
|
||||
{
|
||||
pretty_printer pp;
|
||||
pp_needs_newline (&pp) = true;
|
||||
pp_translate_identifiers (&pp) = false;
|
||||
dump_generic_node (&pp, node, 0, dump_flags, false);
|
||||
|
||||
location_t loc = UNKNOWN_LOCATION;
|
||||
if (EXPR_HAS_LOCATION (node))
|
||||
loc = EXPR_LOCATION (node);
|
||||
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_TREE, loc,
|
||||
xstrdup (pp_formatted_text (&pp)), true);
|
||||
m_items.safe_push (item);
|
||||
}
|
||||
|
||||
/* Append a symbol table node to this optinfo. */
|
||||
|
||||
void
|
||||
optinfo::add_symtab_node (symtab_node *node)
|
||||
{
|
||||
location_t loc = DECL_SOURCE_LOCATION (node->decl);
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_SYMTAB_NODE, loc,
|
||||
xstrdup (node->dump_name ()), true);
|
||||
m_items.safe_push (item);
|
||||
}
|
||||
|
||||
/* Append the decimal represenation of a wide_int_ref to this
|
||||
optinfo. */
|
||||
|
||||
void
|
||||
optinfo::add_dec (const wide_int_ref &wi, signop sgn)
|
||||
{
|
||||
char buf[WIDE_INT_PRINT_BUFFER_SIZE];
|
||||
print_dec (wi, buf, sgn);
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
|
||||
xstrdup (buf), true);
|
||||
m_items.safe_push (item);
|
||||
}
|
||||
|
||||
/* Should optinfo instances be created?
|
||||
All creation of optinfos should be guarded by this predicate.
|
||||
Return true if any optinfo destinations are active. */
|
||||
|
||||
bool optinfo_enabled_p ()
|
||||
{
|
||||
/* Currently no destinations are implemented, just a hook for
|
||||
selftests. */
|
||||
return dump_context::get ().forcibly_enable_optinfo_p ();
|
||||
}
|
||||
|
||||
/* Return true if any of the active optinfo destinations make use
|
||||
of inlining information.
|
||||
(if true, then the information is preserved). */
|
||||
|
||||
bool optinfo_wants_inlining_info_p ()
|
||||
{
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/* Optimization information.
|
||||
Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
Contributed by David Malcolm <dmalcolm@redhat.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_OPTINFO_H
|
||||
#define GCC_OPTINFO_H
|
||||
|
||||
/* An "optinfo" is a bundle of information describing part of an
|
||||
optimization, which can be emitted to zero or more of several
|
||||
destinations, such as:
|
||||
|
||||
* as a "remark" through the diagnostics subsystem
|
||||
|
||||
* saved to a file as an "optimization record"
|
||||
|
||||
Currently no such destinations are implemented.
|
||||
|
||||
They are generated in response to calls to the "dump_*" API in
|
||||
dumpfile.h; repeated calls to the "dump_*" API are consolidated
|
||||
into a pending optinfo instance, with a "dump_*_loc" starting a new
|
||||
optinfo instance.
|
||||
|
||||
The data sent to the dump calls are captured within the pending optinfo
|
||||
instance as a sequence of optinfo_items. For example, given:
|
||||
|
||||
if (dump_enabled_p ())
|
||||
{
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"not vectorized: live stmt not supported: ");
|
||||
dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
|
||||
}
|
||||
|
||||
the "dump_printf_loc" call begins a new optinfo containing two items:
|
||||
(1) a text item containing "not vectorized: live stmt not supported: "
|
||||
(2) a gimple item for "stmt"
|
||||
|
||||
Dump destinations are thus able to access rich metadata about the
|
||||
items when the optinfo is emitted to them, rather than just having plain
|
||||
text. For example, when saving the above optinfo to a file as an
|
||||
"optimization record", the record could capture the source location of
|
||||
"stmt" above, rather than just its textual form.
|
||||
|
||||
The currently pending optinfo is emitted and deleted:
|
||||
* each time a "dump_*_loc" call occurs (which starts the next optinfo), or
|
||||
* when the dump files are changed (at the end of a pass)
|
||||
|
||||
Dumping to an optinfo instance is non-trivial (due to building optinfo_item
|
||||
instances), so all usage should be guarded by
|
||||
|
||||
if (optinfo_enabled_p ())
|
||||
|
||||
which is off by default. */
|
||||
|
||||
|
||||
/* Forward decls. */
|
||||
struct opt_pass;
|
||||
class optinfo_item;
|
||||
|
||||
/* Should optinfo instances be created?
|
||||
All creation of optinfos should be guarded by this predicate.
|
||||
Return true if any optinfo destinations are active. */
|
||||
|
||||
extern bool optinfo_enabled_p ();
|
||||
|
||||
/* Return true if any of the active optinfo destinations make use
|
||||
of inlining information.
|
||||
(if true, then the information is preserved). */
|
||||
|
||||
extern bool optinfo_wants_inlining_info_p ();
|
||||
|
||||
/* The various kinds of optinfo. */
|
||||
|
||||
enum optinfo_kind
|
||||
{
|
||||
OPTINFO_KIND_SUCCESS,
|
||||
OPTINFO_KIND_FAILURE,
|
||||
OPTINFO_KIND_NOTE,
|
||||
OPTINFO_KIND_SCOPE
|
||||
};
|
||||
|
||||
extern const char *optinfo_kind_to_string (enum optinfo_kind kind);
|
||||
|
||||
/* A bundle of information describing part of an optimization. */
|
||||
|
||||
class optinfo
|
||||
{
|
||||
friend class dump_context;
|
||||
|
||||
public:
|
||||
optinfo (const dump_location_t &loc,
|
||||
enum optinfo_kind kind,
|
||||
opt_pass *pass)
|
||||
: m_loc (loc), m_kind (kind), m_pass (pass), m_items ()
|
||||
{}
|
||||
~optinfo ();
|
||||
|
||||
const dump_user_location_t &
|
||||
get_user_location () const { return m_loc.get_user_location (); }
|
||||
|
||||
const dump_impl_location_t &
|
||||
get_impl_location () const { return m_loc.get_impl_location (); }
|
||||
|
||||
enum optinfo_kind get_kind () const { return m_kind; }
|
||||
opt_pass *get_pass () const { return m_pass; }
|
||||
unsigned int num_items () const { return m_items.length (); }
|
||||
const optinfo_item *get_item (unsigned int i) const { return m_items[i]; }
|
||||
|
||||
location_t get_location_t () const { return m_loc.get_location_t (); }
|
||||
profile_count get_count () const { return m_loc.get_count (); }
|
||||
|
||||
private:
|
||||
void emit ();
|
||||
|
||||
/* Pre-canned ways of manipulating the optinfo, for use by friend class
|
||||
dump_context. */
|
||||
void handle_dump_file_kind (dump_flags_t);
|
||||
void add_string (const char *str);
|
||||
void add_printf (const char *format, ...) ATTRIBUTE_PRINTF_2;
|
||||
void add_printf_va (const char *format, va_list ap) ATTRIBUTE_PRINTF (2, 0);
|
||||
void add_gimple_stmt (gimple *stmt, int spc, dump_flags_t dump_flags);
|
||||
void add_gimple_expr (gimple *stmt, int spc, dump_flags_t dump_flags);
|
||||
void add_tree (tree node, dump_flags_t dump_flags);
|
||||
void add_symtab_node (symtab_node *node);
|
||||
void add_dec (const wide_int_ref &wi, signop sgn);
|
||||
|
||||
template<unsigned int N, typename C>
|
||||
void add_poly_int (const poly_int<N, C> &value)
|
||||
{
|
||||
/* Compare with dump_dec (MSG_NOTE, ). */
|
||||
|
||||
STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
|
||||
signop sgn = poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED;
|
||||
|
||||
if (value.is_constant ())
|
||||
add_dec (value.coeffs[0], sgn);
|
||||
else
|
||||
{
|
||||
add_string ("[");
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
{
|
||||
add_dec (value.coeffs[i], sgn);
|
||||
add_string (i == N - 1 ? "]" : ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
dump_location_t m_loc;
|
||||
enum optinfo_kind m_kind;
|
||||
opt_pass *m_pass;
|
||||
auto_vec <optinfo_item *> m_items;
|
||||
};
|
||||
|
||||
/* An enum for discriminating between different kinds of optinfo_item. */
|
||||
|
||||
enum optinfo_item_kind
|
||||
{
|
||||
OPTINFO_ITEM_KIND_TEXT,
|
||||
OPTINFO_ITEM_KIND_TREE,
|
||||
OPTINFO_ITEM_KIND_GIMPLE,
|
||||
OPTINFO_ITEM_KIND_SYMTAB_NODE
|
||||
};
|
||||
|
||||
/* An item within an optinfo. */
|
||||
|
||||
class optinfo_item
|
||||
{
|
||||
public:
|
||||
optinfo_item (enum optinfo_item_kind kind, location_t location,
|
||||
char *text, bool owned);
|
||||
~optinfo_item ();
|
||||
|
||||
enum optinfo_item_kind get_kind () const { return m_kind; }
|
||||
location_t get_location () const { return m_location; }
|
||||
const char *get_text () const { return m_text; }
|
||||
|
||||
private:
|
||||
/* Metadata (e.g. for optimization records). */
|
||||
enum optinfo_item_kind m_kind;
|
||||
location_t m_location;
|
||||
|
||||
/* The textual form of the item. */
|
||||
char *m_text;
|
||||
bool m_owned;
|
||||
};
|
||||
|
||||
#endif /* #ifndef GCC_OPTINFO_H */
|
Loading…
Reference in New Issue