This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto] patch committed to clean up ssa verification error


Most of this patch was adding debugging to make sure that all of the
tree flags are being serialized correctly. There were some changes to
make sure that the variable holding the packed tree flags was always an
unsigned HOST_WIDE_INT. 

The main bug that was fixed was a verification call.  This was fixed by
adding a call to  
recompute_tree_invariant_for_addr_expr.  In a perfect world, this call
would not be needed but there are so many side effects from calling the
build1 ... build7 functions, that it is necessary to reset some of its
bits. 

Kenny

2007-10-20  Kenneth Zadeck <zadeck@naturalbridge.com>

    * lto-read.c (input_tree_flags): Renamed from input_flags to be
    semetric with output_tree_flags.  Added call to log flags.
    (process_tree_flags): Renamed from process_flags.  Fixed a lot of
    type issues to make everything consistent with flags being
    unsigned HOST_WIDE_INTS.
    (input_expr_operand): Added call to
    recompute_tree_invariant_for_addr_expr.
    (input_local_var): Added debugging for tree_chains.  Now calls
    input_tree_flags.
    (input_phi): Made flags unsigned HOST_WIDE_INT.
    (input_ssa_names): Now calls input_tree_flags.
    (lto_read_body): Now sets cfun.
    (lto_read_function_body): Now sets current_function_pointer.
   
2007-10-22  Kenneth Zadeck <zadeck@naturalbridge.com>

    * lto-function-out.c (output_tree_flags): Changed type of
    flags and enhanced stream debugging for flags.
    (output_local_vars): Added debugging for tree_chains.
    (lto_debug_tree_flags): New function.
    * lto-flags.h (lto_debug_tree_flags): New function.
    (LTO_flags_needed): New LTO_tags.
    (LTO_DEBUG_TREE_FLAGS): New macro.
    * Makefile.in (LTO_TAGS_H): Add tree.h dependency.

