Message ID | 1527626483-4723-2-git-send-email-dmalcolm@redhat.com |
---|---|
State | New |
Headers | show |
Series | RFC: Prototype of compiler-assisted performance analysis | expand |
On Tue, May 29, 2018 at 10:32 PM David Malcolm <dmalcolm@redhat.com> wrote: > > The dump machinery uses "int" in a few places, for two different > sets of bitmasks. > > This patch makes things more self-documenting and type-safe by using > a new pair of enums: one for the dump_flags_t and another for the > optgroup_flags. Great! This should also make them accessible in gdb w/o using -g3. > This requires adding some overloaded bit operations to the enums > in question, which, in this patch is done for each enum . If the basic > idea is OK, should I add a template for this? (with some kind of > magic to express that bitmasking operations are only supported on > certain opt-in enums). Does C++ allow > int enums? I think we want some way of knowing when either enum exceeds int (dump_flags_t was already uint64_t but you now make it effectively int again). That is, general wrapping for enum ops should chose an appropriate unsigned integer for the operation. So yes, a common implementation looks useful to me. I think this patch is independently useful. Thanks, Richard. > > gcc/c-family/ChangeLog: > * c-pretty-print.c (c_pretty_printer::statement): Use TDF_NONE > rather than 0. > > gcc/ChangeLog: > * cfg.c (debug): Use TDF_NONE rather than 0. > * cfghooks.c (debug): Likewise. > * dumpfile.c (DUMP_FILE_INFO): Likewise; also for OPTGROUP. > (struct dump_option_value_info): Convert to... > (struct kv_pair): ...this template type. > (dump_options): Convert to kv_pair<dump_flags_t>; use TDF_NONE > rather than 0. > (optinfo_verbosity_options): Likewise. > (optgroup_options): Convert to kv_pair<optgroup_flags_t>; use > OPTGROUP_NONE. > (gcc::dump_manager::dump_register): Use optgroup_flags_t rather > than int for "optgroup_flags" param. > (dump_generic_expr_loc): Use dump_flags_t rather than int for > "dump_kind" param. > (dump_finish): Use TDF_NONE rather than 0. > (gcc::dump_manager::opt_info_enable_passes): Use optgroup_flags_t > rather than int for "optgroup_flags" param. Use TDF_NONE rather > than 0. Update for change to option_ptr. > (opt_info_switch_p_1): Convert "optgroup_flags" param from int * > to optgroup_flags_t *. Use TDF_NONE and OPTGROUP_NONE rather than > 0. Update for changes to optinfo_verbosity_options and > optgroup_options. > (opt_info_switch_p): Convert optgroup_flags from int to > optgroup_flags_t. > * dumpfile.h (TDF_ADDRESS, TDF_SLIM, TDF_RAW, TDF_DETAILS, > TDF_STATS, TDF_BLOCKS, TDF_VOPS, TDF_LINENO, TDF_UID) > TDF_STMTADDR, TDF_GRAPH, TDF_MEMSYMS, TDF_RHS_ONLY, TDF_ASMNAME, > TDF_EH, TDF_NOUID, TDF_ALIAS, TDF_ENUMERATE_LOCALS, TDF_CSELIB, > TDF_SCEV, TDF_GIMPLE, TDF_FOLDING, MSG_OPTIMIZED_LOCATIONS, > MSG_MISSED_OPTIMIZATION, MSG_NOTE, MSG_ALL, TDF_COMPARE_DEBUG, > TDF_NONE): Convert from macros to... > (enum dump_flag): ...this new enum. > (dump_flags_t): Update to use enum. > (operator|, operator&, operator~, operator|=, operator&=): > Implement for dump_flags_t. > (OPTGROUP_NONE, OPTGROUP_IPA, OPTGROUP_LOOP, OPTGROUP_INLINE, > OPTGROUP_OMP, OPTGROUP_VEC, OPTGROUP_OTHER, OPTGROUP_ALL): > Convert from macros to... > (enum optgroup_flag): ...this new enum. > (optgroup_flags_t): New typedef. > (operator|, operator|=): Implement for optgroup_flags_t. > (struct dump_file_info): Convert field "alt_flags" to > dump_flags_t. Convert field "optgroup_flags" to > optgroup_flags_t. > (dump_register): Convert param "optgroup_flags" to > optgroup_flags_t. > (opt_info_enable_passes): Likewise. > * early-remat.c (early_remat::dump_edge_list): Use TDF_NONE rather > than 0. > * gimple-pretty-print.c (debug): Likewise. > * gimple-ssa-store-merging.c (bswap_replace): Likewise. > (merged_store_group::apply_stores): Likewise. > * gimple-ssa-strength-reduction.c (insert_initializers): Likewise. > * gimple.c (verify_gimple_pp): Likewise. > * passes.c (pass_manager::register_one_dump_file): Convert > local "optgroup_flags" to optgroup_flags_t. > * print-tree.c (print_node): Use TDF_NONE rather than 0. > (debug): Likewise. > (debug_body): Likewise. > * tree-pass.h (struct pass_data): Convert field "optgroup_flags" > to optgroup_flags_t. > * tree-pretty-print.c (print_struct_decl): Use TDF_NONE rather > than 0. > * tree-ssa-math-opts.c (convert_mult_to_fma_1): Likewise. > (convert_mult_to_fma): Likewise. > * tree-ssa-reassoc.c (undistribute_ops_list): Likewise. > * tree-ssa-sccvn.c (vn_eliminate): Likewise. > * tree-vect-data-refs.c (dump_lower_bound): Convert param > "dump_kind" to dump_flags_t. > --- > gcc/c-family/c-pretty-print.c | 2 +- > gcc/cfg.c | 4 +- > gcc/cfghooks.c | 2 +- > gcc/dumpfile.c | 56 ++++----- > gcc/dumpfile.h | 227 +++++++++++++++++++++++++++--------- > gcc/early-remat.c | 2 +- > gcc/gimple-pretty-print.c | 2 +- > gcc/gimple-ssa-store-merging.c | 6 +- > gcc/gimple-ssa-strength-reduction.c | 2 +- > gcc/gimple.c | 2 +- > gcc/passes.c | 2 +- > gcc/print-tree.c | 7 +- > gcc/tree-pass.h | 2 +- > gcc/tree-pretty-print.c | 2 +- > gcc/tree-ssa-math-opts.c | 4 +- > gcc/tree-ssa-reassoc.c | 2 +- > gcc/tree-ssa-sccvn.c | 2 +- > gcc/tree-vect-data-refs.c | 2 +- > 18 files changed, 222 insertions(+), 106 deletions(-) > > diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c > index dc76c99..efb41c5 100644 > --- a/gcc/c-family/c-pretty-print.c > +++ b/gcc/c-family/c-pretty-print.c > @@ -2341,7 +2341,7 @@ c_pretty_printer::statement (tree stmt) > if (pp_needs_newline (this)) > pp_newline_and_indent (this, 0); > > - dump_generic_node (this, stmt, pp_indentation (this), 0, true); > + dump_generic_node (this, stmt, pp_indentation (this), TDF_NONE, true); > } > > > diff --git a/gcc/cfg.c b/gcc/cfg.c > index 11026e7..6d55516 100644 > --- a/gcc/cfg.c > +++ b/gcc/cfg.c > @@ -545,8 +545,8 @@ DEBUG_FUNCTION void > debug (edge_def &ref) > { > /* FIXME (crowl): Is this desireable? */ > - dump_edge_info (stderr, &ref, 0, false); > - dump_edge_info (stderr, &ref, 0, true); > + dump_edge_info (stderr, &ref, TDF_NONE, false); > + dump_edge_info (stderr, &ref, TDF_NONE, true); > } > > DEBUG_FUNCTION void > diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c > index 87d864c..ea106e0 100644 > --- a/gcc/cfghooks.c > +++ b/gcc/cfghooks.c > @@ -288,7 +288,7 @@ dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags) > DEBUG_FUNCTION void > debug (basic_block_def &ref) > { > - dump_bb (stderr, &ref, 0, 0); > + dump_bb (stderr, &ref, 0, TDF_NONE); > } > > DEBUG_FUNCTION void > diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c > index 0acc7a9..6af1445 100644 > --- a/gcc/dumpfile.c > +++ b/gcc/dumpfile.c > @@ -50,8 +50,8 @@ const char *dump_file_name; > dump_flags_t dump_flags; > > #define DUMP_FILE_INFO(suffix, swtch, dkind, num) \ > - {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, 0, 0, 0, 0, 0, num, \ > - false, false} > + {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, TDF_NONE, TDF_NONE, \ > + OPTGROUP_NONE, 0, 0, num, false, false} > > /* Table of tree dump switches. This must be consistent with the > TREE_DUMP_INDEX enumeration in dumpfile.h. */ > @@ -74,15 +74,16 @@ static struct dump_file_info dump_files[TDI_end] = > }; > > /* Define a name->number mapping for a dump flag value. */ > -struct dump_option_value_info > +template <typename ValueType> > +struct kv_pair > { > const char *const name; /* the name of the value */ > - const dump_flags_t value; /* the value of the name */ > + const ValueType value; /* the value of the name */ > }; > > /* Table of dump options. This must be consistent with the TDF_* flags > in dumpfile.h and opt_info_options below. */ > -static const struct dump_option_value_info dump_options[] = > +static const kv_pair<dump_flags_t> dump_options[] = > { > {"address", TDF_ADDRESS}, > {"asmname", TDF_ASMNAME}, > @@ -114,23 +115,23 @@ static const struct dump_option_value_info dump_options[] = > {"all", dump_flags_t (~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_GRAPH > | TDF_STMTADDR | TDF_RHS_ONLY | TDF_NOUID > | TDF_ENUMERATE_LOCALS | TDF_SCEV | TDF_GIMPLE))}, > - {NULL, 0} > + {NULL, TDF_NONE} > }; > > /* A subset of the dump_options table which is used for -fopt-info > types. This must be consistent with the MSG_* flags in dumpfile.h. > */ > -static const struct dump_option_value_info optinfo_verbosity_options[] = > +static const kv_pair<dump_flags_t> optinfo_verbosity_options[] = > { > {"optimized", MSG_OPTIMIZED_LOCATIONS}, > {"missed", MSG_MISSED_OPTIMIZATION}, > {"note", MSG_NOTE}, > {"all", MSG_ALL}, > - {NULL, 0} > + {NULL, TDF_NONE} > }; > > /* Flags used for -fopt-info groups. */ > -static const struct dump_option_value_info optgroup_options[] = > +static const kv_pair<optgroup_flags_t> optgroup_options[] = > { > {"ipa", OPTGROUP_IPA}, > {"loop", OPTGROUP_LOOP}, > @@ -138,7 +139,7 @@ static const struct dump_option_value_info optgroup_options[] = > {"omp", OPTGROUP_OMP}, > {"vec", OPTGROUP_VEC}, > {"optall", OPTGROUP_ALL}, > - {NULL, 0} > + {NULL, OPTGROUP_NONE} > }; > > gcc::dump_manager::dump_manager (): > @@ -173,7 +174,8 @@ gcc::dump_manager::~dump_manager () > unsigned int > gcc::dump_manager:: > dump_register (const char *suffix, const char *swtch, const char *glob, > - dump_kind dkind, int optgroup_flags, bool take_ownership) > + dump_kind dkind, optgroup_flags_t optgroup_flags, > + bool take_ownership) > { > int num = m_next_dump++; > > @@ -410,7 +412,7 @@ dump_generic_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags, > location. */ > > void > -dump_generic_expr_loc (int dump_kind, source_location loc, > +dump_generic_expr_loc (dump_flags_t dump_kind, source_location loc, > dump_flags_t extra_dump_flags, tree t) > { > if (dump_file && (dump_kind & pflags)) > @@ -575,9 +577,9 @@ dump_finish (int phase) > dfi->pstream = NULL; > dump_file = NULL; > alt_dump_file = NULL; > - dump_flags = TDI_none; > - alt_flags = 0; > - pflags = 0; > + dump_flags = TDF_NONE; > + alt_flags = TDF_NONE; > + pflags = TDF_NONE; > } > > /* Begin a tree dump for PHASE. Stores any user supplied flag in > @@ -750,7 +752,7 @@ dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename) > > int > gcc::dump_manager:: > -opt_info_enable_passes (int optgroup_flags, dump_flags_t flags, > +opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags, > const char *filename) > { > int n = 0; > @@ -817,11 +819,11 @@ dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob) > return 0; > > ptr = option_value; > - flags = 0; > + flags = TDF_NONE; > > while (*ptr) > { > - const struct dump_option_value_info *option_ptr; > + const struct kv_pair<dump_flags_t> *option_ptr; > const char *end_ptr; > const char *eq_ptr; > unsigned length; > @@ -903,8 +905,8 @@ dump_switch_p (const char *arg) > and filename. Return non-zero if it is a recognized switch. */ > > static int > -opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, > - char **filename) > +opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, > + optgroup_flags_t *optgroup_flags, char **filename) > { > const char *option_value; > const char *ptr; > @@ -913,15 +915,14 @@ opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, > ptr = option_value; > > *filename = NULL; > - *flags = 0; > - *optgroup_flags = 0; > + *flags = TDF_NONE; > + *optgroup_flags = OPTGROUP_NONE; > > if (!ptr) > return 1; /* Handle '-fopt-info' without any additional options. */ > > while (*ptr) > { > - const struct dump_option_value_info *option_ptr; > const char *end_ptr; > const char *eq_ptr; > unsigned length; > @@ -938,8 +939,8 @@ opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, > end_ptr = ptr + strlen (ptr); > length = end_ptr - ptr; > > - for (option_ptr = optinfo_verbosity_options; option_ptr->name; > - option_ptr++) > + for (const kv_pair<dump_flags_t> *option_ptr = optinfo_verbosity_options; > + option_ptr->name; option_ptr++) > if (strlen (option_ptr->name) == length > && !memcmp (option_ptr->name, ptr, length)) > { > @@ -947,7 +948,8 @@ opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, > goto found; > } > > - for (option_ptr = optgroup_options; option_ptr->name; option_ptr++) > + for (const kv_pair<optgroup_flags_t> *option_ptr = optgroup_options; > + option_ptr->name; option_ptr++) > if (strlen (option_ptr->name) == length > && !memcmp (option_ptr->name, ptr, length)) > { > @@ -982,7 +984,7 @@ int > opt_info_switch_p (const char *arg) > { > dump_flags_t flags; > - int optgroup_flags; > + optgroup_flags_t optgroup_flags; > char *filename; > static char *file_seen = NULL; > gcc::dump_manager *dumps = g->get_dumps (); > diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h > index 21803a6..b5582f7 100644 > --- a/gcc/dumpfile.h > +++ b/gcc/dumpfile.h > @@ -58,65 +58,177 @@ enum dump_kind > the DUMP_OPTIONS array in dumpfile.c. The TDF_* flags coexist with > MSG_* flags (for -fopt-info) and the bit values must be chosen to > allow that. */ > -#define TDF_ADDRESS (1 << 0) /* dump node addresses */ > -#define TDF_SLIM (1 << 1) /* don't go wild following links */ > -#define TDF_RAW (1 << 2) /* don't unparse the function */ > -#define TDF_DETAILS (1 << 3) /* show more detailed info about > - each pass */ > -#define TDF_STATS (1 << 4) /* dump various statistics about > - each pass */ > -#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */ > -#define TDF_VOPS (1 << 6) /* display virtual operands */ > -#define TDF_LINENO (1 << 7) /* display statement line numbers */ > -#define TDF_UID (1 << 8) /* display decl UIDs */ > - > -#define TDF_STMTADDR (1 << 9) /* Address of stmt. */ > - > -#define TDF_GRAPH (1 << 10) /* a graph dump is being emitted */ > -#define TDF_MEMSYMS (1 << 11) /* display memory symbols in expr. > - Implies TDF_VOPS. */ > - > -#define TDF_RHS_ONLY (1 << 12) /* a flag to only print the RHS of > - a gimple stmt. */ > -#define TDF_ASMNAME (1 << 13) /* display asm names of decls */ > -#define TDF_EH (1 << 14) /* display EH region number > - holding this gimple statement. */ > -#define TDF_NOUID (1 << 15) /* omit UIDs from dumps. */ > -#define TDF_ALIAS (1 << 16) /* display alias information */ > -#define TDF_ENUMERATE_LOCALS (1 << 17) /* Enumerate locals by uid. */ > -#define TDF_CSELIB (1 << 18) /* Dump cselib details. */ > -#define TDF_SCEV (1 << 19) /* Dump SCEV details. */ > -#define TDF_GIMPLE (1 << 20) /* Dump in GIMPLE FE syntax */ > -#define TDF_FOLDING (1 << 21) /* Dump folding details. */ > -#define MSG_OPTIMIZED_LOCATIONS (1 << 22) /* -fopt-info optimized sources */ > -#define MSG_MISSED_OPTIMIZATION (1 << 23) /* missed opportunities */ > -#define MSG_NOTE (1 << 24) /* general optimization info */ > -#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \ > - | MSG_NOTE) > -#define TDF_COMPARE_DEBUG (1 << 25) /* Dumping for -fcompare-debug. */ > - > - > -/* Value of TDF_NONE is used just for bits filtered by TDF_KIND_MASK. */ > - > -#define TDF_NONE 0 > +enum dump_flag > +{ > + /* 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), > + > + /* -fopt-info optimized sources. */ > + MSG_OPTIMIZED_LOCATIONS = (1 << 22), > + > + /* Missed opportunities. */ > + MSG_MISSED_OPTIMIZATION = (1 << 23), > + > + /* General optimization info. */ > + MSG_NOTE = (1 << 24), > + > + MSG_ALL = (MSG_OPTIMIZED_LOCATIONS > + | MSG_MISSED_OPTIMIZATION > + | MSG_NOTE), > + > + /* Dumping for -fcompare-debug. */ > + TDF_COMPARE_DEBUG = (1 << 25), > +}; > + > +/* Dump flags type. */ > + > +typedef enum dump_flag dump_flags_t; > + > +// FIXME: template > +// FIXME: underlying storage type? > +static inline dump_flags_t > +operator| (dump_flags_t lhs, dump_flags_t rhs) > +{ > + return (dump_flags_t)((int)lhs | (int)rhs); > +} > + > +static inline dump_flags_t > +operator& (dump_flags_t lhs, dump_flags_t rhs) > +{ > + return (dump_flags_t)((int)lhs & (int)rhs); > +} > + > +static inline dump_flags_t > +operator~ (dump_flags_t flags) > +{ > + return (dump_flags_t)~((int)flags); > +} > + > +static inline dump_flags_t & > +operator|= (dump_flags_t &lhs, dump_flags_t rhs) > +{ > + lhs = (dump_flags_t)((int)lhs | (int)rhs); > + return lhs; > +} > + > +static inline dump_flags_t & > +operator&= (dump_flags_t &lhs, dump_flags_t rhs) > +{ > + lhs = (dump_flags_t)((int)lhs & (int)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. */ > -#define OPTGROUP_NONE (0) > -#define OPTGROUP_IPA (1 << 1) /* IPA optimization passes */ > -#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */ > -#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */ > -#define OPTGROUP_OMP (1 << 4) /* OMP (Offloading and Multi > - Processing) transformations */ > -#define OPTGROUP_VEC (1 << 5) /* Vectorization passes */ > -#define OPTGROUP_OTHER (1 << 6) /* All other passes */ > -#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \ > - | OPTGROUP_OMP | OPTGROUP_VEC | OPTGROUP_OTHER) > > -/* Dump flags type. */ > +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), > > -typedef uint64_t dump_flags_t; > + /* 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; > + > +static inline optgroup_flags_t > +operator| (optgroup_flags_t lhs, optgroup_flags_t rhs) > +{ > + return (optgroup_flags_t)((int)lhs | (int)rhs); > +} > + > +static inline optgroup_flags_t & > +operator|= (optgroup_flags_t &lhs, optgroup_flags_t rhs) > +{ > + lhs = (optgroup_flags_t)((int)lhs | (int)rhs); > + return lhs; > +} > > /* Define a tree dump switch. */ > struct dump_file_info > @@ -140,9 +252,9 @@ struct dump_file_info > /* Dump flags. */ > dump_flags_t pflags; > /* A pass flags for -fopt-info. */ > - int alt_flags; > + dump_flags_t alt_flags; > /* Flags for -fopt-info given by a user. */ > - int optgroup_flags; > + optgroup_flags_t optgroup_flags; > /* State of pass-specific stream. */ > int pstate; > /* State of the -fopt-info stream. */ > @@ -214,7 +326,8 @@ public: > SUFFIX, SWTCH, and GLOB. */ > unsigned int > dump_register (const char *suffix, const char *swtch, const char *glob, > - dump_kind dkind, int optgroup_flags, bool take_ownership); > + dump_kind dkind, optgroup_flags_t optgroup_flags, > + bool take_ownership); > > /* Allow languages and middle-end to register their dumps before the > optimization passes. */ > @@ -275,7 +388,7 @@ private: > dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename); > > int > - opt_info_enable_passes (int optgroup_flags, dump_flags_t flags, > + opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags, > const char *filename); > > private: > diff --git a/gcc/early-remat.c b/gcc/early-remat.c > index 28eb9b4..776b2d0 100644 > --- a/gcc/early-remat.c > +++ b/gcc/early-remat.c > @@ -657,7 +657,7 @@ early_remat::dump_edge_list (basic_block bb, bool do_succ) > edge e; > edge_iterator ei; > FOR_EACH_EDGE (e, ei, do_succ ? bb->succs : bb->preds) > - dump_edge_info (dump_file, e, 0, do_succ); > + dump_edge_info (dump_file, e, TDF_NONE, do_succ); > } > > /* Print information about basic block BB to the dump file. */ > diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c > index 6695526..39edaa1 100644 > --- a/gcc/gimple-pretty-print.c > +++ b/gcc/gimple-pretty-print.c > @@ -153,7 +153,7 @@ print_gimple_stmt (FILE *file, gimple *g, int spc, dump_flags_t flags) > DEBUG_FUNCTION void > debug (gimple &ref) > { > - print_gimple_stmt (stderr, &ref, 0, 0); > + print_gimple_stmt (stderr, &ref, 0, TDF_NONE); > } > > DEBUG_FUNCTION void > diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c > index 6f6538b..7362128 100644 > --- a/gcc/gimple-ssa-store-merging.c > +++ b/gcc/gimple-ssa-store-merging.c > @@ -1075,7 +1075,7 @@ bswap_replace (gimple_stmt_iterator gsi, gimple *ins_stmt, tree fndecl, > print_gimple_stmt (dump_file, cur_stmt, 0); > else > { > - print_generic_expr (dump_file, tgt, 0); > + print_generic_expr (dump_file, tgt, TDF_NONE); > fprintf (dump_file, "\n"); > } > } > @@ -1145,7 +1145,7 @@ bswap_replace (gimple_stmt_iterator gsi, gimple *ins_stmt, tree fndecl, > print_gimple_stmt (dump_file, cur_stmt, 0); > else > { > - print_generic_expr (dump_file, tgt, 0); > + print_generic_expr (dump_file, tgt, TDF_NONE); > fprintf (dump_file, "\n"); > } > } > @@ -1956,7 +1956,7 @@ merged_store_group::apply_stores () > if (ret) > { > fprintf (dump_file, "After writing "); > - print_generic_expr (dump_file, cst, 0); > + print_generic_expr (dump_file, cst, TDF_NONE); > fprintf (dump_file, " of size " HOST_WIDE_INT_PRINT_DEC > " at position %d the merged region contains:\n", > info->bitsize, pos_in_buffer); > diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c > index 1c00f09..14fc420 100644 > --- a/gcc/gimple-ssa-strength-reduction.c > +++ b/gcc/gimple-ssa-strength-reduction.c > @@ -3353,7 +3353,7 @@ insert_initializers (slsr_cand_t c) > fputs ("Using existing initializer: ", dump_file); > print_gimple_stmt (dump_file, > SSA_NAME_DEF_STMT (incr_vec[i].initializer), > - 0, 0); > + 0, TDF_NONE); > } > continue; > } > diff --git a/gcc/gimple.c b/gcc/gimple.c > index 9dc4911..c18526a 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -3148,7 +3148,7 @@ static void > verify_gimple_pp (const char *expected, gimple *stmt) > { > pretty_printer pp; > - pp_gimple_stmt_1 (&pp, stmt, 0 /* spc */, 0 /* flags */); > + pp_gimple_stmt_1 (&pp, stmt, 0 /* spc */, TDF_NONE /* flags */); > ASSERT_STREQ (expected, pp_formatted_text (&pp)); > } > > diff --git a/gcc/passes.c b/gcc/passes.c > index ad0a912..62fd413 100644 > --- a/gcc/passes.c > +++ b/gcc/passes.c > @@ -784,7 +784,7 @@ pass_manager::register_one_dump_file (opt_pass *pass) > char num[11]; > dump_kind dkind; > int id; > - int optgroup_flags = OPTGROUP_NONE; > + optgroup_flags_t optgroup_flags = OPTGROUP_NONE; > gcc::dump_manager *dumps = m_ctxt->get_dumps (); > > /* See below in next_pass_1. */ > diff --git a/gcc/print-tree.c b/gcc/print-tree.c > index caf5f26..5c736c5 100644 > --- a/gcc/print-tree.c > +++ b/gcc/print-tree.c > @@ -894,7 +894,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent, > { > pretty_printer buffer; > buffer.buffer->stream = file; > - pp_gimple_stmt_1 (&buffer, SSA_NAME_DEF_STMT (node), indent + 4, 0); > + pp_gimple_stmt_1 (&buffer, SSA_NAME_DEF_STMT (node), indent + 4, > + TDF_NONE); > pp_flush (&buffer); > } > > @@ -1039,7 +1040,7 @@ dump_tree_via_hooks (const tree_node *ptr, dump_flags_t options) > DEBUG_FUNCTION void > debug (const tree_node &ref) > { > - dump_tree_via_hooks (&ref, 0); > + dump_tree_via_hooks (&ref, TDF_NONE); > } > > DEBUG_FUNCTION void > @@ -1070,7 +1071,7 @@ DEBUG_FUNCTION void > debug_body (const tree_node &ref) > { > if (TREE_CODE (&ref) == FUNCTION_DECL) > - dump_function_to_file (const_cast <tree_node*> (&ref), stderr, 0); > + dump_function_to_file (const_cast <tree_node*> (&ref), stderr, TDF_NONE); > else > debug (ref); > } > diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h > index 93a6a99..c757591 100644 > --- a/gcc/tree-pass.h > +++ b/gcc/tree-pass.h > @@ -47,7 +47,7 @@ struct pass_data > const char *name; > > /* The -fopt-info optimization group flags as defined in dumpfile.h. */ > - unsigned int optinfo_flags; > + optgroup_flags_t optinfo_flags; > > /* The timevar id associated with this pass. */ > /* ??? Ideally would be dynamically assigned. */ > diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c > index 276ad00..8963ae0 100644 > --- a/gcc/tree-pretty-print.c > +++ b/gcc/tree-pretty-print.c > @@ -3404,7 +3404,7 @@ print_struct_decl (pretty_printer *pp, const_tree node, int spc, > || TREE_CODE (node) == QUAL_UNION_TYPE)) > pp_string (pp, "union "); > > - dump_generic_node (pp, TYPE_NAME (node), spc, 0, false); > + dump_generic_node (pp, TYPE_NAME (node), spc, TDF_NONE, false); > } > > /* Print the contents of the structure. */ > diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c > index 16d9399..b3f8cb6 100644 > --- a/gcc/tree-ssa-math-opts.c > +++ b/gcc/tree-ssa-math-opts.c > @@ -2710,7 +2710,7 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) > if (dump_file && (dump_flags & TDF_DETAILS)) > { > fprintf (dump_file, "Generated FMA "); > - print_gimple_stmt (dump_file, fma_stmt, 0, 0); > + print_gimple_stmt (dump_file, fma_stmt, 0, TDF_NONE); > fprintf (dump_file, "\n"); > } > > @@ -3046,7 +3046,7 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, > if (dump_file && (dump_flags & TDF_DETAILS)) > { > fprintf (dump_file, "Deferred generating FMA for multiplication "); > - print_gimple_stmt (dump_file, mul_stmt, 0, 0); > + print_gimple_stmt (dump_file, mul_stmt, 0, TDF_NONE); > fprintf (dump_file, "\n"); > } > > diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c > index 0e59bb5..dde9701 100644 > --- a/gcc/tree-ssa-reassoc.c > +++ b/gcc/tree-ssa-reassoc.c > @@ -1606,7 +1606,7 @@ undistribute_ops_list (enum tree_code opcode, > { > fprintf (dump_file, "searching for un-distribute opportunities "); > print_generic_expr (dump_file, > - (*ops)[bitmap_first_set_bit (candidates)]->op, 0); > + (*ops)[bitmap_first_set_bit (candidates)]->op, TDF_NONE); > fprintf (dump_file, " %d\n", nr_candidates); > } > > diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c > index 1463c1d..d8ab1f0 100644 > --- a/gcc/tree-ssa-sccvn.c > +++ b/gcc/tree-ssa-sccvn.c > @@ -5921,7 +5921,7 @@ vn_eliminate (bitmap inserted_exprs) > if (dump_file && (dump_flags & TDF_DETAILS)) > { > fprintf (dump_file, "Removing dead stmt "); > - print_gimple_stmt (dump_file, stmt, 0, 0); > + print_gimple_stmt (dump_file, stmt, 0, TDF_NONE); > } > > gimple_stmt_iterator gsi = gsi_for_stmt (stmt); > diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c > index 9aabcc1..ebc56c0 100644 > --- a/gcc/tree-vect-data-refs.c > +++ b/gcc/tree-vect-data-refs.c > @@ -3229,7 +3229,7 @@ dependence_distance_ge_vf (data_dependence_relation *ddr, > /* Dump LOWER_BOUND using flags DUMP_KIND. Dumps are known to be enabled. */ > > static void > -dump_lower_bound (int dump_kind, const vec_lower_bound &lower_bound) > +dump_lower_bound (dump_flags_t dump_kind, const vec_lower_bound &lower_bound) > { > dump_printf (dump_kind, "%s (", lower_bound.unsigned_p ? "unsigned" : "abs"); > dump_generic_expr (dump_kind, TDF_SLIM, lower_bound.expr); > -- > 1.8.5.3 >
On Fri, Jun 01, 2018 at 12:00:09PM +0200, Richard Biener wrote: > On Tue, May 29, 2018 at 10:32 PM David Malcolm <dmalcolm@redhat.com> wrote: > > > > The dump machinery uses "int" in a few places, for two different > > sets of bitmasks. > > > > This patch makes things more self-documenting and type-safe by using > > a new pair of enums: one for the dump_flags_t and another for the > > optgroup_flags. > > Great! This should also make them accessible in gdb w/o using -g3. > > > This requires adding some overloaded bit operations to the enums > > in question, which, in this patch is done for each enum . If the basic > > idea is OK, should I add a template for this? (with some kind of > > magic to express that bitmasking operations are only supported on > > certain opt-in enums). You may want to look at gdb's enum-flags.h which I think already implements what your doing here. > > Does C++ allow > int enums? I think we want some way of knowing > when either enum exceeds int (dump_flags_t was already uint64_t > but you now make it effectively int again). That is, general wrapping > for enum ops should chose an appropriate unsigned integer for > the operation. So yes, a common implementation looks useful to me. I don't remember very well, but istr C++ will actually use a 8 byte integer if the enum contains constants larger than 2^32. Testing sizeof enum x { A =0x400000000 }; gives the desired thing for me, but it would still be good to check the standard. Trev > > I think this patch is independently useful. > > Thanks, > Richard. > > >
On Tue, 2018-06-05 at 04:40 -0400, Trevor Saunders wrote: > On Fri, Jun 01, 2018 at 12:00:09PM +0200, Richard Biener wrote: > > On Tue, May 29, 2018 at 10:32 PM David Malcolm <dmalcolm@redhat.com > > > wrote: > > > > > > The dump machinery uses "int" in a few places, for two different > > > sets of bitmasks. > > > > > > This patch makes things more self-documenting and type-safe by > > > using > > > a new pair of enums: one for the dump_flags_t and another for the > > > optgroup_flags. > > > > Great! This should also make them accessible in gdb w/o using -g3. > > > > > This requires adding some overloaded bit operations to the enums > > > in question, which, in this patch is done for each enum . If the > > > basic > > > idea is OK, should I add a template for this? (with some kind of > > > magic to express that bitmasking operations are only supported on > > > certain opt-in enums). > > You may want to look at gdb's enum-flags.h which I think already > implements what your doing here. Aha! Thanks! Browsing the git web UI, that gdb header was introduced by Pedro Alves in: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=8d297bbf604c8318ffc72d5a7b3db654409c5ed9 and the current state is here: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/enum-flags.h;hb=HEAD I'll try this out with GCC; hopefully it works with C++98. Presumably it would be good to share this header between GCC and GDB; CCing Pedro; Pedro: hi! Does this sound sane? (for reference, the GCC patch we're discussing here is: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01685.html ) Presumably gcc's copy should live in the gcc's top-level "include" subdirectory? Would we need to change that "This file is part of GDB." comment, and the include guards' "COMMON_ENUM_FLAGS_H"? > > Does C++ allow > int enums? I think we want some way of knowing > > when either enum exceeds int (dump_flags_t was already uint64_t > > but you now make it effectively int again). That is, general > > wrapping > > for enum ops should chose an appropriate unsigned integer for > > the operation. So yes, a common implementation looks useful to me. > > I don't remember very well, but istr C++ will actually use a 8 byte > integer if the enum contains constants larger than 2^32. Testing > sizeof enum x { A =0x400000000 }; gives the desired thing for me, but > it > would still be good to check the standard. FWIW C++11 onwards has a std::underlying_type for enums: http://en.cppreference.com/w/cpp/types/underlying_type (GCC is on C++98). The gdb header seems to emulate this via the use of sizeof(T) to select an appropriate integer_for_size specialization and thus the appropriate struct enum_underlying_type specialization (if I'm reading it right). > Trev > > > > > > I think this patch is independently useful. Richard: by this, did you mean that the patch is OK for trunk as-is? (keeping a more general bitflags enum patch as followup work) Note to self: still needs bootstrap-and-testing. > > Thanks, > > Richard. Thanks Dave
On 06/05/2018 03:49 PM, David Malcolm wrote: > On Tue, 2018-06-05 at 04:40 -0400, Trevor Saunders wrote: >> You may want to look at gdb's enum-flags.h which I think already >> implements what your doing here. > > Aha! Thanks! > > Browsing the git web UI, that gdb header was introduced by Pedro Alves > in: > https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=8d297bbf604c8318ffc72d5a7b3db654409c5ed9 > and the current state is here: > https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/enum-flags.h;hb=HEAD > > I'll try this out with GCC; hopefully it works with C++98. It should -- it was written/added while GDB still required C++98. Note I have a WIP series here: https://github.com/palves/gdb/commits/palves/cxx11-enum-flags that fixes a few things, and adds a bunch of unit tests. In the process, it uses C++11 constructs (hence the branch's name), but I think that can be reverted to still work with C++98. I had seen some noises recently about GCC maybe considering requiring C++11. Is that reasonable to expect in this cycle? (GDB requires GCC 4.8 or later, FWIW.) Getting that branch into master had fallen lower on my TODO, but if there's interest, I can try to finish it off soon, so we can share a better baseline. (I posted it once, but found some issues which I fixed since but never managed to repost.) > > Presumably it would be good to share this header between GCC and GDB; > CCing Pedro; Pedro: hi! Does this sound sane? > (for reference, the GCC patch we're discussing here is: > https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01685.html ) Sure! Thanks, Pedro Alves
On June 5, 2018 4:49:21 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote: >On Tue, 2018-06-05 at 04:40 -0400, Trevor Saunders wrote: >> On Fri, Jun 01, 2018 at 12:00:09PM +0200, Richard Biener wrote: >> > On Tue, May 29, 2018 at 10:32 PM David Malcolm <dmalcolm@redhat.com >> > > wrote: >> > > >> > > The dump machinery uses "int" in a few places, for two different >> > > sets of bitmasks. >> > > >> > > This patch makes things more self-documenting and type-safe by >> > > using >> > > a new pair of enums: one for the dump_flags_t and another for the >> > > optgroup_flags. >> > >> > Great! This should also make them accessible in gdb w/o using -g3. >> > >> > > This requires adding some overloaded bit operations to the enums >> > > in question, which, in this patch is done for each enum . If the >> > > basic >> > > idea is OK, should I add a template for this? (with some kind of >> > > magic to express that bitmasking operations are only supported on >> > > certain opt-in enums). >> >> You may want to look at gdb's enum-flags.h which I think already >> implements what your doing here. > >Aha! Thanks! > >Browsing the git web UI, that gdb header was introduced by Pedro Alves >in: >https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=8d297bbf604c8318ffc72d5a7b3db654409c5ed9 >and the current state is here: >https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/enum-flags.h;hb=HEAD > >I'll try this out with GCC; hopefully it works with C++98. > >Presumably it would be good to share this header between GCC and GDB; >CCing Pedro; Pedro: hi! Does this sound sane? >(for reference, the GCC patch we're discussing here is: > https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01685.html ) > >Presumably gcc's copy should live in the gcc's top-level "include" >subdirectory? > >Would we need to change that "This file is part of GDB." comment, and >the include guards' "COMMON_ENUM_FLAGS_H"? > >> > Does C++ allow > int enums? I think we want some way of knowing >> > when either enum exceeds int (dump_flags_t was already uint64_t >> > but you now make it effectively int again). That is, general >> > wrapping >> > for enum ops should chose an appropriate unsigned integer for >> > the operation. So yes, a common implementation looks useful to me. >> >> I don't remember very well, but istr C++ will actually use a 8 byte >> integer if the enum contains constants larger than 2^32. Testing >> sizeof enum x { A =0x400000000 }; gives the desired thing for me, but >> it >> would still be good to check the standard. > >FWIW C++11 onwards has a std::underlying_type for enums: > http://en.cppreference.com/w/cpp/types/underlying_type >(GCC is on C++98). The gdb header seems to emulate this via the use of >sizeof(T) to select an appropriate integer_for_size specialization and >thus the appropriate struct enum_underlying_type specialization (if I'm >reading it right). > >> Trev >> >> >> > >> > I think this patch is independently useful. > >Richard: by this, did you mean that the patch is OK for trunk as-is? Yes. Richard. >(keeping a more general bitflags enum patch as followup work) Note to >self: still needs bootstrap-and-testing. > >> > Thanks, >> > Richard. > >Thanks >Dave
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index dc76c99..efb41c5 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -2341,7 +2341,7 @@ c_pretty_printer::statement (tree stmt) if (pp_needs_newline (this)) pp_newline_and_indent (this, 0); - dump_generic_node (this, stmt, pp_indentation (this), 0, true); + dump_generic_node (this, stmt, pp_indentation (this), TDF_NONE, true); } diff --git a/gcc/cfg.c b/gcc/cfg.c index 11026e7..6d55516 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -545,8 +545,8 @@ DEBUG_FUNCTION void debug (edge_def &ref) { /* FIXME (crowl): Is this desireable? */ - dump_edge_info (stderr, &ref, 0, false); - dump_edge_info (stderr, &ref, 0, true); + dump_edge_info (stderr, &ref, TDF_NONE, false); + dump_edge_info (stderr, &ref, TDF_NONE, true); } DEBUG_FUNCTION void diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 87d864c..ea106e0 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -288,7 +288,7 @@ dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags) DEBUG_FUNCTION void debug (basic_block_def &ref) { - dump_bb (stderr, &ref, 0, 0); + dump_bb (stderr, &ref, 0, TDF_NONE); } DEBUG_FUNCTION void diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c index 0acc7a9..6af1445 100644 --- a/gcc/dumpfile.c +++ b/gcc/dumpfile.c @@ -50,8 +50,8 @@ const char *dump_file_name; dump_flags_t dump_flags; #define DUMP_FILE_INFO(suffix, swtch, dkind, num) \ - {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, 0, 0, 0, 0, 0, num, \ - false, false} + {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, TDF_NONE, TDF_NONE, \ + OPTGROUP_NONE, 0, 0, num, false, false} /* Table of tree dump switches. This must be consistent with the TREE_DUMP_INDEX enumeration in dumpfile.h. */ @@ -74,15 +74,16 @@ static struct dump_file_info dump_files[TDI_end] = }; /* Define a name->number mapping for a dump flag value. */ -struct dump_option_value_info +template <typename ValueType> +struct kv_pair { const char *const name; /* the name of the value */ - const dump_flags_t value; /* the value of the name */ + const ValueType value; /* the value of the name */ }; /* Table of dump options. This must be consistent with the TDF_* flags in dumpfile.h and opt_info_options below. */ -static const struct dump_option_value_info dump_options[] = +static const kv_pair<dump_flags_t> dump_options[] = { {"address", TDF_ADDRESS}, {"asmname", TDF_ASMNAME}, @@ -114,23 +115,23 @@ static const struct dump_option_value_info dump_options[] = {"all", dump_flags_t (~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_GRAPH | TDF_STMTADDR | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV | TDF_GIMPLE))}, - {NULL, 0} + {NULL, TDF_NONE} }; /* A subset of the dump_options table which is used for -fopt-info types. This must be consistent with the MSG_* flags in dumpfile.h. */ -static const struct dump_option_value_info optinfo_verbosity_options[] = +static const kv_pair<dump_flags_t> optinfo_verbosity_options[] = { {"optimized", MSG_OPTIMIZED_LOCATIONS}, {"missed", MSG_MISSED_OPTIMIZATION}, {"note", MSG_NOTE}, {"all", MSG_ALL}, - {NULL, 0} + {NULL, TDF_NONE} }; /* Flags used for -fopt-info groups. */ -static const struct dump_option_value_info optgroup_options[] = +static const kv_pair<optgroup_flags_t> optgroup_options[] = { {"ipa", OPTGROUP_IPA}, {"loop", OPTGROUP_LOOP}, @@ -138,7 +139,7 @@ static const struct dump_option_value_info optgroup_options[] = {"omp", OPTGROUP_OMP}, {"vec", OPTGROUP_VEC}, {"optall", OPTGROUP_ALL}, - {NULL, 0} + {NULL, OPTGROUP_NONE} }; gcc::dump_manager::dump_manager (): @@ -173,7 +174,8 @@ gcc::dump_manager::~dump_manager () unsigned int gcc::dump_manager:: dump_register (const char *suffix, const char *swtch, const char *glob, - dump_kind dkind, int optgroup_flags, bool take_ownership) + dump_kind dkind, optgroup_flags_t optgroup_flags, + bool take_ownership) { int num = m_next_dump++; @@ -410,7 +412,7 @@ dump_generic_expr (dump_flags_t dump_kind, dump_flags_t extra_dump_flags, location. */ void -dump_generic_expr_loc (int dump_kind, source_location loc, +dump_generic_expr_loc (dump_flags_t dump_kind, source_location loc, dump_flags_t extra_dump_flags, tree t) { if (dump_file && (dump_kind & pflags)) @@ -575,9 +577,9 @@ dump_finish (int phase) dfi->pstream = NULL; dump_file = NULL; alt_dump_file = NULL; - dump_flags = TDI_none; - alt_flags = 0; - pflags = 0; + dump_flags = TDF_NONE; + alt_flags = TDF_NONE; + pflags = TDF_NONE; } /* Begin a tree dump for PHASE. Stores any user supplied flag in @@ -750,7 +752,7 @@ dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename) int gcc::dump_manager:: -opt_info_enable_passes (int optgroup_flags, dump_flags_t flags, +opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags, const char *filename) { int n = 0; @@ -817,11 +819,11 @@ dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob) return 0; ptr = option_value; - flags = 0; + flags = TDF_NONE; while (*ptr) { - const struct dump_option_value_info *option_ptr; + const struct kv_pair<dump_flags_t> *option_ptr; const char *end_ptr; const char *eq_ptr; unsigned length; @@ -903,8 +905,8 @@ dump_switch_p (const char *arg) and filename. Return non-zero if it is a recognized switch. */ static int -opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, - char **filename) +opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, + optgroup_flags_t *optgroup_flags, char **filename) { const char *option_value; const char *ptr; @@ -913,15 +915,14 @@ opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, ptr = option_value; *filename = NULL; - *flags = 0; - *optgroup_flags = 0; + *flags = TDF_NONE; + *optgroup_flags = OPTGROUP_NONE; if (!ptr) return 1; /* Handle '-fopt-info' without any additional options. */ while (*ptr) { - const struct dump_option_value_info *option_ptr; const char *end_ptr; const char *eq_ptr; unsigned length; @@ -938,8 +939,8 @@ opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, end_ptr = ptr + strlen (ptr); length = end_ptr - ptr; - for (option_ptr = optinfo_verbosity_options; option_ptr->name; - option_ptr++) + for (const kv_pair<dump_flags_t> *option_ptr = optinfo_verbosity_options; + option_ptr->name; option_ptr++) if (strlen (option_ptr->name) == length && !memcmp (option_ptr->name, ptr, length)) { @@ -947,7 +948,8 @@ opt_info_switch_p_1 (const char *arg, dump_flags_t *flags, int *optgroup_flags, goto found; } - for (option_ptr = optgroup_options; option_ptr->name; option_ptr++) + for (const kv_pair<optgroup_flags_t> *option_ptr = optgroup_options; + option_ptr->name; option_ptr++) if (strlen (option_ptr->name) == length && !memcmp (option_ptr->name, ptr, length)) { @@ -982,7 +984,7 @@ int opt_info_switch_p (const char *arg) { dump_flags_t flags; - int optgroup_flags; + optgroup_flags_t optgroup_flags; char *filename; static char *file_seen = NULL; gcc::dump_manager *dumps = g->get_dumps (); diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h index 21803a6..b5582f7 100644 --- a/gcc/dumpfile.h +++ b/gcc/dumpfile.h @@ -58,65 +58,177 @@ enum dump_kind the DUMP_OPTIONS array in dumpfile.c. The TDF_* flags coexist with MSG_* flags (for -fopt-info) and the bit values must be chosen to allow that. */ -#define TDF_ADDRESS (1 << 0) /* dump node addresses */ -#define TDF_SLIM (1 << 1) /* don't go wild following links */ -#define TDF_RAW (1 << 2) /* don't unparse the function */ -#define TDF_DETAILS (1 << 3) /* show more detailed info about - each pass */ -#define TDF_STATS (1 << 4) /* dump various statistics about - each pass */ -#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */ -#define TDF_VOPS (1 << 6) /* display virtual operands */ -#define TDF_LINENO (1 << 7) /* display statement line numbers */ -#define TDF_UID (1 << 8) /* display decl UIDs */ - -#define TDF_STMTADDR (1 << 9) /* Address of stmt. */ - -#define TDF_GRAPH (1 << 10) /* a graph dump is being emitted */ -#define TDF_MEMSYMS (1 << 11) /* display memory symbols in expr. - Implies TDF_VOPS. */ - -#define TDF_RHS_ONLY (1 << 12) /* a flag to only print the RHS of - a gimple stmt. */ -#define TDF_ASMNAME (1 << 13) /* display asm names of decls */ -#define TDF_EH (1 << 14) /* display EH region number - holding this gimple statement. */ -#define TDF_NOUID (1 << 15) /* omit UIDs from dumps. */ -#define TDF_ALIAS (1 << 16) /* display alias information */ -#define TDF_ENUMERATE_LOCALS (1 << 17) /* Enumerate locals by uid. */ -#define TDF_CSELIB (1 << 18) /* Dump cselib details. */ -#define TDF_SCEV (1 << 19) /* Dump SCEV details. */ -#define TDF_GIMPLE (1 << 20) /* Dump in GIMPLE FE syntax */ -#define TDF_FOLDING (1 << 21) /* Dump folding details. */ -#define MSG_OPTIMIZED_LOCATIONS (1 << 22) /* -fopt-info optimized sources */ -#define MSG_MISSED_OPTIMIZATION (1 << 23) /* missed opportunities */ -#define MSG_NOTE (1 << 24) /* general optimization info */ -#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \ - | MSG_NOTE) -#define TDF_COMPARE_DEBUG (1 << 25) /* Dumping for -fcompare-debug. */ - - -/* Value of TDF_NONE is used just for bits filtered by TDF_KIND_MASK. */ - -#define TDF_NONE 0 +enum dump_flag +{ + /* 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), + + /* -fopt-info optimized sources. */ + MSG_OPTIMIZED_LOCATIONS = (1 << 22), + + /* Missed opportunities. */ + MSG_MISSED_OPTIMIZATION = (1 << 23), + + /* General optimization info. */ + MSG_NOTE = (1 << 24), + + MSG_ALL = (MSG_OPTIMIZED_LOCATIONS + | MSG_MISSED_OPTIMIZATION + | MSG_NOTE), + + /* Dumping for -fcompare-debug. */ + TDF_COMPARE_DEBUG = (1 << 25), +}; + +/* Dump flags type. */ + +typedef enum dump_flag dump_flags_t; + +// FIXME: template +// FIXME: underlying storage type? +static inline dump_flags_t +operator| (dump_flags_t lhs, dump_flags_t rhs) +{ + return (dump_flags_t)((int)lhs | (int)rhs); +} + +static inline dump_flags_t +operator& (dump_flags_t lhs, dump_flags_t rhs) +{ + return (dump_flags_t)((int)lhs & (int)rhs); +} + +static inline dump_flags_t +operator~ (dump_flags_t flags) +{ + return (dump_flags_t)~((int)flags); +} + +static inline dump_flags_t & +operator|= (dump_flags_t &lhs, dump_flags_t rhs) +{ + lhs = (dump_flags_t)((int)lhs | (int)rhs); + return lhs; +} + +static inline dump_flags_t & +operator&= (dump_flags_t &lhs, dump_flags_t rhs) +{ + lhs = (dump_flags_t)((int)lhs & (int)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. */ -#define OPTGROUP_NONE (0) -#define OPTGROUP_IPA (1 << 1) /* IPA optimization passes */ -#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */ -#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */ -#define OPTGROUP_OMP (1 << 4) /* OMP (Offloading and Multi - Processing) transformations */ -#define OPTGROUP_VEC (1 << 5) /* Vectorization passes */ -#define OPTGROUP_OTHER (1 << 6) /* All other passes */ -#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \ - | OPTGROUP_OMP | OPTGROUP_VEC | OPTGROUP_OTHER) -/* Dump flags type. */ +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), -typedef uint64_t dump_flags_t; + /* 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; + +static inline optgroup_flags_t +operator| (optgroup_flags_t lhs, optgroup_flags_t rhs) +{ + return (optgroup_flags_t)((int)lhs | (int)rhs); +} + +static inline optgroup_flags_t & +operator|= (optgroup_flags_t &lhs, optgroup_flags_t rhs) +{ + lhs = (optgroup_flags_t)((int)lhs | (int)rhs); + return lhs; +} /* Define a tree dump switch. */ struct dump_file_info @@ -140,9 +252,9 @@ struct dump_file_info /* Dump flags. */ dump_flags_t pflags; /* A pass flags for -fopt-info. */ - int alt_flags; + dump_flags_t alt_flags; /* Flags for -fopt-info given by a user. */ - int optgroup_flags; + optgroup_flags_t optgroup_flags; /* State of pass-specific stream. */ int pstate; /* State of the -fopt-info stream. */ @@ -214,7 +326,8 @@ public: SUFFIX, SWTCH, and GLOB. */ unsigned int dump_register (const char *suffix, const char *swtch, const char *glob, - dump_kind dkind, int optgroup_flags, bool take_ownership); + dump_kind dkind, optgroup_flags_t optgroup_flags, + bool take_ownership); /* Allow languages and middle-end to register their dumps before the optimization passes. */ @@ -275,7 +388,7 @@ private: dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename); int - opt_info_enable_passes (int optgroup_flags, dump_flags_t flags, + opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags, const char *filename); private: diff --git a/gcc/early-remat.c b/gcc/early-remat.c index 28eb9b4..776b2d0 100644 --- a/gcc/early-remat.c +++ b/gcc/early-remat.c @@ -657,7 +657,7 @@ early_remat::dump_edge_list (basic_block bb, bool do_succ) edge e; edge_iterator ei; FOR_EACH_EDGE (e, ei, do_succ ? bb->succs : bb->preds) - dump_edge_info (dump_file, e, 0, do_succ); + dump_edge_info (dump_file, e, TDF_NONE, do_succ); } /* Print information about basic block BB to the dump file. */ diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 6695526..39edaa1 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -153,7 +153,7 @@ print_gimple_stmt (FILE *file, gimple *g, int spc, dump_flags_t flags) DEBUG_FUNCTION void debug (gimple &ref) { - print_gimple_stmt (stderr, &ref, 0, 0); + print_gimple_stmt (stderr, &ref, 0, TDF_NONE); } DEBUG_FUNCTION void diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 6f6538b..7362128 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -1075,7 +1075,7 @@ bswap_replace (gimple_stmt_iterator gsi, gimple *ins_stmt, tree fndecl, print_gimple_stmt (dump_file, cur_stmt, 0); else { - print_generic_expr (dump_file, tgt, 0); + print_generic_expr (dump_file, tgt, TDF_NONE); fprintf (dump_file, "\n"); } } @@ -1145,7 +1145,7 @@ bswap_replace (gimple_stmt_iterator gsi, gimple *ins_stmt, tree fndecl, print_gimple_stmt (dump_file, cur_stmt, 0); else { - print_generic_expr (dump_file, tgt, 0); + print_generic_expr (dump_file, tgt, TDF_NONE); fprintf (dump_file, "\n"); } } @@ -1956,7 +1956,7 @@ merged_store_group::apply_stores () if (ret) { fprintf (dump_file, "After writing "); - print_generic_expr (dump_file, cst, 0); + print_generic_expr (dump_file, cst, TDF_NONE); fprintf (dump_file, " of size " HOST_WIDE_INT_PRINT_DEC " at position %d the merged region contains:\n", info->bitsize, pos_in_buffer); diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index 1c00f09..14fc420 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -3353,7 +3353,7 @@ insert_initializers (slsr_cand_t c) fputs ("Using existing initializer: ", dump_file); print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (incr_vec[i].initializer), - 0, 0); + 0, TDF_NONE); } continue; } diff --git a/gcc/gimple.c b/gcc/gimple.c index 9dc4911..c18526a 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3148,7 +3148,7 @@ static void verify_gimple_pp (const char *expected, gimple *stmt) { pretty_printer pp; - pp_gimple_stmt_1 (&pp, stmt, 0 /* spc */, 0 /* flags */); + pp_gimple_stmt_1 (&pp, stmt, 0 /* spc */, TDF_NONE /* flags */); ASSERT_STREQ (expected, pp_formatted_text (&pp)); } diff --git a/gcc/passes.c b/gcc/passes.c index ad0a912..62fd413 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -784,7 +784,7 @@ pass_manager::register_one_dump_file (opt_pass *pass) char num[11]; dump_kind dkind; int id; - int optgroup_flags = OPTGROUP_NONE; + optgroup_flags_t optgroup_flags = OPTGROUP_NONE; gcc::dump_manager *dumps = m_ctxt->get_dumps (); /* See below in next_pass_1. */ diff --git a/gcc/print-tree.c b/gcc/print-tree.c index caf5f26..5c736c5 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -894,7 +894,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent, { pretty_printer buffer; buffer.buffer->stream = file; - pp_gimple_stmt_1 (&buffer, SSA_NAME_DEF_STMT (node), indent + 4, 0); + pp_gimple_stmt_1 (&buffer, SSA_NAME_DEF_STMT (node), indent + 4, + TDF_NONE); pp_flush (&buffer); } @@ -1039,7 +1040,7 @@ dump_tree_via_hooks (const tree_node *ptr, dump_flags_t options) DEBUG_FUNCTION void debug (const tree_node &ref) { - dump_tree_via_hooks (&ref, 0); + dump_tree_via_hooks (&ref, TDF_NONE); } DEBUG_FUNCTION void @@ -1070,7 +1071,7 @@ DEBUG_FUNCTION void debug_body (const tree_node &ref) { if (TREE_CODE (&ref) == FUNCTION_DECL) - dump_function_to_file (const_cast <tree_node*> (&ref), stderr, 0); + dump_function_to_file (const_cast <tree_node*> (&ref), stderr, TDF_NONE); else debug (ref); } diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 93a6a99..c757591 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -47,7 +47,7 @@ struct pass_data const char *name; /* The -fopt-info optimization group flags as defined in dumpfile.h. */ - unsigned int optinfo_flags; + optgroup_flags_t optinfo_flags; /* The timevar id associated with this pass. */ /* ??? Ideally would be dynamically assigned. */ diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 276ad00..8963ae0 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -3404,7 +3404,7 @@ print_struct_decl (pretty_printer *pp, const_tree node, int spc, || TREE_CODE (node) == QUAL_UNION_TYPE)) pp_string (pp, "union "); - dump_generic_node (pp, TYPE_NAME (node), spc, 0, false); + dump_generic_node (pp, TYPE_NAME (node), spc, TDF_NONE, false); } /* Print the contents of the structure. */ diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 16d9399..b3f8cb6 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -2710,7 +2710,7 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Generated FMA "); - print_gimple_stmt (dump_file, fma_stmt, 0, 0); + print_gimple_stmt (dump_file, fma_stmt, 0, TDF_NONE); fprintf (dump_file, "\n"); } @@ -3046,7 +3046,7 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Deferred generating FMA for multiplication "); - print_gimple_stmt (dump_file, mul_stmt, 0, 0); + print_gimple_stmt (dump_file, mul_stmt, 0, TDF_NONE); fprintf (dump_file, "\n"); } diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 0e59bb5..dde9701 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -1606,7 +1606,7 @@ undistribute_ops_list (enum tree_code opcode, { fprintf (dump_file, "searching for un-distribute opportunities "); print_generic_expr (dump_file, - (*ops)[bitmap_first_set_bit (candidates)]->op, 0); + (*ops)[bitmap_first_set_bit (candidates)]->op, TDF_NONE); fprintf (dump_file, " %d\n", nr_candidates); } diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 1463c1d..d8ab1f0 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -5921,7 +5921,7 @@ vn_eliminate (bitmap inserted_exprs) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Removing dead stmt "); - print_gimple_stmt (dump_file, stmt, 0, 0); + print_gimple_stmt (dump_file, stmt, 0, TDF_NONE); } gimple_stmt_iterator gsi = gsi_for_stmt (stmt); diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 9aabcc1..ebc56c0 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3229,7 +3229,7 @@ dependence_distance_ge_vf (data_dependence_relation *ddr, /* Dump LOWER_BOUND using flags DUMP_KIND. Dumps are known to be enabled. */ static void -dump_lower_bound (int dump_kind, const vec_lower_bound &lower_bound) +dump_lower_bound (dump_flags_t dump_kind, const vec_lower_bound &lower_bound) { dump_printf (dump_kind, "%s (", lower_bound.unsigned_p ? "unsigned" : "abs"); dump_generic_expr (dump_kind, TDF_SLIM, lower_bound.expr);