775 lines
23 KiB
C++
775 lines
23 KiB
C++
/* Definitions for the shared dumpfile.
|
|
Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
|
|
|
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_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.cc), with additional codes for middle-end
|
|
specific entities (see dumpfile.cc). */
|
|
|
|
#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.cc. */
|
|
enum tree_dump_index
|
|
{
|
|
TDI_none, /* No dump */
|
|
TDI_cgraph, /* dump function call graph. */
|
|
TDI_inheritance, /* dump type inheritance graph. */
|
|
TDI_clones, /* dump IPA cloning decisions. */
|
|
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. */
|
|
TDI_rtl_all, /* enable all the RTL dumps. */
|
|
TDI_ipa_all, /* enable all the IPA dumps. */
|
|
|
|
TDI_end
|
|
};
|
|
|
|
/* Enum used to distinguish dump files to types. */
|
|
|
|
enum dump_kind
|
|
{
|
|
DK_none,
|
|
DK_lang,
|
|
DK_tree,
|
|
DK_rtl,
|
|
DK_ipa
|
|
};
|
|
|
|
/* Bit masks to control dumping. Not all values are applicable to all
|
|
dumps. Add new ones at the end. When you define new values, extend
|
|
the DUMP_OPTIONS array in dumpfile.cc. The TDF_* flags coexist with
|
|
MSG_* flags (for -fopt-info) and the bit values must be chosen to
|
|
allow that. */
|
|
enum dump_flag : uint32_t
|
|
{
|
|
/* Value of TDF_NONE is used just for bits filtered by TDF_KIND_MASK. */
|
|
TDF_NONE = 0,
|
|
|
|
/* Dump node addresses. */
|
|
TDF_ADDRESS = (1 << 0),
|
|
|
|
/* Don't go wild following links. */
|
|
TDF_SLIM = (1 << 1),
|
|
|
|
/* Don't unparse the function. */
|
|
TDF_RAW = (1 << 2),
|
|
|
|
/* Show more detailed info about each pass. */
|
|
TDF_DETAILS = (1 << 3),
|
|
|
|
/* Dump various statistics about each pass. */
|
|
TDF_STATS = (1 << 4),
|
|
|
|
/* Display basic block boundaries. */
|
|
TDF_BLOCKS = (1 << 5),
|
|
|
|
/* Display virtual operands. */
|
|
TDF_VOPS = (1 << 6),
|
|
|
|
/* Display statement line numbers. */
|
|
TDF_LINENO = (1 << 7),
|
|
|
|
/* Display decl UIDs. */
|
|
TDF_UID = (1 << 8),
|
|
|
|
/* Address of stmt. */
|
|
TDF_STMTADDR = (1 << 9),
|
|
|
|
/* A graph dump is being emitted. */
|
|
TDF_GRAPH = (1 << 10),
|
|
|
|
/* Display memory symbols in expr.
|
|
Implies TDF_VOPS. */
|
|
TDF_MEMSYMS = (1 << 11),
|
|
|
|
/* A flag to only print the RHS of a gimple stmt. */
|
|
TDF_RHS_ONLY = (1 << 12),
|
|
|
|
/* Display asm names of decls. */
|
|
TDF_ASMNAME = (1 << 13),
|
|
|
|
/* Display EH region number holding this gimple statement. */
|
|
TDF_EH = (1 << 14),
|
|
|
|
/* Omit UIDs from dumps. */
|
|
TDF_NOUID = (1 << 15),
|
|
|
|
/* Display alias information. */
|
|
TDF_ALIAS = (1 << 16),
|
|
|
|
/* Enumerate locals by uid. */
|
|
TDF_ENUMERATE_LOCALS = (1 << 17),
|
|
|
|
/* Dump cselib details. */
|
|
TDF_CSELIB = (1 << 18),
|
|
|
|
/* Dump SCEV details. */
|
|
TDF_SCEV = (1 << 19),
|
|
|
|
/* Dump in GIMPLE FE syntax. */
|
|
TDF_GIMPLE = (1 << 20),
|
|
|
|
/* 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),
|
|
|
|
/* Missed opportunities. */
|
|
MSG_MISSED_OPTIMIZATION = (1 << 23),
|
|
|
|
/* General optimization info. */
|
|
MSG_NOTE = (1 << 24),
|
|
|
|
/* 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),
|
|
|
|
/* All -fdump- flags. */
|
|
TDF_ALL_VALUES = (1 << 28) - 1,
|
|
|
|
/* Dumping for -fcompare-debug. */
|
|
TDF_COMPARE_DEBUG = (1 << 28),
|
|
|
|
/* Dump a GIMPLE value which means wrapping certain things with _Literal. */
|
|
TDF_GIMPLE_VAL = (1 << 29),
|
|
|
|
/* For error. */
|
|
TDF_ERROR = ((uint32_t)1 << 30),
|
|
};
|
|
|
|
/* Dump flags type. */
|
|
|
|
typedef enum dump_flag dump_flags_t;
|
|
|
|
inline dump_flags_t
|
|
operator| (dump_flags_t lhs, dump_flags_t rhs)
|
|
{
|
|
return (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
|
|
| (std::underlying_type<dump_flags_t>::type)rhs);
|
|
}
|
|
|
|
inline dump_flags_t
|
|
operator& (dump_flags_t lhs, dump_flags_t rhs)
|
|
{
|
|
return (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
|
|
& (std::underlying_type<dump_flags_t>::type)rhs);
|
|
}
|
|
|
|
inline dump_flags_t
|
|
operator~ (dump_flags_t flags)
|
|
{
|
|
return (dump_flags_t)~((std::underlying_type<dump_flags_t>::type)flags);
|
|
}
|
|
|
|
inline dump_flags_t &
|
|
operator|= (dump_flags_t &lhs, dump_flags_t rhs)
|
|
{
|
|
lhs = (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
|
|
| (std::underlying_type<dump_flags_t>::type)rhs);
|
|
return lhs;
|
|
}
|
|
|
|
inline dump_flags_t &
|
|
operator&= (dump_flags_t &lhs, dump_flags_t rhs)
|
|
{
|
|
lhs = (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
|
|
& (std::underlying_type<dump_flags_t>::type)rhs);
|
|
return lhs;
|
|
}
|
|
|
|
/* Flags to control high-level -fopt-info dumps. Usually these flags
|
|
define a group of passes. An optimization pass can be part of
|
|
multiple groups. */
|
|
|
|
enum optgroup_flag
|
|
{
|
|
OPTGROUP_NONE = 0,
|
|
|
|
/* IPA optimization passes */
|
|
OPTGROUP_IPA = (1 << 1),
|
|
|
|
/* Loop optimization passes */
|
|
OPTGROUP_LOOP = (1 << 2),
|
|
|
|
/* Inlining passes */
|
|
OPTGROUP_INLINE = (1 << 3),
|
|
|
|
/* OMP (Offloading and Multi Processing) transformations */
|
|
OPTGROUP_OMP = (1 << 4),
|
|
|
|
/* Vectorization passes */
|
|
OPTGROUP_VEC = (1 << 5),
|
|
|
|
/* All other passes */
|
|
OPTGROUP_OTHER = (1 << 6),
|
|
|
|
OPTGROUP_ALL = (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE
|
|
| OPTGROUP_OMP | OPTGROUP_VEC | OPTGROUP_OTHER)
|
|
};
|
|
|
|
typedef enum optgroup_flag optgroup_flags_t;
|
|
|
|
inline optgroup_flags_t
|
|
operator| (optgroup_flags_t lhs, optgroup_flags_t rhs)
|
|
{
|
|
return (optgroup_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
|
|
| (std::underlying_type<dump_flags_t>::type)rhs);
|
|
}
|
|
|
|
inline optgroup_flags_t &
|
|
operator|= (optgroup_flags_t &lhs, optgroup_flags_t rhs)
|
|
{
|
|
lhs = (optgroup_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
|
|
| (std::underlying_type<dump_flags_t>::type)rhs);
|
|
return lhs;
|
|
}
|
|
|
|
/* Define a tree dump switch. */
|
|
struct dump_file_info
|
|
{
|
|
/* Suffix to give output file. */
|
|
const char *suffix;
|
|
/* Command line dump switch. */
|
|
const char *swtch;
|
|
/* Command line glob. */
|
|
const char *glob;
|
|
/* Filename for the pass-specific stream. */
|
|
const char *pfilename;
|
|
/* Filename for the -fopt-info stream. */
|
|
const char *alt_filename;
|
|
/* Pass-specific dump stream. */
|
|
FILE *pstream;
|
|
/* -fopt-info stream. */
|
|
FILE *alt_stream;
|
|
/* Dump kind. */
|
|
dump_kind dkind;
|
|
/* Dump flags. */
|
|
dump_flags_t pflags;
|
|
/* A pass flags for -fopt-info. */
|
|
dump_flags_t alt_flags;
|
|
/* Flags for -fopt-info given by a user. */
|
|
optgroup_flags_t optgroup_flags;
|
|
/* State of pass-specific stream. */
|
|
int pstate;
|
|
/* State of the -fopt-info stream. */
|
|
int alt_state;
|
|
/* Dump file number. */
|
|
int num;
|
|
/* Fields "suffix", "swtch", "glob" can be const strings,
|
|
or can be dynamically allocated, needing free. */
|
|
bool owns_strings;
|
|
/* When a given dump file is being initialized, this flag is set to true
|
|
if the corresponding TDF_graph dump file has also been initialized. */
|
|
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.cc */
|
|
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 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. */
|
|
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.cc --> 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, 4);
|
|
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 (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 (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.cc */
|
|
extern void dump_node (const_tree, dump_flags_t, FILE *);
|
|
|
|
/* In combine.cc */
|
|
extern void dump_combine_total_stats (FILE *);
|
|
/* In cfghooks.cc */
|
|
extern void dump_bb (FILE *, basic_block, int, dump_flags_t);
|
|
|
|
class opt_pass;
|
|
|
|
namespace gcc {
|
|
|
|
/* A class for managing all of the various dump files used by the
|
|
optimization passes. */
|
|
|
|
class dump_manager
|
|
{
|
|
public:
|
|
|
|
dump_manager ();
|
|
~dump_manager ();
|
|
|
|
/* Register a dumpfile.
|
|
|
|
TAKE_OWNERSHIP determines whether callee takes ownership of strings
|
|
SUFFIX, SWTCH, and GLOB. */
|
|
unsigned int
|
|
dump_register (const char *suffix, const char *swtch, const char *glob,
|
|
dump_kind dkind, optgroup_flags_t optgroup_flags,
|
|
bool take_ownership);
|
|
|
|
/* Allow languages and middle-end to register their dumps before the
|
|
optimization passes. */
|
|
void
|
|
register_dumps ();
|
|
|
|
/* Return the dump_file_info for the given phase. */
|
|
struct dump_file_info *
|
|
get_dump_file_info (int phase) const;
|
|
|
|
struct dump_file_info *
|
|
get_dump_file_info_by_switch (const char *swtch) const;
|
|
|
|
/* 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, int part = -1) const;
|
|
|
|
char *
|
|
get_dump_file_name (struct dump_file_info *dfi, int part = -1) const;
|
|
|
|
void
|
|
dump_switch_p (const char *arg);
|
|
|
|
/* Start a dump for PHASE. Store user-supplied dump flags in
|
|
*FLAG_PTR. Return the number of streams opened. Set globals
|
|
DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
|
|
set dump_flags appropriately for both pass dump stream and
|
|
-fopt-info stream. */
|
|
int
|
|
dump_start (int phase, dump_flags_t *flag_ptr);
|
|
|
|
/* Finish a tree dump for PHASE and close associated dump streams. Also
|
|
reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
|
|
void
|
|
dump_finish (int phase);
|
|
|
|
FILE *
|
|
dump_begin (int phase, dump_flags_t *flag_ptr, int part);
|
|
|
|
/* Returns nonzero if tree dump PHASE has been initialized. */
|
|
int
|
|
dump_initialized_p (int phase) const;
|
|
|
|
/* Returns the switch name of PHASE. */
|
|
const char *
|
|
dump_flag_name (int phase) const;
|
|
|
|
void register_pass (opt_pass *pass);
|
|
|
|
private:
|
|
|
|
int
|
|
dump_phase_enabled_p (int phase) const;
|
|
|
|
int
|
|
dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob);
|
|
|
|
int
|
|
dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename);
|
|
|
|
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. */
|
|
int m_next_dump;
|
|
struct dump_file_info *m_extra_dump_files;
|
|
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);
|
|
|
|
/* Grant access to opt_info_enable_passes. */
|
|
friend int ::opt_info_switch_p (const char *arg);
|
|
|
|
}; // class dump_manager
|
|
|
|
} // namespace gcc
|
|
|
|
#endif /* GCC_DUMPFILE_H */
|