Index: lto-function-out.c
===================================================================
--- lto-function-out.c	(revision 129549)
+++ lto-function-out.c	(working copy)
@@ -732,14 +732,13 @@ output_decl_index (struct output_stream 
 static void
 output_tree_flags (struct output_block *ob, enum tree_code code, tree expr)
 {
-  int flags = 0;
+  unsigned HOST_WIDE_INT flags = 0;
   const char *file_to_write = NULL;
   int line_to_write = -1;
   const char *current_file;
 
   if (code == 0 || TEST_BIT (lto_flags_needed_for, code))
     {
-      LTO_DEBUG_TOKEN ("flags");
 
 #define START_CLASS_SWITCH()              \
   {                                       \
@@ -749,7 +748,8 @@ output_tree_flags (struct output_block *
     {
 
 #define START_CLASS_CASE(class)    case class:
-#define ADD_CLASS_FLAG(flag_name) { flags <<= 1; if (expr->base. flag_name ) flags |= 1; }
+#define ADD_CLASS_FLAG(flag_name) \
+      { flags <<= 1; if (expr->base. flag_name ) flags |= 1; }
 #define END_CLASS_CASE(class)      break;
 #define END_CLASS_SWITCH()                \
     default:                              \
@@ -761,10 +761,14 @@ output_tree_flags (struct output_block *
     switch (code)			  \
     {
 #define START_EXPR_CASE(code)    case code:
-#define ADD_EXPR_FLAG(flag_name) { flags <<= 1; if (expr->base. flag_name ) flags |= 1; }
-#define ADD_DECL_FLAG(flag_name) { flags <<= 1; if (expr->decl_common. flag_name ) flags |= 1; }
-#define ADD_VIS_FLAG(flag_name)  { flags <<= 1; if (expr->decl_with_vis. flag_name ) flags |= 1; }
-#define ADD_FUNC_FLAG(flag_name) { flags <<= 1; if (expr->function_decl. flag_name ) flags |= 1; }
+#define ADD_EXPR_FLAG(flag_name) \
+      { flags <<= 1; if (expr->base. flag_name ) flags |= 1; }
+#define ADD_DECL_FLAG(flag_name) \
+      { flags <<= 1; if (expr->decl_common. flag_name ) flags |= 1; }
+#define ADD_VIS_FLAG(flag_name)  \
+      { flags <<= 1; if (expr->decl_with_vis. flag_name ) flags |= 1; }
+#define ADD_FUNC_FLAG(flag_name) \
+      { flags <<= 1; if (expr->function_decl. flag_name ) flags |= 1; }
 #define END_EXPR_CASE(class)      break;
 #define END_EXPR_SWITCH()                 \
     default:                              \
@@ -814,7 +818,10 @@ output_tree_flags (struct output_block *
 	    }
 	}
 
+      LTO_DEBUG_TOKEN ("flags");
       output_uleb128 (ob, flags);
+      LTO_DEBUG_TREE_FLAGS (code, flags);
+
       if (file_to_write)
 	{
 	  LTO_DEBUG_TOKEN ("file");
@@ -1584,6 +1591,7 @@ output_local_vars (struct output_block *
       if (!is_var)
 	{
 	  output_type_ref (ob, DECL_ARG_TYPE (decl));
+	  LTO_DEBUG_TOKEN ("chain");
 	  if (TREE_CHAIN (decl))
 	    output_expr_operand (ob, TREE_CHAIN (decl));
 	  else
@@ -2223,4 +2231,64 @@ debug_out_fun (struct lto_debug_context 
     = (struct output_stream *)context->current_data;
   output_1_stream (stream, c);
 }
+/* Print the tree flags to the debugging stream.  */
+   
+void 
+lto_debug_tree_flags (struct lto_debug_context *context, 
+		      enum tree_code code, 
+		      unsigned HOST_WIDE_INT flags)
+{
+#define CLEAROUT (HOST_BITS_PER_WIDE_INT - 1)
+
+#define START_CLASS_SWITCH()              \
+  {                                       \
+                                          \
+    switch (TREE_CODE_CLASS (code))       \
+    {
+
+#define START_CLASS_CASE(class)    case class:
+#define ADD_CLASS_FLAG(flag_name) \
+  { if (flags >> CLEAROUT) lto_debug_token (context, " " # flag_name ); flags <<= 1; }
+#define END_CLASS_CASE(class)      break;
+#define END_CLASS_SWITCH()                \
+    default:                              \
+      gcc_unreachable ();                 \
+    }
+
+
+#define START_EXPR_SWITCH()               \
+    switch (code)			  \
+    {
+#define START_EXPR_CASE(code)    case code:
+#define ADD_EXPR_FLAG(flag_name) \
+  { if (flags >> CLEAROUT) lto_debug_token (context, " " # flag_name ); flags <<= 1; }
+#define ADD_DECL_FLAG(flag_name) \
+  { if (flags >> CLEAROUT) lto_debug_token (context, " " # flag_name ); flags <<= 1; }
+#define ADD_VIS_FLAG(flag_name)  \
+  { if (flags >> CLEAROUT) lto_debug_token (context, " " # flag_name ); flags <<= 1; }
+#define ADD_FUNC_FLAG(flag_name) \
+  { if (flags >> CLEAROUT) lto_debug_token (context, " " # flag_name ); flags <<= 1; }
+#define END_EXPR_CASE(class)      break;
+#define END_EXPR_SWITCH()                 \
+    default:                              \
+      gcc_unreachable ();                 \
+    }                                     \
+  }
+
+#include "lto-tree-flags.def"
+
+#undef START_CLASS_SWITCH
+#undef START_CLASS_CASE
+#undef ADD_CLASS_FLAG
+#undef END_CLASS_CASE
+#undef END_CLASS_SWITCH
+#undef START_EXPR_SWITCH
+#undef START_EXPR_CASE
+#undef ADD_EXPR_FLAG
+#undef ADD_DECL_FLAG
+#undef ADD_VIS_FLAG
+#undef ADD_FUNC_FLAG
+#undef END_EXPR_CASE
+#undef END_EXPR_SWITCH
+}
 #endif
Index: lto-tags.h
===================================================================
--- lto-tags.h	(revision 129549)
+++ lto-tags.h	(working copy)
@@ -24,6 +24,7 @@
 #ifndef GCC_LTO_TAGS_H
 #define GCC_LTO_TAGS_H
 
+#include "tree.h"
 #include "sbitmap.h"
 
 #define LTO_major_version 0
@@ -261,10 +262,13 @@ struct lto_header
 #define REDUNDANT_TYPE_SYSTEM 1
 
 enum LTO_tags {
+/* This allows flags to be sent for a tag even if the tag do not indicate one is needed.  */
+  LTO_flags_needed = 1,
 
 /* The 1 variant indicates that the basic block is not empty.  */
-  LTO_bb0 = 1,
+  LTO_bb0,
   LTO_bb1,
+
 /* Variant 1 is used to set region to no zero value.  */
   LTO_set_eh0,
   LTO_set_eh1,
@@ -496,11 +500,14 @@ void lto_static_init (void);
   lto_debug_string (&lto_debug_context, value, len)
 #define LTO_DEBUG_TOKEN(value) \
   lto_debug_token (&lto_debug_context, value)
+#define LTO_DEBUG_TREE_FLAGS(code,value) \
+  lto_debug_tree_flags (&lto_debug_context, code, flags)
 #define LTO_DEBUG_UNDENT() \
   lto_debug_undent (&lto_debug_context)
 #define LTO_DEBUG_WIDE(tag,value) \
   lto_debug_wide (&lto_debug_context, tag, value)
 
+
 struct lto_debug_context;
 
 typedef void (*lto_debug_out) (struct lto_debug_context *context, char c);
@@ -525,15 +532,18 @@ extern void lto_debug_indent_token (stru
 extern void lto_debug_integer (struct lto_debug_context *, const char *, HOST_WIDE_INT, HOST_WIDE_INT);
 extern void lto_debug_string (struct lto_debug_context *, const char *, int);
 extern void lto_debug_token (struct lto_debug_context *, const char *);
+extern void lto_debug_tree_flags (struct lto_debug_context *, enum tree_code, unsigned HOST_WIDE_INT);
 extern void lto_debug_undent (struct lto_debug_context *);
 extern void lto_debug_wide (struct lto_debug_context *, const char *, HOST_WIDE_INT);
 
+
 #else
 #define LTO_DEBUG_INDENT(tag) (void)0
 #define LTO_DEBUG_INDENT_TOKEN(value) (void)0
 #define LTO_DEBUG_INTEGER(tag,high,low) (void)0
 #define LTO_DEBUG_STRING(value,len) (void)0
 #define LTO_DEBUG_TOKEN(value) (void)0
+#define LTO_DEBUG_TREE_FLAGS(code, value) (void)0
 #define LTO_DEBUG_UNDENT() (void)0
 #define LTO_DEBUG_WIDE(tag,value) (void)0
 #endif
Index: lto/lto-read.c
===================================================================
--- lto/lto-read.c	(revision 129549)
+++ lto/lto-read.c	(working copy)
@@ -338,18 +338,37 @@ get_type_ref (struct data_in *data_in, s
 }
 
 /* Set all of the FLAGS for NODE.  */
-#define CLEAROUT (HOST_BITS_PER_INT - 1)
+#define CLEAROUT (HOST_BITS_PER_WIDE_INT - 1)
+
+
+/* Read the tree flags for CODE from IB.  */
+
+static unsigned HOST_WIDE_INT 
+input_tree_flags (struct input_block *ib, enum tree_code code)
+{
+  unsigned HOST_WIDE_INT flags;
+
+  if (TEST_BIT (lto_flags_needed_for, code))
+    {
+      LTO_DEBUG_TOKEN ("flags");
+      flags = input_uleb128 (ib);
+      LTO_DEBUG_TREE_FLAGS (code, flags);
+    }
+  else
+    flags = 0;
+  return flags;
+}
 
 
 /* Set all of the flag bits inside EXPR by unpacking FLAGS.  */
 
 static void
-process_flags (tree expr, unsigned HOST_WIDE_INT flags)
+process_tree_flags (tree expr, unsigned HOST_WIDE_INT flags)
 {
   enum tree_code code = TREE_CODE (expr);
   /* Shift the flags up so that the first flag is at the top of the
      flag word.  */
-  flags <<= HOST_BITS_PER_INT - num_flags_for_code[code];
+  flags <<= HOST_BITS_PER_WIDE_INT - num_flags_for_code[code];
 
 #define START_CLASS_SWITCH()              \
   {                                       \
@@ -358,7 +377,8 @@ process_flags (tree expr, unsigned HOST_
     {
 
 #define START_CLASS_CASE(class)    case class:
-#define ADD_CLASS_FLAG(flag_name) { expr->base. flag_name = flags >> CLEAROUT;  flags <<= 1; }
+#define ADD_CLASS_FLAG(flag_name) \
+  { expr->base. flag_name = flags >> CLEAROUT; flags <<= 1; }
 #define END_CLASS_CASE(class)      break;
 #define END_CLASS_SWITCH()                \
     default:                              \
@@ -370,10 +390,14 @@ process_flags (tree expr, unsigned HOST_
     switch (code)			  \
     {
 #define START_EXPR_CASE(code)    case code:
-#define ADD_EXPR_FLAG(flag_name) { expr->base. flag_name = (flags >> CLEAROUT);  flags <<= 1; }
-#define ADD_DECL_FLAG(flag_name) { expr->decl_common. flag_name = flags >> CLEAROUT; flags <<= 1; }
-#define ADD_VIS_FLAG(flag_name)  { expr->decl_with_vis. flag_name = (flags >> CLEAROUT); flags <<= 1; }
-#define ADD_FUNC_FLAG(flag_name) { expr->function_decl. flag_name = (flags >> CLEAROUT); flags <<= 1; }
+#define ADD_EXPR_FLAG(flag_name) \
+  { expr->base. flag_name = (flags >> CLEAROUT); flags <<= 1; }
+#define ADD_DECL_FLAG(flag_name) \
+  { expr->decl_common. flag_name = flags >> CLEAROUT; flags <<= 1; }
+#define ADD_VIS_FLAG(flag_name)  \
+  { expr->decl_with_vis. flag_name = (flags >> CLEAROUT); flags <<= 1; }
+#define ADD_FUNC_FLAG(flag_name) \
+  { expr->function_decl. flag_name = (flags >> CLEAROUT); flags <<= 1; }
 #define END_EXPR_CASE(class)      break;
 #define END_EXPR_SWITCH()                 \
     default:                              \
@@ -399,24 +423,6 @@ process_flags (tree expr, unsigned HOST_
 }
 
 
-/* Read the flags for CODE from IB.  */
-
-static unsigned int 
-input_flags (struct input_block *ib, enum tree_code code)
-{
-  unsigned int flags;
-
-  if (TEST_BIT (lto_flags_needed_for, code))
-    {
-      LTO_DEBUG_TOKEN ("flags");
-      flags = input_uleb128 (ib);
-    }
-  else
-    flags = 0;
-  return flags;
-}
-
-
 /* Read a node in the gimple tree from IB.  The TAG has already been
    read.  */
 
@@ -435,7 +441,7 @@ input_expr_operand (struct input_block *
   if (TEST_BIT (lto_types_needed_for, code))
     type = get_type_ref (data_in, ib);
 
-  flags = input_flags (ib, code);
+  flags = input_tree_flags (ib, code);
 
   /* FIXME! need to figure out how to set the file and line number.  */
   if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
@@ -908,7 +914,14 @@ input_expr_operand (struct input_block *
 
   LTO_DEBUG_UNDENT();
   if (flags)
-    process_flags (result, flags);
+    process_tree_flags (result, flags);
+
+  /* It is not enought to just put the flags back as we serialized
+     them.  There are side effects to the buildN functions which play
+     with the flags to the point that we just have to call this here
+     to get it right.  */
+  if (code == ADDR_EXPR)
+    recompute_tree_invariant_for_addr_expr (result);
   return result;
 }
 
@@ -1045,6 +1058,7 @@ input_local_var (struct data_in *data_in
   if (!is_var)
     {
       DECL_ARG_TYPE (result) = get_type_ref (data_in, ib);
+      LTO_DEBUG_TOKEN ("chain");
       tag = input_record_start (ib);
       if (tag)
 	TREE_CHAIN (result) = input_expr_operand (ib, data_in, fn, tag);
@@ -1052,8 +1066,7 @@ input_local_var (struct data_in *data_in
 	TREE_CHAIN (result) = NULL_TREE;
     }
   
-  LTO_DEBUG_TOKEN ("flags");
-  flags = input_uleb128 (ib);
+  flags = input_tree_flags (ib, LTO_flags_needed);
   
   /* FIXME: Need to figure out how to set the line number.  */
   if (flags & 0x2)
@@ -1090,7 +1103,7 @@ input_local_var (struct data_in *data_in
     DECL_ABSTRACT_ORIGIN (result) 
       = input_expr_operand (ib, data_in, fn, input_record_start (ib));
   
-  process_flags (result, flags);
+  process_tree_flags (result, flags);
   LTO_DEBUG_UNDENT();
 
   /* Record the variable.  */
@@ -1252,7 +1265,7 @@ static tree
 input_phi (struct input_block *ib, basic_block bb, 
 	   struct data_in *data_in, struct function *fn)
 {
-  unsigned int flags = input_flags (ib, PHI_NODE);
+  unsigned HOST_WIDE_INT flags = input_tree_flags (ib, PHI_NODE);
 
   tree phi_result = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib));
   int len = EDGE_COUNT (bb->preds);
@@ -1281,7 +1294,7 @@ input_phi (struct input_block *ib, basic
     }
 
   if (flags)
-    process_flags (result, flags);
+    process_tree_flags (result, flags);
 
   LTO_DEBUG_UNDENT();
 
@@ -1305,7 +1318,7 @@ input_ssa_names (struct data_in *data_in
     {
       tree ssa_name;
       tree name;
-      unsigned int flags;
+      unsigned HOST_WIDE_INT flags;
 
       /* Skip over the elements that had been freed.  */
       while (VEC_length (tree, SSANAMES (fn)) < i)
@@ -1314,9 +1327,8 @@ input_ssa_names (struct data_in *data_in
       name = input_expr_operand (ib, data_in, fn, input_record_start (ib));
       ssa_name = make_ssa_name (fn, name, build_empty_stmt ());
 
-      LTO_DEBUG_TOKEN ("flags");
-      flags = input_uleb128 (ib);
-      process_flags (ssa_name, flags);
+      flags = input_tree_flags (ib, LTO_flags_needed);
+      process_tree_flags (ssa_name, flags);
 
       i = input_uleb128 (ib);
     } 
@@ -1608,6 +1620,7 @@ lto_read_body (lto_info_fd *fd,
   if (in_function)
     {
       struct function *fn = DECL_STRUCT_FUNCTION (t);
+      cfun = fn;
       data_in.num_named_labels = header->num_named_labels;
 
 #ifdef LTO_STREAM_DEBUGGING
@@ -1671,6 +1684,7 @@ lto_read_function_body (lto_info_fd *fd,
 			tree fn_decl,
 			const void *data)
 {
+  current_function_decl = fn_decl;
   lto_read_body (fd, context, fn_decl, data, true);
 }
 
@@ -1762,5 +1776,5 @@ debug_out_fun (struct lto_debug_context 
       gcc_unreachable ();
     }
 }
-    
+ 
 #endif
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 129549)
+++ Makefile.in	(working copy)
@@ -838,7 +838,7 @@ TREE_INLINE_H = tree-inline.h $(VARRAY_H
 REAL_H = real.h $(MACHMODE_H)
 DBGCNT_H = dbgcnt.h dbgcnt.def
 EBIMAP_H = ebitmap.h sbitmap.h
-LTO_TAGS_H = lto-tags.h sbitmap.h
+LTO_TAGS_H = lto-tags.h tree.h sbitmap.h
 TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H)
 
 #

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]