Patchwork [pph] Minimal type merging. (issue5620047)

login
register
mail settings
Submitter Lawrence Crowl
Date Feb. 2, 2012, 2:44 a.m.
Message ID <20120202024455.846DA22265F@jade.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/139056/
State New
Headers show

Comments

Lawrence Crowl - Feb. 2, 2012, 2:44 a.m.
This patch adds minimal type merging.  It unifies the existence of
types for a struct decl.  The method is to emit a merge key for the
type when we emit a merge key for the struct decl.

Test x4structover1.cc is now passing.

The next step is to merge struct definitions.  For that we have test
cases x*incomplete*, which progressively add more information to the
classes in different configurations of pph files.

Tested on x64.



--
This patch is available for review at http://codereview.appspot.com/5620047
Diego Novillo - Feb. 2, 2012, 2:54 a.m.
On Wed, Feb 1, 2012 at 18:44, Lawrence Crowl <crowl@google.com> wrote:

> @@ -1393,7 +1393,12 @@ dump_function_decl (tree t, int flags)
>     }
>
>   fntype = TREE_TYPE (t);
> -  parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
> +  gcc_assert (fntype)

You forgot a semi-colon :)  Fixed.


Diego.

Patch

Index: gcc/testsuite/ChangeLog.pph

2012-02-01   Lawrence Crowl  <crowl@google.com>

	* g++.dg/pph/x4structover1.cc: Mark fixed.
	* g++.dg/pph/a0incomplete2.hi: New.
	* g++.dg/pph/a0incomplete3.hi: New.
	* g++.dg/pph/a0incomplete4.cci: New.
	* g++.dg/pph/x0incomplete1.h: New.
	* g++.dg/pph/x0incomplete2.h: New.
	* g++.dg/pph/x0incomplete3.h: New.
	* g++.dg/pph/x1incomplete3.h: New.
	* g++.dg/pph/x1incomplete4.cc: New.
	* g++.dg/pph/x2incomplete4.cc: New.
	* g++.dg/pph/x3incomplete412.cc: New.
	* g++.dg/pph/x3incomplete413.cc: New.
	* g++.dg/pph/x4incomplete4123.cc: New.
	* g++.dg/pph/x4incomplete4321.cc: New.

Index: gcc/cp/ChangeLog.pph

2012-02-01   Lawrence Crowl  <crowl@google.com>

	* error.c (dump_function_decl):  Add protection against NULL.
	* pph-out.c (pph_out_merge_key_tree):  Write merge keys for struct
	types, as opposed to decls.
	* pph-in.c (pph_in_merge_tree_body):  Save chains in decls only.
	(pph_in_merge_key_tree): Read merge keys for struct types.  Split
	handling into two phases, cache insertion (which is before the trace
	front) and sub-tree reading.


Index: gcc/testsuite/g++.dg/pph/x1incomplete3.h
===================================================================
--- gcc/testsuite/g++.dg/pph/x1incomplete3.h	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x1incomplete3.h	(revision 0)
@@ -0,0 +1,7 @@ 
+#ifndef X0INCOMPLETE3_H
+#define X0INCOMPLETE3_H
+
+#include "x0incomplete2.h"
+#include "a0incomplete3.hi"
+
+#endif
Index: gcc/testsuite/g++.dg/pph/x0incomplete2.h
===================================================================
--- gcc/testsuite/g++.dg/pph/x0incomplete2.h	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x0incomplete2.h	(revision 0)
@@ -0,0 +1,6 @@ 
+#ifndef X0INCOMPLETE2_H
+#define X0INCOMPLETE2_H
+
+#include "a0incomplete2.hi"
+
+#endif
Index: gcc/testsuite/g++.dg/pph/x2incomplete4.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x2incomplete4.cc	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x2incomplete4.cc	(revision 0)
@@ -0,0 +1,5 @@ 
+// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "internal compiler error: in import_export_decl, at cp/decl2.c" "" { xfail *-*-* } 0 }
+
+#include "x1incomplete3.h"
+#include "a0incomplete4.cci"
Index: gcc/testsuite/g++.dg/pph/x0incomplete3.h
===================================================================
--- gcc/testsuite/g++.dg/pph/x0incomplete3.h	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x0incomplete3.h	(revision 0)
@@ -0,0 +1,7 @@ 
+#ifndef X0INCOMPLETE3_H
+#define X0INCOMPLETE3_H
+
+#include "a0incomplete2.hi"
+#include "a0incomplete3.hi"
+
+#endif
Index: gcc/testsuite/g++.dg/pph/x1incomplete4.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x1incomplete4.cc	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x1incomplete4.cc	(revision 0)
@@ -0,0 +1,2 @@ 
+#include "x0incomplete3.h"
+#include "a0incomplete4.cci"
Index: gcc/testsuite/g++.dg/pph/a0incomplete4.cci
===================================================================
--- gcc/testsuite/g++.dg/pph/a0incomplete4.cci	(revision 0)
+++ gcc/testsuite/g++.dg/pph/a0incomplete4.cci	(revision 0)
@@ -0,0 +1,5 @@ 
+int query( copies arg )
+{
+    copies var( arg );
+    return var.value();
+}
Index: gcc/testsuite/g++.dg/pph/x4incomplete4123.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x4incomplete4123.cc	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x4incomplete4123.cc	(revision 0)
@@ -0,0 +1,4 @@ 
+#include "x0incomplete1.h"
+#include "x0incomplete2.h"
+#include "x0incomplete3.h"
+#include "a0incomplete4.cci"
Index: gcc/testsuite/g++.dg/pph/x3incomplete412.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x3incomplete412.cc	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x3incomplete412.cc	(revision 0)
@@ -0,0 +1,4 @@ 
+#include "x0incomplete1.h"
+#include "x0incomplete2.h"
+#include "a0incomplete3.hi"
+#include "a0incomplete4.cci"
Index: gcc/testsuite/g++.dg/pph/a0incomplete2.hi
===================================================================
--- gcc/testsuite/g++.dg/pph/a0incomplete2.hi	(revision 0)
+++ gcc/testsuite/g++.dg/pph/a0incomplete2.hi	(revision 0)
@@ -0,0 +1,12 @@ 
+#ifndef A0INCOMPLETE2_HI
+#define A0INCOMPLETE2_HI
+
+struct copies
+{
+    copies();
+    copies( const copies &arg );
+    int value();
+    int field;
+};
+
+#endif
Index: gcc/testsuite/g++.dg/pph/x4structover1.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x4structover1.cc	(revision 183821)
+++ gcc/testsuite/g++.dg/pph/x4structover1.cc	(working copy)
@@ -1,7 +1,3 @@ 
-// { dg-xfail-if "BOGUS TYPE MERGE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// This test fails because even if we merge type decls,
-// we are not merging the corresponding types.
-
 #include "x0structover1.h"
 #include "x0structover2.h"
 
