Message ID | 20100710002250.z5dvg6z1ckkgg480-nzlynne@webmail.spamcop.net |
---|---|
State | New |
Headers | show |
On Sat, Jul 10, 2010 at 6:22 AM, Joern Rennecke <amylaar@spamcop.net> wrote: > I abandoned my earlier approach to show the scope blocks; while it is nice > for debugging, it needs to much internal knowledge of what it means for > a symbol to be in the block, and which symbols/ declarations must be > skipped, > and it is not really good at spotting order issues with symbols that are > not in the scope blocks. > So instead, I gather a list of all the declarations that are used by the > gimple statements and the trees they contains, sort them according to uid, > and emit them with a number indicating where in the depth-first search > of the gimple/trees each declaration was encountered first. > > Because this is basically a list of 'live' declarations, I've put in in > tree-ssa-live.c . > > The regression test for pr42806 originally caused a crash in > print_declaration, which is why I added the new test for TREE_TYPE (t) > there. > > Bootstrapped & regression tested on i686-pc-linux-gnu. As desired, > the new test flags PR44832: > FAIL: c-c++-common/pr44832.c (test for excess errors) > FAIL: c-c++-common/pr44832.c -Wc++-compat (test for excess errors) > Otherwise, there are no new failures. > > The patch I have for PR44832 passes this new test. > > tested build of 'all-gcc' for i686-pc-linux-gnu X alpha-linux-gnu > using configure options --enable-build-with-cxx' '--enable-werror-always and > gcc (GCC) 4.6.0 20100630 (experimental). > > Bootstrapped on x86_64-unknown-linux-gnu. > The new test triggers there for both gcc and g++, too. > > 2010-07-10 Joern Rennecke <joern.rennecke@embecosm.com> > > gcc: > * tree-dump.c (dump_options): Add enumerate_locals entry. > Add TDF_NOID exclusion to all entry. > * tree-dump.h (dump_enumerated_decls): Declare. > * tree-pretty-print.c (dump_generic_node): For TDF_NOID, > Don't display type uid. > (print_declaration): Don't crash on TREE_TYPE (t) == 0. > * tree-pass.h (TDF_ENUMERATE_LOCALS): Define. > * tree-ssa-live.c: Include gimple.h. > (numbered_tree_d): New struct. > (numbered_tree): New typedef. > (DEF_VEC_O (numbered_tree): New. > (DEF_VEC_ALLOC_O (numbered_tree, heap)): Likewise. > (compare_decls_by_uid, dump_enumerated_decls_push): New functions. > (dump_enumerated_decls): Likewise. > * tree-optimize.c (execute_cleanup_cfg_post_optimizing): > If flag_dump_final_insns, call dump_enumerated_decls. > * tree-cfg.c (dump_function_to_file): Call dump_enumerated_decls. > * Makefile.in (tree-ssa-live.o): Depend on $(GIMPLE_H). > gcc/testsuite: > * c-c++-common/pr44832.c: New test. > > Index: gcc/tree-dump.c > =================================================================== > --- gcc/tree-dump.c (revision 161952) > +++ gcc/tree-dump.c (working copy) > @@ -821,9 +821,10 @@ static const struct dump_option_value_in > {"eh", TDF_EH}, > {"alias", TDF_ALIAS}, > {"nouid", TDF_NOUID}, > + {"enumerate_locals", TDF_ENUMERATE_LOCALS}, > {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA > | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE > - | TDF_RHS_ONLY | TDF_NOUID)}, > + | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS)}, > {NULL, 0} > }; > > Index: gcc/tree-dump.h > =================================================================== > --- gcc/tree-dump.h (revision 161952) > +++ gcc/tree-dump.h (working copy) > @@ -91,6 +91,7 @@ extern void queue_and_dump_index (dump_i > extern void queue_and_dump_type (dump_info_p, const_tree); > extern void dump_function (int, tree); > extern void dump_function_to_file (tree, FILE *, int); > +extern void dump_enumerated_decls (FILE *, int); > extern void debug_function (tree, int); > extern int dump_flag (dump_info_p, int, const_tree); > > Index: gcc/tree-pretty-print.c > =================================================================== > --- gcc/tree-pretty-print.c (revision 161952) > +++ gcc/tree-pretty-print.c (working copy) > @@ -757,6 +757,8 @@ dump_generic_node (pretty_printer *buffe > pp_string (buffer, str); > if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node))) > dump_decl_name (buffer, TYPE_NAME (node), flags); > + else if (flags & TDF_NOUID) > + pp_printf (buffer, "<Txxxx>"); > else > pp_printf (buffer, "<T%x>", TYPE_UID (node)); > > @@ -1081,6 +1083,8 @@ dump_generic_node (pretty_printer *buffe > } > if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node))) > dump_decl_name (buffer, TYPE_NAME (node), flags); > + else if (flags & TDF_NOUID) > + pp_printf (buffer, "<Txxxx>"); > else > pp_printf (buffer, "<T%x>", TYPE_UID (node)); > dump_function_declaration (buffer, node, spc, flags); > @@ -2310,7 +2314,7 @@ print_declaration (pretty_printer *buffe > pp_string (buffer, "static "); > > /* Print the type and name. */ > - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) > + if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) > { > tree tmp; > > Index: gcc/tree-pass.h > =================================================================== > --- gcc/tree-pass.h (revision 161952) > +++ gcc/tree-pass.h (working copy) > @@ -81,6 +81,7 @@ enum tree_dump_index > holding this gimple statement. */ > #define TDF_NOUID (1 << 20) /* omit UIDs from dumps. */ > #define TDF_ALIAS (1 << 21) /* display alias information */ > +#define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */ > > > /* In tree-dump.c */ > Index: gcc/testsuite/c-c++-common/pr44832.c > =================================================================== > --- gcc/testsuite/c-c++-common/pr44832.c (revision 0) > +++ gcc/testsuite/c-c++-common/pr44832.c (revision 0) > @@ -0,0 +1,160 @@ > +/* PR debug/44832 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fcompare-debug" } */ > + > +struct rtx_def; > +typedef struct rtx_def *rtx; > +typedef const struct rtx_def *const_rtx; > +struct rtvec_def; > +typedef struct rtvec_def *rtvec; > +extern int ix86_isa_flags; > + > +enum machine_mode > +{ > + VOIDmode, > + V8HImode, > + V16QImode, > + V4SImode, > + V2DImode, > + V32QImode, > + MAX_MACHINE_MODE, > + > + NUM_MACHINE_MODES = MAX_MACHINE_MODE > +}; > +extern unsigned char mode_size[NUM_MACHINE_MODES]; > +extern const unsigned char mode_inner[NUM_MACHINE_MODES]; > +extern const unsigned char mode_nunits[NUM_MACHINE_MODES]; > +enum rtx_code { > + > +CONST_INT , > + > +CONST_FIXED , > + > +CONST_DOUBLE > + > + }; > +union rtunion_def > +{ > + rtvec rt_rtvec; > +}; > +typedef union rtunion_def rtunion; > +struct rtx_def { > + > + __extension__ enum rtx_code code: 16; > + > + __extension__ enum machine_mode mode : 8; > + > + union u { > + rtunion fld[1]; > + } u; > +}; > +struct rtvec_def { > + rtx elem[1]; > +}; > +extern int rtx_equal_p (const_rtx, const_rtx); > +extern rtx gen_reg_rtx (enum machine_mode); > + > +extern void > +ix86_expand_vector_init_concat (enum machine_mode mode, > + rtx target, rtx *ops, int n); > + > +static void > +ix86_expand_vector_init_general (unsigned char mmx_ok, enum machine_mode > mode, > + rtx target, rtx vals) > +{ > + rtx ops[32], op0, op1; > + enum machine_mode half_mode = VOIDmode; > + int n, i; > + > + switch (mode) > + { > + case V4SImode: > + case V2DImode: > + n = mode_nunits[mode]; > + ix86_expand_vector_init_concat (mode, target, ops, n); > + return; > + > + case V32QImode: > + goto half; > +half: > +{ > + typedef int eger; > + if (mode != V4SImode) > + ops[0] = 0; > +} > + n = mode_nunits[mode]; > + for (i = 0; i < n; i++) > + ops[i] = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]); > + op0 = gen_reg_rtx (VOIDmode); > + return; > + > + case V16QImode: > + if (!((ix86_isa_flags & (1 << 19)) != 0)) > + break; > + > + case V8HImode: > + if (!((ix86_isa_flags & (1 << 17)) != 0)) > + break; > + > + n = mode_nunits[mode]; > + for (i = 0; i < n; i++) > + ops[i] = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]); > + return; > + > + default: > + ; > + } > + > + { > + int n_words; > + > + n_words = ((unsigned short) mode_size[mode]) / 4; > + > + if (n_words == 4) > + ix86_expand_vector_init_general (0, V4SImode, 0, 0); > + } > +} > + > + > +void > +ix86_expand_vector_init (unsigned char mmx_ok, rtx target, rtx vals) > +{ > + enum machine_mode mode = ((enum machine_mode) (target)->mode); > + enum machine_mode inner_mode = ((enum machine_mode) mode_inner[mode]); > + int n_elts = mode_nunits[mode]; > + int n_var = 0, one_var = -1; > + unsigned char all_same = 1, all_const_zero = 1; > + int i; > + rtx x; > + > + for (i = 0; i < n_elts; ++i) > + { > + x = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]); > + if (!((((enum rtx_code) (x)->code) == CONST_INT) > + || ((enum rtx_code) (x)->code) == CONST_DOUBLE > + || ((enum rtx_code) (x)->code) == CONST_FIXED)) > + n_var++, one_var = i; > + else > + all_const_zero = 0; > + if (i > 0 && !rtx_equal_p (x, > (((((vals)->u.fld[0]).rt_rtvec))->elem[0]))) > + all_same = 0; > + } > + > + > + if (n_var == 0) > + { > + return; > + } > + > + if (all_same) > + return; > + > + if (n_var == 1) > + { > + if (all_const_zero) > + return; > + > + } > + > + ix86_expand_vector_init_general (mmx_ok, mode, target, vals); > +} > Index: gcc/tree-ssa-live.c > =================================================================== > --- gcc/tree-ssa-live.c (revision 161952) > +++ gcc/tree-ssa-live.c (working copy) > @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. > #include "toplev.h" > #include "debug.h" > #include "flags.h" > +#include "gimple.h" > > #ifdef ENABLE_CHECKING > static void verify_live_on_entry (tree_live_info_p); > @@ -1164,6 +1165,95 @@ dump_live_info (FILE *f, tree_live_info_ > } > } > > +struct GTY(()) numbered_tree_d > +{ > + tree t; > + int num; > +}; > +typedef struct numbered_tree_d numbered_tree; > + > +DEF_VEC_O (numbered_tree); > +DEF_VEC_ALLOC_O (numbered_tree, heap); > + > +/* Compare two declarations references by their DECL_UID / sequence number. > + Called via qsort. */ > + > +static int > +compare_decls_by_uid (const void *pa, const void *pb) > +{ > + const numbered_tree *nt_a = ((const numbered_tree *)pa); > + const numbered_tree *nt_b = ((const numbered_tree *)pb); > + > + if (DECL_UID (nt_a->t) != DECL_UID (nt_b->t)) > + return DECL_UID (nt_a->t) - DECL_UID (nt_b->t); > + return nt_a->num - nt_b->num; > +} > + > +/* Called via walk_gimple_stmt / walk_gimple_op by dump_enumerated_decls. > */ > +static tree > +dump_enumerated_decls_push (tree *tp, int *walk_subtrees, void *data) > +{ > + struct walk_stmt_info *wi = (struct walk_stmt_info *) data; > + VEC (numbered_tree, heap) **list = (VEC (numbered_tree, heap) **) > &wi->info; > + numbered_tree nt; > + > + if (!DECL_P (*tp)) > + return NULL_TREE; > + nt.t = *tp; > + nt.num = VEC_length (numbered_tree, *list); > + VEC_safe_push (numbered_tree, heap, *list, &nt); > + *walk_subtrees = 0; > + return NULL_TREE; > +} > + > +/* Find all the declarations used by the current function, sort them by > uid, > + and emit the sorted list. Each declaration is tagged with a sequence > + number indicating when it was found during statement / tree walking, > + so that TDF_NOUID comparisons of anonymous declarations are still > + meaningful. Where a declaration was encountered more than once, we > + emit only the sequence number of the first encounter. > + FILE is the dump file where to output the list and FLAGS is as in > + print_generic_expr. */ > +void > +dump_enumerated_decls (FILE *file, int flags) > +{ > + basic_block bb; > + struct walk_stmt_info wi; > + VEC (numbered_tree, heap) *decl_list = VEC_alloc (numbered_tree, heap, > 40); > + > + wi.info = (void*) decl_list; > + wi.pset = NULL; > + FOR_EACH_BB (bb) > + { > + gimple_stmt_iterator gsi; > + > + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) > + if (!is_gimple_debug (gsi_stmt (gsi))) > + walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi); > + } > + decl_list = (VEC (numbered_tree, heap) *) wi.info; > + qsort (VEC_address (numbered_tree, decl_list), > + VEC_length (numbered_tree, decl_list), > + sizeof (numbered_tree), compare_decls_by_uid); > + if (VEC_length (numbered_tree, decl_list)) > + { > + unsigned ix; > + numbered_tree *ntp; > + tree last = NULL_TREE; > + > + fprintf (file, "Used declarations sorted by DECL_UID:\n"); > + for (ix = 0; VEC_iterate (numbered_tree, decl_list, ix, ntp); ix++) > + { > + if (ntp->t == last) > + continue; > + fprintf (file, "%d: ", ntp->num); > + print_generic_decl (file, ntp->t, flags); > + fprintf (file, "\n"); > + last = ntp->t; > + } > + } > + VEC_free (numbered_tree, heap, decl_list); > +} > > #ifdef ENABLE_CHECKING > /* Verify that SSA_VAR is a non-virtual SSA_NAME. */ > Index: gcc/tree-optimize.c > =================================================================== > --- gcc/tree-optimize.c (revision 161952) > +++ gcc/tree-optimize.c (working copy) > @@ -191,6 +191,34 @@ execute_cleanup_cfg_post_optimizing (voi > cleanup_tree_cfg (); > cleanup_dead_labels (); > group_case_labels (); > + if (flag_dump_final_insns) Please restrict this to flag_compare_debug_opt || flag_compare_debug. > + { > + FILE *final_output = fopen (flag_dump_final_insns, "a"); > + > + if (!final_output) > + { > + error ("could not open final insn dump file %qs: %m", > + flag_dump_final_insns); > + flag_dump_final_insns = NULL; > + } > + else > + { > + int save_unnumbered = flag_dump_unnumbered; > + int save_noaddr = flag_dump_noaddr; > + > + flag_dump_noaddr = flag_dump_unnumbered = 1; > + fprintf (final_output, "\n\n\n"); Excessive whitespace. Please dump the function name the locals are for, for example above, here: + fprintf (file, "Used declarations sorted by DECL_UID:\n"); otherwise the patch looks good. Please give others the chance to comment before checking it in. Also please make sure bootstrap with --with-build-config=bootstrap-debug-[big|lean] works. I suppose you want to delay this patch until the a for the VRP label problem is applied. Thanks, Richard. > + dump_enumerated_decls (final_output, dump_flags | TDF_NOUID); > + flag_dump_noaddr = save_noaddr; > + flag_dump_unnumbered = save_unnumbered; > + if (fclose (final_output)) > + { > + error ("could not close final insn dump file %qs: %m", > + flag_dump_final_insns); > + flag_dump_final_insns = NULL; > + } > + } > + } > return 0; > } > > Index: gcc/Makefile.in > =================================================================== > --- gcc/Makefile.in (revision 161952) > +++ gcc/Makefile.in (working copy) > @@ -2448,7 +2448,7 @@ domwalk.o : domwalk.c $(CONFIG_H) $(SYST > tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ > $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ > $(TREE_SSA_LIVE_H) $(BITMAP_H) $(TOPLEV_H) debug.h $(FLAGS_H) \ > - tree-pretty-print.h gimple-pretty-print.h > + tree-pretty-print.h gimple-pretty-print.h $(GIMPLE_H) > tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \ > $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) \ > $(TREE_PASS_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) \ > Index: gcc/tree-cfg.c > =================================================================== > --- gcc/tree-cfg.c (revision 161952) > +++ gcc/tree-cfg.c (working copy) > @@ -6448,6 +6448,8 @@ dump_function_to_file (tree fn, FILE *fi > fprintf (file, "}\n"); > } > > + if (flags & TDF_ENUMERATE_LOCALS) > + dump_enumerated_decls (file, flags); > fprintf (file, "\n\n"); > > /* Restore CFUN. */ > >
Quoting Richard Guenther <richard.guenther@gmail.com>: > Also please make sure bootstrap with > --with-build-config=bootstrap-debug-[big|lean] > works. That's already broken. I've filed PR44901 for this failure.
On Fri, Jul 9, 2010 at 9:22 PM, Joern Rennecke <amylaar@spamcop.net> wrote: > I abandoned my earlier approach to show the scope blocks; while it is nice > for debugging, it needs to much internal knowledge of what it means for > a symbol to be in the block, and which symbols/ declarations must be > skipped, > and it is not really good at spotting order issues with symbols that are > not in the scope blocks. > So instead, I gather a list of all the declarations that are used by the > gimple statements and the trees they contains, sort them according to uid, > and emit them with a number indicating where in the depth-first search > of the gimple/trees each declaration was encountered first. > > Because this is basically a list of 'live' declarations, I've put in in > tree-ssa-live.c . > > The regression test for pr42806 originally caused a crash in > print_declaration, which is why I added the new test for TREE_TYPE (t) > there. > > Bootstrapped & regression tested on i686-pc-linux-gnu. As desired, > the new test flags PR44832: > FAIL: c-c++-common/pr44832.c (test for excess errors) > FAIL: c-c++-common/pr44832.c -Wc++-compat (test for excess errors) > Otherwise, there are no new failures. > > The patch I have for PR44832 passes this new test. > > tested build of 'all-gcc' for i686-pc-linux-gnu X alpha-linux-gnu > using configure options --enable-build-with-cxx' '--enable-werror-always and > gcc (GCC) 4.6.0 20100630 (experimental). > > Bootstrapped on x86_64-unknown-linux-gnu. > The new test triggers there for both gcc and g++, too. > > 2010-07-10 Joern Rennecke <joern.rennecke@embecosm.com> > > gcc: > * tree-dump.c (dump_options): Add enumerate_locals entry. > Add TDF_NOID exclusion to all entry. > * tree-dump.h (dump_enumerated_decls): Declare. > * tree-pretty-print.c (dump_generic_node): For TDF_NOID, > Don't display type uid. > (print_declaration): Don't crash on TREE_TYPE (t) == 0. > * tree-pass.h (TDF_ENUMERATE_LOCALS): Define. > * tree-ssa-live.c: Include gimple.h. > (numbered_tree_d): New struct. > (numbered_tree): New typedef. > (DEF_VEC_O (numbered_tree): New. > (DEF_VEC_ALLOC_O (numbered_tree, heap)): Likewise. > (compare_decls_by_uid, dump_enumerated_decls_push): New functions. > (dump_enumerated_decls): Likewise. > * tree-optimize.c (execute_cleanup_cfg_post_optimizing): > If flag_dump_final_insns, call dump_enumerated_decls. > * tree-cfg.c (dump_function_to_file): Call dump_enumerated_decls. > * Makefile.in (tree-ssa-live.o): Depend on $(GIMPLE_H). > gcc/testsuite: > * c-c++-common/pr44832.c: New test. > This patch may have introduced uninitialized variables: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45419 H.J.
On Thu, Aug 26, 2010 at 12:51 PM, H.J. Lu <hjl.tools@gmail.com> wrote: > On Fri, Jul 9, 2010 at 9:22 PM, Joern Rennecke <amylaar@spamcop.net> wrote: >> I abandoned my earlier approach to show the scope blocks; while it is nice >> for debugging, it needs to much internal knowledge of what it means for >> a symbol to be in the block, and which symbols/ declarations must be >> skipped, >> and it is not really good at spotting order issues with symbols that are >> not in the scope blocks. >> So instead, I gather a list of all the declarations that are used by the >> gimple statements and the trees they contains, sort them according to uid, >> and emit them with a number indicating where in the depth-first search >> of the gimple/trees each declaration was encountered first. >> >> Because this is basically a list of 'live' declarations, I've put in in >> tree-ssa-live.c . >> >> The regression test for pr42806 originally caused a crash in >> print_declaration, which is why I added the new test for TREE_TYPE (t) >> there. >> >> Bootstrapped & regression tested on i686-pc-linux-gnu. As desired, >> the new test flags PR44832: >> FAIL: c-c++-common/pr44832.c (test for excess errors) >> FAIL: c-c++-common/pr44832.c -Wc++-compat (test for excess errors) >> Otherwise, there are no new failures. >> >> The patch I have for PR44832 passes this new test. >> >> tested build of 'all-gcc' for i686-pc-linux-gnu X alpha-linux-gnu >> using configure options --enable-build-with-cxx' '--enable-werror-always and >> gcc (GCC) 4.6.0 20100630 (experimental). >> >> Bootstrapped on x86_64-unknown-linux-gnu. >> The new test triggers there for both gcc and g++, too. >> >> 2010-07-10 Joern Rennecke <joern.rennecke@embecosm.com> >> >> gcc: >> * tree-dump.c (dump_options): Add enumerate_locals entry. >> Add TDF_NOID exclusion to all entry. >> * tree-dump.h (dump_enumerated_decls): Declare. >> * tree-pretty-print.c (dump_generic_node): For TDF_NOID, >> Don't display type uid. >> (print_declaration): Don't crash on TREE_TYPE (t) == 0. >> * tree-pass.h (TDF_ENUMERATE_LOCALS): Define. >> * tree-ssa-live.c: Include gimple.h. >> (numbered_tree_d): New struct. >> (numbered_tree): New typedef. >> (DEF_VEC_O (numbered_tree): New. >> (DEF_VEC_ALLOC_O (numbered_tree, heap)): Likewise. >> (compare_decls_by_uid, dump_enumerated_decls_push): New functions. >> (dump_enumerated_decls): Likewise. >> * tree-optimize.c (execute_cleanup_cfg_post_optimizing): >> If flag_dump_final_insns, call dump_enumerated_decls. >> * tree-cfg.c (dump_function_to_file): Call dump_enumerated_decls. >> * Makefile.in (tree-ssa-live.o): Depend on $(GIMPLE_H). >> gcc/testsuite: >> * c-c++-common/pr44832.c: New test. >> > > This patch may have introduced uninitialized variables: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45419 > This also caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46583
Index: gcc/tree-dump.c =================================================================== --- gcc/tree-dump.c (revision 161952) +++ gcc/tree-dump.c (working copy) @@ -821,9 +821,10 @@ static const struct dump_option_value_in {"eh", TDF_EH}, {"alias", TDF_ALIAS}, {"nouid", TDF_NOUID}, + {"enumerate_locals", TDF_ENUMERATE_LOCALS}, {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE - | TDF_RHS_ONLY | TDF_NOUID)}, + | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS)}, {NULL, 0} }; Index: gcc/tree-dump.h =================================================================== --- gcc/tree-dump.h (revision 161952) +++ gcc/tree-dump.h (working copy) @@ -91,6 +91,7 @@ extern void queue_and_dump_index (dump_i extern void queue_and_dump_type (dump_info_p, const_tree); extern void dump_function (int, tree); extern void dump_function_to_file (tree, FILE *, int); +extern void dump_enumerated_decls (FILE *, int); extern void debug_function (tree, int); extern int dump_flag (dump_info_p, int, const_tree); Index: gcc/tree-pretty-print.c =================================================================== --- gcc/tree-pretty-print.c (revision 161952) +++ gcc/tree-pretty-print.c (working copy) @@ -757,6 +757,8 @@ dump_generic_node (pretty_printer *buffe pp_string (buffer, str); if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node))) dump_decl_name (buffer, TYPE_NAME (node), flags); + else if (flags & TDF_NOUID) + pp_printf (buffer, "<Txxxx>"); else pp_printf (buffer, "<T%x>", TYPE_UID (node)); @@ -1081,6 +1083,8 @@ dump_generic_node (pretty_printer *buffe } if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node))) dump_decl_name (buffer, TYPE_NAME (node), flags); + else if (flags & TDF_NOUID) + pp_printf (buffer, "<Txxxx>"); else pp_printf (buffer, "<T%x>", TYPE_UID (node)); dump_function_declaration (buffer, node, spc, flags); @@ -2310,7 +2314,7 @@ print_declaration (pretty_printer *buffe pp_string (buffer, "static "); /* Print the type and name. */ - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) + if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) { tree tmp; Index: gcc/tree-pass.h =================================================================== --- gcc/tree-pass.h (revision 161952) +++ gcc/tree-pass.h (working copy) @@ -81,6 +81,7 @@ enum tree_dump_index holding this gimple statement. */ #define TDF_NOUID (1 << 20) /* omit UIDs from dumps. */ #define TDF_ALIAS (1 << 21) /* display alias information */ +#define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */ /* In tree-dump.c */ Index: gcc/testsuite/c-c++-common/pr44832.c =================================================================== --- gcc/testsuite/c-c++-common/pr44832.c (revision 0) +++ gcc/testsuite/c-c++-common/pr44832.c (revision 0) @@ -0,0 +1,160 @@ +/* PR debug/44832 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcompare-debug" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; +typedef const struct rtx_def *const_rtx; +struct rtvec_def; +typedef struct rtvec_def *rtvec; +extern int ix86_isa_flags; + +enum machine_mode +{ + VOIDmode, + V8HImode, + V16QImode, + V4SImode, + V2DImode, + V32QImode, + MAX_MACHINE_MODE, + + NUM_MACHINE_MODES = MAX_MACHINE_MODE +}; +extern unsigned char mode_size[NUM_MACHINE_MODES]; +extern const unsigned char mode_inner[NUM_MACHINE_MODES]; +extern const unsigned char mode_nunits[NUM_MACHINE_MODES]; +enum rtx_code { + +CONST_INT , + +CONST_FIXED , + +CONST_DOUBLE + + }; +union rtunion_def +{ + rtvec rt_rtvec; +}; +typedef union rtunion_def rtunion; +struct rtx_def { + + __extension__ enum rtx_code code: 16; + + __extension__ enum machine_mode mode : 8; + + union u { + rtunion fld[1]; + } u; +}; +struct rtvec_def { + rtx elem[1]; +}; +extern int rtx_equal_p (const_rtx, const_rtx); +extern rtx gen_reg_rtx (enum machine_mode); + +extern void +ix86_expand_vector_init_concat (enum machine_mode mode, + rtx target, rtx *ops, int n); + +static void +ix86_expand_vector_init_general (unsigned char mmx_ok, enum machine_mode mode, + rtx target, rtx vals) +{ + rtx ops[32], op0, op1; + enum machine_mode half_mode = VOIDmode; + int n, i; + + switch (mode) + { + case V4SImode: + case V2DImode: + n = mode_nunits[mode]; + ix86_expand_vector_init_concat (mode, target, ops, n); + return; + + case V32QImode: + goto half; +half: +{ + typedef int eger; + if (mode != V4SImode) + ops[0] = 0; +} + n = mode_nunits[mode]; + for (i = 0; i < n; i++) + ops[i] = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]); + op0 = gen_reg_rtx (VOIDmode); + return; + + case V16QImode: + if (!((ix86_isa_flags & (1 << 19)) != 0)) + break; + + case V8HImode: + if (!((ix86_isa_flags & (1 << 17)) != 0)) + break; + + n = mode_nunits[mode]; + for (i = 0; i < n; i++) + ops[i] = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]); + return; + + default: + ; + } + + { + int n_words; + + n_words = ((unsigned short) mode_size[mode]) / 4; + + if (n_words == 4) + ix86_expand_vector_init_general (0, V4SImode, 0, 0); + } +} + + +void +ix86_expand_vector_init (unsigned char mmx_ok, rtx target, rtx vals) +{ + enum machine_mode mode = ((enum machine_mode) (target)->mode); + enum machine_mode inner_mode = ((enum machine_mode) mode_inner[mode]); + int n_elts = mode_nunits[mode]; + int n_var = 0, one_var = -1; + unsigned char all_same = 1, all_const_zero = 1; + int i; + rtx x; + + for (i = 0; i < n_elts; ++i) + { + x = (((((vals)->u.fld[0]).rt_rtvec))->elem[i]); + if (!((((enum rtx_code) (x)->code) == CONST_INT) + || ((enum rtx_code) (x)->code) == CONST_DOUBLE + || ((enum rtx_code) (x)->code) == CONST_FIXED)) + n_var++, one_var = i; + else + all_const_zero = 0; + if (i > 0 && !rtx_equal_p (x, (((((vals)->u.fld[0]).rt_rtvec))->elem[0]))) + all_same = 0; + } + + + if (n_var == 0) + { + return; + } + + if (all_same) + return; + + if (n_var == 1) + { + if (all_const_zero) + return; + + } + + ix86_expand_vector_init_general (mmx_ok, mode, target, vals); +} Index: gcc/tree-ssa-live.c =================================================================== --- gcc/tree-ssa-live.c (revision 161952) +++ gcc/tree-ssa-live.c (working copy) @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. #include "toplev.h" #include "debug.h" #include "flags.h" +#include "gimple.h" #ifdef ENABLE_CHECKING static void verify_live_on_entry (tree_live_info_p); @@ -1164,6 +1165,95 @@ dump_live_info (FILE *f, tree_live_info_ } } +struct GTY(()) numbered_tree_d +{ + tree t; + int num; +}; +typedef struct numbered_tree_d numbered_tree; + +DEF_VEC_O (numbered_tree); +DEF_VEC_ALLOC_O (numbered_tree, heap); + +/* Compare two declarations references by their DECL_UID / sequence number. + Called via qsort. */ + +static int +compare_decls_by_uid (const void *pa, const void *pb) +{ + const numbered_tree *nt_a = ((const numbered_tree *)pa); + const numbered_tree *nt_b = ((const numbered_tree *)pb); + + if (DECL_UID (nt_a->t) != DECL_UID (nt_b->t)) + return DECL_UID (nt_a->t) - DECL_UID (nt_b->t); + return nt_a->num - nt_b->num; +} + +/* Called via walk_gimple_stmt / walk_gimple_op by dump_enumerated_decls. */ +static tree +dump_enumerated_decls_push (tree *tp, int *walk_subtrees, void *data) +{ + struct walk_stmt_info *wi = (struct walk_stmt_info *) data; + VEC (numbered_tree, heap) **list = (VEC (numbered_tree, heap) **) &wi->info; + numbered_tree nt; + + if (!DECL_P (*tp)) + return NULL_TREE; + nt.t = *tp; + nt.num = VEC_length (numbered_tree, *list); + VEC_safe_push (numbered_tree, heap, *list, &nt); + *walk_subtrees = 0; + return NULL_TREE; +} + +/* Find all the declarations used by the current function, sort them by uid, + and emit the sorted list. Each declaration is tagged with a sequence + number indicating when it was found during statement / tree walking, + so that TDF_NOUID comparisons of anonymous declarations are still + meaningful. Where a declaration was encountered more than once, we + emit only the sequence number of the first encounter. + FILE is the dump file where to output the list and FLAGS is as in + print_generic_expr. */ +void +dump_enumerated_decls (FILE *file, int flags) +{ + basic_block bb; + struct walk_stmt_info wi; + VEC (numbered_tree, heap) *decl_list = VEC_alloc (numbered_tree, heap, 40); + + wi.info = (void*) decl_list; + wi.pset = NULL; + FOR_EACH_BB (bb) + { + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + if (!is_gimple_debug (gsi_stmt (gsi))) + walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi); + } + decl_list = (VEC (numbered_tree, heap) *) wi.info; + qsort (VEC_address (numbered_tree, decl_list), + VEC_length (numbered_tree, decl_list), + sizeof (numbered_tree), compare_decls_by_uid); + if (VEC_length (numbered_tree, decl_list)) + { + unsigned ix; + numbered_tree *ntp; + tree last = NULL_TREE; + + fprintf (file, "Used declarations sorted by DECL_UID:\n"); + for (ix = 0; VEC_iterate (numbered_tree, decl_list, ix, ntp); ix++) + { + if (ntp->t == last) + continue; + fprintf (file, "%d: ", ntp->num); + print_generic_decl (file, ntp->t, flags); + fprintf (file, "\n"); + last = ntp->t; + } + } + VEC_free (numbered_tree, heap, decl_list); +} #ifdef ENABLE_CHECKING /* Verify that SSA_VAR is a non-virtual SSA_NAME. */ Index: gcc/tree-optimize.c =================================================================== --- gcc/tree-optimize.c (revision 161952) +++ gcc/tree-optimize.c (working copy) @@ -191,6 +191,34 @@ execute_cleanup_cfg_post_optimizing (voi cleanup_tree_cfg (); cleanup_dead_labels (); group_case_labels (); + if (flag_dump_final_insns) + { + FILE *final_output = fopen (flag_dump_final_insns, "a"); + + if (!final_output) + { + error ("could not open final insn dump file %qs: %m", + flag_dump_final_insns); + flag_dump_final_insns = NULL; + } + else + { + int save_unnumbered = flag_dump_unnumbered; + int save_noaddr = flag_dump_noaddr; + + flag_dump_noaddr = flag_dump_unnumbered = 1; + fprintf (final_output, "\n\n\n"); + dump_enumerated_decls (final_output, dump_flags | TDF_NOUID); + flag_dump_noaddr = save_noaddr; + flag_dump_unnumbered = save_unnumbered; + if (fclose (final_output)) + { + error ("could not close final insn dump file %qs: %m", + flag_dump_final_insns); + flag_dump_final_insns = NULL; + } + } + } return 0; } Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 161952) +++ gcc/Makefile.in (working copy) @@ -2448,7 +2448,7 @@ domwalk.o : domwalk.c $(CONFIG_H) $(SYST tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ $(TREE_SSA_LIVE_H) $(BITMAP_H) $(TOPLEV_H) debug.h $(FLAGS_H) \ - tree-pretty-print.h gimple-pretty-print.h + tree-pretty-print.h gimple-pretty-print.h $(GIMPLE_H) tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) \ $(TREE_PASS_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) \ Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 161952) +++ gcc/tree-cfg.c (working copy) @@ -6448,6 +6448,8 @@ dump_function_to_file (tree fn, FILE *fi fprintf (file, "}\n"); } + if (flags & TDF_ENUMERATE_LOCALS) + dump_enumerated_decls (file, flags); fprintf (file, "\n\n"); /* Restore CFUN. */