diff mbox

RFA: Fix other/44874

Message ID 20100710002250.z5dvg6z1ckkgg480-nzlynne@webmail.spamcop.net
State New
Headers show

Commit Message

Joern Rennecke July 10, 2010, 4:22 a.m. UTC
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.

Comments

Richard Biener July 10, 2010, 8:12 a.m. UTC | #1
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.  */
>
>
Joern Rennecke July 10, 2010, 10:55 a.m. UTC | #2
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.
H.J. Lu Aug. 26, 2010, 7:51 p.m. UTC | #3
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.
H.J. Lu Nov. 21, 2010, 12:23 a.m. UTC | #4
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
diff mbox

Patch

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.  */