re PR other/44874 (TDF_NOUID dumps miss information about DECL_UID ordering)
authorJoern Rennecke <joern.rennecke@embecosm.com>
Tue, 13 Jul 2010 21:55:57 +0000 (21:55 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Tue, 13 Jul 2010 21:55:57 +0000 (22:55 +0100)
gcc:
PR other/44874
* 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 comparing
debug info and 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:
PR other/44874
PR debug/44832
* c-c++-common/pr44832.c: New test.

From-SVN: r162156

gcc/ChangeLog
gcc/Makefile.in
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr44832.c [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-dump.c
gcc/tree-dump.h
gcc/tree-optimize.c
gcc/tree-pass.h
gcc/tree-pretty-print.c
gcc/tree-ssa-live.c

index 6af68b2bd1e7972f154bacc61a1c2c88125a7b33..cf771a7a2b5f30087b441ef3b629b273178179d9 100644 (file)
@@ -1,3 +1,25 @@
+2010-07-13  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+       PR other/44874
+       * 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 comparing
+       debug info and 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).
+
 2010-07-13  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * expmed.h (MAX_BITS_PER_WORD): Move to...
index c6f199f95bebe1d0747e8286e890bb783b2abc5b..5a45701b71fa878f8f7330d3e55b1fa06413cb41 100644 (file)
@@ -2452,7 +2452,7 @@ domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 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 f0792b5d6c52b8101b2b3dbb068e64a74d240e21..8eafd743484d1038191a43d6fcc79766132edfbf 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-10  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+       PR other/44874
+       PR debug/44832
+       * c-c++-common/pr44832.c: New test.
+
 2010-07-13  Iain Sandoe  <iains@gcc.gnu.org>
 
        PR objc/44488
diff --git a/gcc/testsuite/c-c++-common/pr44832.c b/gcc/testsuite/c-c++-common/pr44832.c
new file mode 100644 (file)
index 0000000..4138e37
--- /dev/null
@@ -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 9e38ca717a114be740f2b9b653f408c8e8883ea1..b4923c1b49478b2b187ceeaa0d1a6b9c07217cc5 100644 (file)
@@ -6449,6 +6449,8 @@ dump_function_to_file (tree fn, FILE *file, int flags)
        fprintf (file, "}\n");
     }
 
+  if (flags & TDF_ENUMERATE_LOCALS)
+    dump_enumerated_decls (file, flags);
   fprintf (file, "\n\n");
 
   /* Restore CFUN.  */
index be39479b821894b9521c15e4866ecbe6b5cbef37..fcbace23683ce7ca4e99d2a39a64006752088912 100644 (file)
@@ -821,9 +821,10 @@ static const struct dump_option_value_info dump_options[] =
   {"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 eeb28e0aad6a071b680d13d6ef5b86f6a6d8cead..f5b04ff67ea42743f8b351c17fe82d9c786e453d 100644 (file)
@@ -91,6 +91,7 @@ extern void queue_and_dump_index (dump_info_p, const char *, const_tree, int);
 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 aebcbb10c600384e9b5bf3b61666d886ad14f5b7..e736b4fab81caa6dea0ecb7dee0969d79237c7c1 100644 (file)
@@ -191,6 +191,35 @@ execute_cleanup_cfg_post_optimizing (void)
   cleanup_tree_cfg ();
   cleanup_dead_labels ();
   group_case_labels ();
+  if ((flag_compare_debug_opt || flag_compare_debug)
+      && 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");
+         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 a4c97b39155b0f4977d7ec0b55e18e03112ea52c..c72d7cfa6da019bf248a0f50d9560e77d0a3f766 100644 (file)
@@ -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 db85caf8ceff49b06245e9c8a4d72a7e919d0a27..fde91844ec7123df225fc7c212067160ce4daa24 100644 (file)
@@ -757,6 +757,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
          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 *buffer, tree node, int spc, int flags,
        }
       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);
@@ -2312,7 +2316,7 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
     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 ab79d7f327ebc8c5c353780402f31593a32f3140..fcd277951fb6889cc8dee79cf7e15d53e9ead987 100644 (file)
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #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);
@@ -1196,6 +1197,96 @@ dump_live_info (FILE *f, tree_live_info_p live, int flag)
     }
 }
 
+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, "Declarations used by %s, sorted by DECL_UID:\n",
+              current_function_name ());
+      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.  */