[pph] Fix 3 asm differences (issue4695048)

Diego Novillo dnovillo@google.com
Tue Jul 12 19:49:00 GMT 2011


This patch is a slight adaptation of Gab's fix to the order in which
we stream chains (http://codereview.appspot.com/4657092).  I mostly
just changed how we keep the temporary list to reverse (it now uses a
VEC instead of a custom-build linked list).

The other change is in the reader.  We were not registering symbols in
scope_chain->static_aggregates as they come from the PPH file (which
would cause an ICE in x1hardlookup.cc).

This fixes 3 tests, but we still have some asm differences that are
similar in nature: when reinstantiating PPH images, the compiler emits
some symbols in different order, causing different numbering and
naming in the assembler output (we need to generate identical output
from a pph or from text).

Tested on x86_64.  Committed to branch.


Diego.

2011-07-12   Diego Novillo  <dnovillo@google.com>

	* pph-streamer-in.c (pph_register_decl_in_symtab): New.
	(pph_register_binding_in_symtab): Rename from
	pph_register_decls_in_symtab.  Update all users.
	Do not call nreverse on bl->names and bl->namespaces.
	Call pph_register_decl_in_symtab.
	(pph_read_file_contents): Register decls in
	FILE_STATIC_AGGREGATES.

2011-07-12  Gabriel Charette  <gchare@google.com>
	    Diego Novillo  <dnovillo@google.com>

	* pph-streamer-out.c (pph_out_chained_tree): New.
	(pph_out_chain_filtered): Add REVERSE_P parameter.
	If REVERSE_P is set, write the list in reverse order.
	Update all users.
	(pph_out_binding_level): Write out lists bl->names,
	bl->namespaces, bl->usings and bl->using_directives in
	reverse.


testsuite/ChangeLog.pph
2011-07-12  Gabriel Charette  <gchare@google.com>

	* g++.dg/pph/c1pr44948-1a.cc: Mark fixed.
	* g++.dg/pph/c2pr36533.cc: Mark fixed.
	* g++.dg/pph/x2functions.cc: Mark fixed.

diff --git a/gcc/cp/pph-streamer-in.c b/gcc/cp/pph-streamer-in.c
index 63f8965..e7d1d00 100644
--- a/gcc/cp/pph-streamer-in.c
+++ b/gcc/cp/pph-streamer-in.c
@@ -1175,29 +1175,33 @@ pph_in_lang_type (pph_stream *stream)
 }
 
 
+/* Register DECL with the middle end.  */
+
+static void
+pph_register_decl_in_symtab (tree decl)
+{
+  if (TREE_CODE (decl) == VAR_DECL
+      && TREE_STATIC (decl)
+      && !DECL_EXTERNAL (decl))
+    varpool_finalize_decl (decl);
+}
+
+
 /* Register all the symbols in binding level BL in the callgraph symbol
    table.  */
 
 static void
-pph_register_decls_in_symtab (struct cp_binding_level *bl)
+pph_register_binding_in_symtab (struct cp_binding_level *bl)
 {
   tree t;
 
-  /* The chains are built backwards (ref: add_decl_to_level),
-     reverse them before putting them back in.  */
-  bl->names = nreverse (bl->names);
-  bl->namespaces = nreverse (bl->namespaces);
-
+  /* Add file-local symbols to the varpool.  */
   for (t = bl->names; t; t = DECL_CHAIN (t))
-    {
-      /* Add file-local symbols to the varpool.  */
-      if (TREE_CODE (t) == VAR_DECL && TREE_STATIC (t) && !DECL_EXTERNAL (t))
-	varpool_finalize_decl (t);
-    }
+    pph_register_decl_in_symtab (t);
 
   /* Recurse into the namespaces contained in BL.  */
   for (t = bl->namespaces; t; t = DECL_CHAIN (t))
-    pph_register_decls_in_symtab (NAMESPACE_LEVEL (t));
+    pph_register_binding_in_symtab (NAMESPACE_LEVEL (t));
 }
 
 
