/* Definitions for the shared dumpfile.
- Copyright (C) 2004-2018 Free Software Foundation, Inc.
+ Copyright (C) 2004-2021 Free Software Foundation, Inc.
This file is part of GCC.
#ifndef GCC_DUMPFILE_H
#define GCC_DUMPFILE_H 1
+#include "profile-count.h"
+
+/* An attribute for annotating formatting printing functions that use
+ the dumpfile/optinfo formatting codes. These are the pretty_printer
+ format codes (see pretty-print.c), with additional codes for middle-end
+ specific entities (see dumpfile.c). */
+
+#if GCC_VERSION >= 9000
+#define ATTRIBUTE_GCC_DUMP_PRINTF(m, n) \
+ __attribute__ ((__format__ (__gcc_dump_printf__, m ,n))) \
+ ATTRIBUTE_NONNULL(m)
+#else
+#define ATTRIBUTE_GCC_DUMP_PRINTF(m, n) ATTRIBUTE_NONNULL(m)
+#endif
/* Different tree dump places. When you add new tree dump places,
extend the DUMP_FILES array in dumpfile.c. */
TDI_original, /* dump each function before optimizing it */
TDI_gimple, /* dump each function after gimplifying it */
TDI_nested, /* dump each function after unnesting it */
+ TDI_lto_stream_out, /* dump information about lto streaming */
+ TDI_profile_report, /* dump information about profile quality */
TDI_lang_all, /* enable all the language dumps. */
TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */
/* Dump folding details. */
TDF_FOLDING = (1 << 21),
+ /* MSG_* flags for expressing the kinds of message to
+ be emitted by -fopt-info. */
+
/* -fopt-info optimized sources. */
MSG_OPTIMIZED_LOCATIONS = (1 << 22),
/* General optimization info. */
MSG_NOTE = (1 << 24),
- MSG_ALL = (MSG_OPTIMIZED_LOCATIONS
- | MSG_MISSED_OPTIMIZATION
- | MSG_NOTE),
+ /* Mask for selecting MSG_-kind flags. */
+ MSG_ALL_KINDS = (MSG_OPTIMIZED_LOCATIONS
+ | MSG_MISSED_OPTIMIZATION
+ | MSG_NOTE),
+
+ /* MSG_PRIORITY_* flags for expressing the priority levels of message
+ to be emitted by -fopt-info, and filtering on them.
+ By default, messages at the top-level dump scope are "user-facing",
+ whereas those that are in nested scopes are implicitly "internals".
+ This behavior can be overridden for a given dump message by explicitly
+ specifying one of the MSG_PRIORITY_* flags.
+
+ By default, dump files show both kinds of message, whereas -fopt-info
+ only shows "user-facing" messages, and requires the "-internals"
+ sub-option of -fopt-info to show the internal messages. */
+
+ /* Implicitly supplied for messages at the top-level dump scope. */
+ MSG_PRIORITY_USER_FACING = (1 << 25),
+
+ /* Implicitly supplied for messages within nested dump scopes. */
+ MSG_PRIORITY_INTERNALS = (1 << 26),
+
+ /* Supplied when an opt_problem generated in a nested scope is re-emitted
+ at the top-level. We want to default to showing these in -fopt-info
+ output, but to *not* show them in dump files, as the message would be
+ shown twice, messing up "scan-tree-dump-times" in DejaGnu tests. */
+ MSG_PRIORITY_REEMITTED = (1 << 27),
+
+ /* Mask for selecting MSG_PRIORITY_* flags. */
+ MSG_ALL_PRIORITIES = (MSG_PRIORITY_USER_FACING
+ | MSG_PRIORITY_INTERNALS
+ | MSG_PRIORITY_REEMITTED),
/* Dumping for -fcompare-debug. */
- TDF_COMPARE_DEBUG = (1 << 25)
+ TDF_COMPARE_DEBUG = (1 << 28),
+
+ /* For error. */
+ TDF_ERROR = (1 << 26),
+
+ /* All values. */
+ TDF_ALL_VALUES = (1 << 29) - 1
};
/* Dump flags type. */
bool graph_dump_initialized;
};
+/* A class for describing where in the user's source that a dump message
+ relates to, with various constructors for convenience.
+ In particular, this lets us associate dump messages
+ with hotness information (e.g. from PGO), allowing them to
+ be prioritized by code hotness. */
+
+class dump_user_location_t
+{
+ public:
+ /* Default constructor, analogous to UNKNOWN_LOCATION. */
+ dump_user_location_t () : m_count (), m_loc (UNKNOWN_LOCATION) {}
+
+ /* Construct from a gimple statement (using its location and hotness). */
+ dump_user_location_t (const gimple *stmt);
+
+ /* Construct from an RTL instruction (using its location and hotness). */
+ dump_user_location_t (const rtx_insn *insn);
+
+ /* Construct from a location_t. This one is deprecated (since it doesn't
+ capture hotness information); it thus needs to be spelled out. */
+ static dump_user_location_t
+ from_location_t (location_t loc)
+ {
+ return dump_user_location_t (profile_count (), loc);
+ }
+
+ /* Construct from a function declaration. This one requires spelling out
+ to avoid accidentally constructing from other kinds of tree. */
+ static dump_user_location_t
+ from_function_decl (tree fndecl);
+
+ profile_count get_count () const { return m_count; }
+ location_t get_location_t () const { return m_loc; }
+
+ private:
+ /* Private ctor from count and location, for use by from_location_t. */
+ dump_user_location_t (profile_count count, location_t loc)
+ : m_count (count), m_loc (loc)
+ {}
+
+ profile_count m_count;
+ location_t m_loc;
+};
+
+/* A class for identifying where in the compiler's own source
+ (or a plugin) that a dump message is being emitted from. */
+
+class dump_impl_location_t
+{
+public:
+ dump_impl_location_t (
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ const char *file = __builtin_FILE (),
+ int line = __builtin_LINE (),
+ const char *function = __builtin_FUNCTION ()
+#else
+ const char *file = __FILE__,
+ int line = __LINE__,
+ const char *function = NULL
+#endif
+ )
+ : m_file (file), m_line (line), m_function (function)
+ {}
+
+ const char *m_file;
+ int m_line;
+ const char *m_function;
+};
+
+/* A bundle of metadata for describing a dump message:
+ (a) the dump_flags
+ (b) the source location within the compiler/plugin.
+
+ The constructors use default parameters so that (b) gets sets up
+ automatically.
+
+ Hence you can pass in e.g. MSG_NOTE, and the dump call
+ will automatically record where in GCC's source code the
+ dump was emitted from. */
+
+class dump_metadata_t
+{
+ public:
+ dump_metadata_t (dump_flags_t dump_flags,
+ const dump_impl_location_t &impl_location
+ = dump_impl_location_t ())
+ : m_dump_flags (dump_flags),
+ m_impl_location (impl_location)
+ {
+ }
+
+ dump_flags_t get_dump_flags () const { return m_dump_flags; }
+
+ const dump_impl_location_t &
+ get_impl_location () const { return m_impl_location; }
+
+ private:
+ dump_flags_t m_dump_flags;
+ dump_impl_location_t m_impl_location;
+};
+
+/* A bundle of information for describing the location of a dump message:
+ (a) the source location and hotness within the user's code, together with
+ (b) the source location within the compiler/plugin.
+
+ The constructors use default parameters so that (b) gets sets up
+ automatically.
+
+ The upshot is that you can pass in e.g. a gimple * to dump_printf_loc,
+ and the dump call will automatically record where in GCC's source
+ code the dump was emitted from. */
+
+class dump_location_t
+{
+ public:
+ /* Default constructor, analogous to UNKNOWN_LOCATION. */
+ dump_location_t (const dump_impl_location_t &impl_location
+ = dump_impl_location_t ())
+ : m_user_location (dump_user_location_t ()),
+ m_impl_location (impl_location)
+ {
+ }
+
+ /* Construct from a gimple statement (using its location and hotness). */
+ dump_location_t (const gimple *stmt,
+ const dump_impl_location_t &impl_location
+ = dump_impl_location_t ())
+ : m_user_location (dump_user_location_t (stmt)),
+ m_impl_location (impl_location)
+ {
+ }
+
+ /* Construct from an RTL instruction (using its location and hotness). */
+ dump_location_t (const rtx_insn *insn,
+ const dump_impl_location_t &impl_location
+ = dump_impl_location_t ())
+ : m_user_location (dump_user_location_t (insn)),
+ m_impl_location (impl_location)
+ {
+ }
+
+ /* Construct from a dump_user_location_t. */
+ dump_location_t (const dump_user_location_t &user_location,
+ const dump_impl_location_t &impl_location
+ = dump_impl_location_t ())
+ : m_user_location (user_location),
+ m_impl_location (impl_location)
+ {
+ }
+
+ /* Construct from a location_t. This one is deprecated (since it doesn't
+ capture hotness information), and thus requires spelling out. */
+ static dump_location_t
+ from_location_t (location_t loc,
+ const dump_impl_location_t &impl_location
+ = dump_impl_location_t ())
+ {
+ return dump_location_t (dump_user_location_t::from_location_t (loc),
+ impl_location);
+ }
+
+ const dump_user_location_t &
+ get_user_location () const { return m_user_location; }
+
+ const dump_impl_location_t &
+ get_impl_location () const { return m_impl_location; }
+
+ location_t get_location_t () const
+ {
+ return m_user_location.get_location_t ();
+ }
+
+ profile_count get_count () const { return m_user_location.get_count (); }
+
+ private:
+ dump_user_location_t m_user_location;
+ dump_impl_location_t m_impl_location;
+};
+
/* In dumpfile.c */
-extern FILE *dump_begin (int, dump_flags_t *);
+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, source_location,
- const char *, ...) ATTRIBUTE_PRINTF_3;
+extern const kv_pair<optgroup_flags_t> optgroup_options[];
+extern dump_flags_t
+parse_dump_option (const char *, const char **);
+
+/* Global variables used to communicate with passes. */
+extern FILE *dump_file;
+extern dump_flags_t dump_flags;
+extern const char *dump_file_name;
+
+extern bool dumps_are_enabled;
+
+extern void set_dump_file (FILE *new_dump_file);
+
+/* Return true if any of the dumps is enabled, false otherwise. */
+static inline bool
+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.
+
+ Some destinations are written to immediately as dump_* calls
+ are made; for others, the output is consolidated into an "optinfo"
+ instance (with its own metadata), and only emitted once the optinfo
+ is complete.
+
+ The destinations are:
+
+ (a) the "immediate" destinations:
+ (a.1) the active dump_file, if any
+ (a.2) the -fopt-info destination, if any
+ (b) the "optinfo" destinations, if any:
+ (b.1) as optimization records
+
+ dump_* (MSG_*) --> dumpfile.c --> items --> (a.1) dump_file
+ | `-> (a.2) alt_dump_file
+ |
+ `--> (b) optinfo
+ `---> optinfo destinations
+ (b.1) optimization records
+
+ 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 (const dump_metadata_t &, const char *, ...)
+ ATTRIBUTE_GCC_DUMP_PRINTF (2, 3);
+
+extern void dump_printf_loc (const dump_metadata_t &, const dump_user_location_t &,
+ const char *, ...)
+ ATTRIBUTE_GCC_DUMP_PRINTF (3, 0);
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, source_location, 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, source_location, dump_flags_t,
- gimple *, int);
-extern void dump_gimple_stmt (dump_flags_t, dump_flags_t, gimple *, int);
-extern void print_combine_total_stats (void);
-extern bool enable_rtl_dump_file (void);
+extern void dump_generic_expr_loc (const dump_metadata_t &,
+ const dump_user_location_t &,
+ dump_flags_t, tree);
+extern void dump_generic_expr (const dump_metadata_t &, dump_flags_t, tree);
+extern void dump_gimple_stmt_loc (const dump_metadata_t &,
+ const dump_user_location_t &,
+ dump_flags_t, gimple *, int);
+extern void dump_gimple_stmt (const dump_metadata_t &, dump_flags_t, gimple *, int);
+extern void dump_gimple_expr_loc (const dump_metadata_t &,
+ const dump_user_location_t &,
+ dump_flags_t, gimple *, int);
+extern void dump_gimple_expr (const dump_metadata_t &, dump_flags_t, gimple *, int);
+extern void dump_symtab_node (const dump_metadata_t &, symtab_node *);
template<unsigned int N, typename C>
-void dump_dec (dump_flags_t, const poly_int<N, C> &);
+void dump_dec (const dump_metadata_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. */
+
+extern unsigned int get_dump_scope_depth ();
+extern void dump_begin_scope (const char *name,
+ const dump_user_location_t &user_location,
+ const dump_impl_location_t &impl_location);
+extern void dump_end_scope ();
+
+/* Implementation detail of the AUTO_DUMP_SCOPE macro below.
+
+ A RAII-style class intended to make it easy to emit dump
+ information about entering and exiting a collection of nested
+ function calls. */
+
+class auto_dump_scope
+{
+ public:
+ auto_dump_scope (const char *name,
+ const dump_user_location_t &user_location,
+ const dump_impl_location_t &impl_location
+ = dump_impl_location_t ())
+ {
+ if (dump_enabled_p ())
+ dump_begin_scope (name, user_location, impl_location);
+ }
+ ~auto_dump_scope ()
+ {
+ if (dump_enabled_p ())
+ dump_end_scope ();
+ }
+};
+
+/* A macro for calling:
+ dump_begin_scope (NAME, USER_LOC);
+ via an RAII object, thus printing "=== MSG ===\n" to the dumpfile etc,
+ and then calling
+ dump_end_scope ();
+ once the object goes out of scope, thus capturing the nesting of
+ the scopes.
+
+ These scopes affect dump messages within them: dump messages at the
+ top level implicitly default to MSG_PRIORITY_USER_FACING, whereas those
+ in a nested scope implicitly default to MSG_PRIORITY_INTERNALS. */
+
+#define AUTO_DUMP_SCOPE(NAME, USER_LOC) \
+ auto_dump_scope scope (NAME, USER_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 cfghooks.c */
extern void dump_bb (FILE *, basic_block, int, dump_flags_t);
-/* Global variables used to communicate with passes. */
-extern FILE *dump_file;
-extern FILE *alt_dump_file;
-extern dump_flags_t dump_flags;
-extern const char *dump_file_name;
-
-/* Return true if any of the dumps is enabled, false otherwise. */
-static inline bool
-dump_enabled_p (void)
-{
- return (dump_file || alt_dump_file);
-}
+class opt_pass;
namespace gcc {
+/* A class for managing all of the various dump files used by the
+ optimization passes. */
+
class dump_manager
{
public:
/* Return the name of the dump file for the given phase.
If the dump is not enabled, returns NULL. */
char *
- get_dump_file_name (int phase) const;
+ get_dump_file_name (int phase, int part = -1) const;
char *
- get_dump_file_name (struct dump_file_info *dfi) const;
+ get_dump_file_name (struct dump_file_info *dfi, int part = -1) const;
- int
+ void
dump_switch_p (const char *arg);
/* Start a dump for PHASE. Store user-supplied dump flags in
dump_finish (int phase);
FILE *
- dump_begin (int phase, dump_flags_t *flag_ptr);
+ dump_begin (int phase, dump_flags_t *flag_ptr, int part);
/* Returns nonzero if tree dump PHASE has been initialized. */
int
const char *
dump_flag_name (int phase) const;
+ void register_pass (opt_pass *pass);
+
private:
int
opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags,
const char *filename);
+ bool update_dfi_for_opt_info (dump_file_info *dfi) const;
+
private:
/* Dynamically registered dump files and switches. */
size_t m_extra_dump_files_in_use;
size_t m_extra_dump_files_alloced;
+ /* Stored values from -fopt-info, for handling passes created after
+ option-parsing (by backends and by plugins). */
+ optgroup_flags_t m_optgroup_flags;
+ dump_flags_t m_optinfo_flags;
+ char *m_optinfo_filename;
+
/* Grant access to dump_enable_all. */
friend bool ::enable_rtl_dump_file (void);