Index: gcc/testsuite/g++.dg/pph/x4incomplete4321.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x4incomplete4321.cc	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x4incomplete4321.cc	(revision 0)
@@ -0,0 +1,7 @@ 
+// pph asm xdiff 64351
+// XFAIL missing constructors
+
+#include "x0incomplete3.h"
+#include "x0incomplete2.h"
+#include "x0incomplete1.h"
+#include "a0incomplete4.cci"
Index: gcc/testsuite/g++.dg/pph/x3incomplete413.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x3incomplete413.cc	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x3incomplete413.cc	(revision 0)
@@ -0,0 +1,3 @@ 
+#include "x0incomplete1.h"
+#include "x0incomplete3.h"
+#include "a0incomplete4.cci"
Index: gcc/testsuite/g++.dg/pph/a0incomplete3.hi
===================================================================
--- gcc/testsuite/g++.dg/pph/a0incomplete3.hi	(revision 0)
+++ gcc/testsuite/g++.dg/pph/a0incomplete3.hi	(revision 0)
@@ -0,0 +1,21 @@ 
+#ifndef A0INCOMPLETE3_HI
+#define A0INCOMPLETE3_HI
+
+inline copies::copies()
+:
+   field( 0 )
+{
+}
+
+inline copies::copies( const copies &arg )
+:
+   field( arg.field + 1 )
+{
+}
+
+inline int copies::value()
+{
+    return field;
+}
+
+#endif
Index: gcc/testsuite/g++.dg/pph/x0incomplete1.h
===================================================================
--- gcc/testsuite/g++.dg/pph/x0incomplete1.h	(revision 0)
+++ gcc/testsuite/g++.dg/pph/x0incomplete1.h	(revision 0)
@@ -0,0 +1,6 @@ 
+#ifndef X0INCOMPLETE1_H
+#define X0INCOMPLETE1_H
+
+struct stuff;
+
+#endif
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 183821)
+++ gcc/cp/error.c	(working copy)
@@ -1351,7 +1351,7 @@  static void
 dump_function_decl (tree t, int flags)
 {
   tree fntype;
-  tree parmtypes;
+  tree parmtypes, argtypes;
   tree cname = NULL_TREE;
   tree template_args = NULL_TREE;
   tree template_parms = NULL_TREE;
@@ -1393,7 +1393,12 @@  dump_function_decl (tree t, int flags)
     }
 
   fntype = TREE_TYPE (t);
-  parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
+  gcc_assert (fntype)
+  argtypes = TYPE_ARG_TYPES (fntype);
+  if (argtypes)
+    parmtypes = skip_artificial_parms_for (t, argtypes);
+  else
+    parmtypes = NULL;
 
   if (DECL_CLASS_SCOPE_P (t))
     cname = DECL_CONTEXT (t);
Index: gcc/cp/pph-out.c
===================================================================
--- gcc/cp/pph-out.c	(revision 183821)
+++ gcc/cp/pph-out.c	(working copy)
@@ -2353,11 +2353,19 @@  pph_out_merge_key_tree (pph_stream *stre
       /* Write the merge name, used to lookup EXPR in the reader's context
 	 and merge if necessary.  */
       pph_out_merge_name (stream, expr);
+
+      if (TREE_CODE (expr) == TYPE_DECL)
+	{
+	  bool is_implicit = DECL_IMPLICIT_TYPEDEF_P (expr);
+	  tree type = TREE_TYPE (expr);
+	  pph_out_bool (stream, is_implicit);
+	  if (is_implicit)
+	    pph_out_merge_key_tree (stream, type);
+	}
     }
   else
     {
       gcc_assert (TYPE_P (expr));
-      gcc_assert (false);
     }
 
   if (flag_pph_tracer)