@@ -1220,7 +1224,7 @@ pph_in_scope_chain (pph_stream *stream)
   new_bindings = pph_in_binding_level (stream, scope_chain->bindings);
 
   /* Register all the symbols in STREAM with the call graph.  */
-  pph_register_decls_in_symtab (new_bindings);
+  pph_register_binding_in_symtab (new_bindings);
 
   /* Merge the bindings from STREAM into saved_scope->bindings.  */
   chainon (cur_bindings->names, new_bindings->names);
@@ -1413,6 +1417,16 @@ pph_read_file_contents (pph_stream *stream)
   file_static_aggregates = pph_in_tree (stream);
   static_aggregates = chainon (file_static_aggregates, static_aggregates);
 
+  /* Register all symbols in FILE_STATIC_AGGREGATES with the middle end.
+     Each element of this list is an INIT_EXPR expression.  */
+  for (t = file_static_aggregates; t; t = TREE_CHAIN (t))
+    {
+      tree lhs = TREE_OPERAND (TREE_PURPOSE (t), 0);
+      tree rhs = TREE_OPERAND (TREE_PURPOSE (t), 1);
+      pph_register_decl_in_symtab (lhs);
+      pph_register_decl_in_symtab (rhs);
+    }
+
   /* Expand all the functions with bodies that we read from STREAM.  */
   FOR_EACH_VEC_ELT (tree, stream->fns_to_expand, i, fndecl)
     {
diff --git a/gcc/cp/pph-streamer-out.c b/gcc/cp/pph-streamer-out.c
index f7bf739..9c9a1f8 100644
--- a/gcc/cp/pph-streamer-out.c
+++ b/gcc/cp/pph-streamer-out.c
@@ -584,21 +584,44 @@ pph_out_label_binding (pph_stream *stream, cp_label_binding *lb, bool ref_p)
 }
 
 
+/* Outputs chained tree T by nulling out its chain first and restoring it
+   after the streaming is done. STREAM and REF_P are as in
+   pph_out_chain_filtered.  */
+
+static inline void
+pph_out_chained_tree (pph_stream *stream, tree t, bool ref_p)
+{
+  tree saved_chain;
+
+  saved_chain = TREE_CHAIN (t);
+  TREE_CHAIN (t) = NULL_TREE;
+
+  pph_out_tree_or_ref_1 (stream, t, ref_p, 2);
+
+  TREE_CHAIN (t) = saved_chain;
+}
+
+
 /* Output a chain of nodes to STREAM starting with FIRST.  Skip any
    nodes that do not match FILTER.  REF_P is true if nodes in the chain
-   should be emitted as references.  */
+   should be emitted as references.  Stream the chain in the reverse order
+   if REVERSE is true.*/
 
 static void
 pph_out_chain_filtered (pph_stream *stream, tree first, bool ref_p,
-			   enum chain_filter filter)
+			   enum chain_filter filter, bool reverse_p)
 {
   unsigned count;
+  int i;
   tree t;
+  VEC(tree,gc) *reverse_list = NULL;
 
   /* Special case.  If the caller wants no filtering, it is much
      faster to just call pph_out_chain directly.  */
   if (filter == NONE)
     {
+      if (reverse_p)
+	nreverse (first);
       pph_out_chain (stream, first, ref_p);
       return;
     }
@@ -612,24 +635,31 @@ pph_out_chain_filtered (pph_stream *stream, tree first, bool ref_p,
     }
   pph_out_uint (stream, count);
 
+  /* We cannot use the actual chain and simply reverse that before
+     streaming out below as there are other chains being streamed out
+     as part of streaming the trees in the current chain and this
+     creates conflicts. Thus, we will create an array containing all
+     the trees we want to stream out and stream that backwards without
+     altering the chain itself.  */
+  if (reverse_p && count > 0)
+    reverse_list = VEC_alloc (tree, gc, count);
+
   /* Output all the nodes that match the filter.  */
   for (t = first; t; t = TREE_CHAIN (t))
     {
-      tree saved_chain;
-
       /* Apply filters to T.  */
       if (filter == NO_BUILTINS && DECL_P (t) && DECL_IS_BUILTIN (t))
 	continue;
 
-      /* Clear TREE_CHAIN to avoid blindly recursing into the rest
-	 of the list.  */
-      saved_chain = TREE_CHAIN (t);
-      TREE_CHAIN (t) = NULL_TREE;
-
-      pph_out_tree_or_ref_1 (stream, t, ref_p, 2);
-
-      TREE_CHAIN (t) = saved_chain;
+      if (reverse_p)
+	VEC_quick_push (tree, reverse_list, t);
+      else
+	pph_out_chained_tree (stream, t, ref_p);
     }
+
+  if (reverse_p && count > 0)
+    FOR_EACH_VEC_ELT_REVERSE (tree, reverse_list, i, t)
+      pph_out_chained_tree (stream, t, ref_p);
 }
 
 
@@ -648,13 +678,14 @@ pph_out_binding_level (pph_stream *stream, struct cp_binding_level *bl,
   if (!pph_out_start_record (stream, bl))
     return;
 
-  pph_out_chain_filtered (stream, bl->names, ref_p, NO_BUILTINS);
-  pph_out_chain_filtered (stream, bl->namespaces, ref_p, NO_BUILTINS);
+  pph_out_chain_filtered (stream, bl->names, ref_p, NO_BUILTINS, true);
+  pph_out_chain_filtered (stream, bl->namespaces, ref_p, NO_BUILTINS, true);
 
   pph_out_tree_vec (stream, bl->static_decls, ref_p);
 
-  pph_out_chain_filtered (stream, bl->usings, ref_p, NO_BUILTINS);
-  pph_out_chain_filtered (stream, bl->using_directives, ref_p, NO_BUILTINS);
+  pph_out_chain_filtered (stream, bl->usings, ref_p, NO_BUILTINS, true);
+  pph_out_chain_filtered (stream, bl->using_directives, ref_p, NO_BUILTINS,
+			  true);
 
   pph_out_uint (stream, VEC_length (cp_class_binding, bl->class_shadowed));
   FOR_EACH_VEC_ELT (cp_class_binding, bl->class_shadowed, i, cs)
diff --git a/gcc/testsuite/g++.dg/pph/c1pr44948-1a.cc b/gcc/testsuite/g++.dg/pph/c1pr44948-1a.cc
index c13ee87..0340dc5 100644
--- a/gcc/testsuite/g++.dg/pph/c1pr44948-1a.cc
+++ b/gcc/testsuite/g++.dg/pph/c1pr44948-1a.cc
@@ -1,3 +1,3 @@
 // { dg-xfail-if "INFINITE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: in lto_streamer_cache_get, at lto-streamer.c" "" { xfail *-*-* } 0 }
+// { dg-bogus "internal compiler error: in lto_get_pickled_tree, at lto-streamer-in.c" "" { xfail *-*-* } 0 }
 #include "c0pr44948-1a.h"
diff --git a/gcc/testsuite/g++.dg/pph/c2pr36533.cc b/gcc/testsuite/g++.dg/pph/c2pr36533.cc
index d8d6d8c..b44e8c9 100644
--- a/gcc/testsuite/g++.dg/pph/c2pr36533.cc
+++ b/gcc/testsuite/g++.dg/pph/c2pr36533.cc
@@ -1,3 +1,2 @@
 /* { dg-options "-w -fpermissive" } */
-// pph asm xdiff
 #include "c1pr36533.h"
diff --git a/gcc/testsuite/g++.dg/pph/x2functions.cc b/gcc/testsuite/g++.dg/pph/x2functions.cc
index 78df01b..d4e2cf7 100644
--- a/gcc/testsuite/g++.dg/pph/x2functions.cc
+++ b/gcc/testsuite/g++.dg/pph/x2functions.cc
@@ -1,5 +1,3 @@
-// pph asm xdiff
-
 #include "x1functions.h"
 
 int type::mbr_decl_then_def(int i)      // need body

--
This patch is available for review at http://codereview.appspot.com/4695048



More information about the Gcc-patches mailing list