Index: gcc/cp/pph-in.c
===================================================================
--- gcc/cp/pph-in.c	(revision 183821)
+++ gcc/cp/pph-in.c	(working copy)
@@ -2116,11 +2116,6 @@  pph_in_merge_tree_body (pph_stream *stre
   struct lto_input_block *ib = stream->encoder.r.ib;
   struct data_in *data_in = stream->encoder.r.data_in;
 
-  /* If we are reading a merge body, it means that EXPR is already in
-     some chain.  Given that EXPR may now be in a different location
-     in the chain, we need to make sure we do not lose it.  */
-  tree saved_expr_chain = TREE_CHAIN (expr);
-
   /* Read the language-independent parts of EXPR's body.  */
   streamer_read_tree_body (ib, data_in, expr);
 
@@ -2128,7 +2123,15 @@  pph_in_merge_tree_body (pph_stream *stre
   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
     {
       case tcc_declaration:
+	{
+	  /* If we are reading a merge body, it means that EXPR is already in
+	     some chain.  Given that EXPR may now be in a different location
+	     in the chain, we need to make sure we do not lose it.
+	     FIXME pph: We should just not save TREE_CHAIN for merge bodies.  */
+	  tree saved_expr_chain = TREE_CHAIN (expr);
        pph_in_merge_tcc_declaration (stream, expr);
+	  TREE_CHAIN (expr) = saved_expr_chain;
+	}
        break;
 
       case tcc_type:
@@ -2140,10 +2143,6 @@  pph_in_merge_tree_body (pph_stream *stre
                     pph_tree_code_text (TREE_CODE (expr)));
        break;
     }
-
-  /* Restore TREE_CHAIN if necessary.  FIXME pph, we should just not
-     save TREE_CHAIN for merge bodies.  */
-  TREE_CHAIN (expr) = saved_expr_chain;
 }
 
 
@@ -2413,7 +2412,7 @@  pph_in_merge_key_tree (pph_stream *strea
   unsigned image_ix, ix;
   tree read_expr, expr;
   bool fully_read_p;
-  const char *name;
+  const char *name = "?";
 
   marker = pph_in_start_record (stream, &image_ix, &ix, PPH_any_tree);
   if (marker == PPH_RECORD_END)
@@ -2426,36 +2425,52 @@  pph_in_merge_key_tree (pph_stream *strea
      language-independent bitfields for the new tree.  */
   read_expr = pph_in_tree_header (stream, &fully_read_p);
   gcc_assert (!fully_read_p);
+  gcc_assert (chain);
 
   if (DECL_P (read_expr))
     {
-      gcc_assert (chain);
       name = pph_in_string (stream);
       /* If we are merging into an existing CHAIN.  Look for a match in
          CHAIN to READ_EXPR's header.  If we found a match, EXPR will be
          the existing tree that matches READ_EXPR. Otherwise, EXPR is the
          newly allocated READ_EXPR.  */
       expr = pph_merge_into_chain (read_expr, name, chain);
-      gcc_assert (expr != NULL);
-      pph_cache_insert_at (&stream->cache, expr, ix,
-			   pph_tree_code_to_tag (expr));
+    }
+  else
+    {
+      gcc_assert (TYPE_P (read_expr));
+      if (*chain)
+	expr = *chain;
+      else
+	expr = read_expr;
+    }
+  gcc_assert (expr != NULL);
+  pph_cache_insert_at (&stream->cache, expr, ix,
+		       pph_tree_code_to_tag (expr));
 
-      if (flag_pph_tracer)
-        pph_trace_tree (expr, name, pph_trace_front,
-		        expr == read_expr ? pph_trace_unmerged_key
-				          : pph_trace_merged_key);
+  if (flag_pph_tracer)
+    pph_trace_tree (expr, name, pph_trace_front,
+		    expr == read_expr ? pph_trace_unmerged_key
+				      : pph_trace_merged_key);
 
-      if (flag_pph_tracer)
-        pph_trace_tree (expr, name, pph_trace_back,
-		        expr == read_expr ? pph_trace_unmerged_key
-				          : pph_trace_merged_key);
+  if (DECL_P (read_expr))
+    {
+      if (TREE_CODE (expr) == TYPE_DECL)
+	{
+	  bool is_implicit = pph_in_bool (stream);
+	  if (is_implicit)
+	    pph_in_merge_key_tree (stream, &(TREE_TYPE (expr)));
+	}
     }
   else
     {
-      gcc_assert (TYPE_P (read_expr));
-      gcc_assert (false);
     }
 
+  if (flag_pph_tracer)
+    pph_trace_tree (expr, name, pph_trace_back,
+		    expr == read_expr ? pph_trace_unmerged_key
+				      : pph_trace_merged_key);
+
   return expr;
 }