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]

[PATCH] Make devirtualization use BINFO_VTABLE instead of BINFO_VIRTUALS


Hi,

the patch below is an updated version of an RFC patch I have sent here
some three weeks ago:

http://gcc.gnu.org/ml/gcc-patches/2011-08/msg00975.html

However, this is no longer an RFC but a request for approval because I
have amended it to work also on architectures that use function
descriptors in their VMTs.

The original mail describes the patch in a bit more detail, the main
points are that:

- This patch significantly reduces memory footprint of WPA when LTOing
  C++ code.  Memory peak of WPA of Firefox decreases by by 36% from
  4554 MB to 2893 MB and that of 483.xalancbmk drops by 21% from
  555205 kB to 439121 kB.  The number of type-based devirtualizations
  is the same for both applications.  (I have verified all these
  numbers today.)

- Nevertheless, this method of devirtualization cannot automatically
  de-thunkize this-adjusting thunks and newly direct calls to them
  cannot be inlined because the inliner does not have this capability
  now.  This is in fact a regression from 4.6, and testcases
  ivinline-7.C and ivinline-9.C had to be XFAILed exactly for this
  reason.  The size of the memory savings and the fact that we do not
  devirtualize that much now make this an acceptable tradeoff, though.

- The main change of this patch is actually quite small, it is the
  reimplementation of gimple_get_virt_method_for_binfo and BINFO
  streaming.  However, because of the missing de-thunkization, all
  various delta parameters and fields could go away and associated
  code is dead.  I removed some of it but not all because it might be
  useful soon (such as edge optimization info streaming functions and
  gimple_adjust_this_by_delta).  I can remove those too upon request.

I have changed the testcase devirt-3.C slightly so that the called
function was not the first in the MVT, this has proved to be useful
when adjusting the patch for ia64.

I have bootstrapped and tested this patch on x86_64-linux (all
languages including obj-c++ and Ada) and ia64-linux (without Ada).  I
have also verified that LTOed Firefox browses and 483.xalancbmk gives
the expected testing output.  So, OK for trunk?

Thanks,

Martin



2011-08-31  Martin Jambor  <mjambor@suse.cz>

	* cgraph.h (cgraph_indirect_call_info): Removed field thunk_delta.
	* gimple-fold.c (gimple_get_virt_method_for_binfo): Rewritten to use
	BINFO_VTABLE.  Parameter delta removed, all callers updated.
	* tree.c (free_lang_data_in_binfo): Clear BINFO_VIRTUALs instead
	BINFO_VTABLE.
	* cgraph.c (cgraph_make_edge_direct): Removed parameter delta, updated
	all calls.
	* cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Removed
	handling of thunk_delta.
	* ipa-cp.c (get_indirect_edge_target): Removed parameter delta.
	(devirtualization_time_bonus): Do not handle thunk deltas.
	(ipcp_discover_new_direct_edges): Likewise.
	* ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.
	(try_make_edge_direct_simple_call): Likewise.
	(try_make_edge_direct_virtual_call): Likewise.
	* lto-cgraph.c (output_cgraph_opt_summary_p): Likewise.  Mark
	parameter set as unused.
	(output_edge_opt_summary): Likewise.  Mark both parameters as unused.
	* lto-cgraph.c (output_cgraph_opt_summary_p): Likewise.  Mark
	parameter set as unused.
	(output_edge_opt_summary): Likewise.  Mark both parameters as unused.
	(input_edge_opt_summary): Likewise.
	* lto-streamer-out.c (lto_output_ts_binfo_tree_pointers): Do not stream
	BINFO_VIRTUALS at all.
	* lto-streamer-in.c (lto_input_ts_binfo_tree_pointers): Likewise.

	* testsuite/g++.dg/ipa/devirt-3.C: Added a distraction method.
	* testsuite/g++.dg/ipa/ivinline-7.C: Added a test for direct call
	discovery, xfailed test for inlining.
	* testsuite/g++.dg/ipa/ivinline-9.C: Likewise.

Index: src/gcc/gimple-fold.c
===================================================================
--- src.orig/gcc/gimple-fold.c
+++ src/gcc/gimple-fold.c
@@ -1381,51 +1381,6 @@ gimple_fold_builtin (gimple stmt)
   return result;
 }
 
-/* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
-   is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
-   KNOWN_BINFO carries the binfo describing the true type of
-   OBJ_TYPE_REF_OBJECT(REF).  If a call to the function must be accompanied
-   with a this adjustment, the constant which should be added to this pointer
-   is stored to *DELTA.  If REFUSE_THUNKS is true, return NULL if the function
-   is a thunk (other than a this adjustment which is dealt with by DELTA). */
-
-tree
-gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
-				  tree *delta)
-{
-  HOST_WIDE_INT i;
-  tree v, fndecl;
-
-  v = BINFO_VIRTUALS (known_binfo);
-  /* If there is no virtual methods leave the OBJ_TYPE_REF alone.  */
-  if (!v)
-    return NULL_TREE;
-  i = 0;
-  while (i != token)
-    {
-      i += (TARGET_VTABLE_USES_DESCRIPTORS
-	    ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
-      v = TREE_CHAIN (v);
-    }
-
-  /* If BV_VCALL_INDEX is non-NULL, give up.  */
-  if (TREE_TYPE (v))
-    return NULL_TREE;
-
-  fndecl = TREE_VALUE (v);
-
-  /* When cgraph node is missing and function is not public, we cannot
-     devirtualize.  This can happen in WHOPR when the actual method
-     ends up in other partition, because we found devirtualization
-     possibility too late.  */
-  if (!can_refer_decl_in_current_unit_p (TREE_VALUE (v)))
-    return NULL_TREE;
-
-  *delta = TREE_PURPOSE (v);
-  gcc_checking_assert (host_integerp (*delta, 0));
-  return fndecl;
-}
-
 /* Generate code adjusting the first parameter of a call statement determined
    by GSI by DELTA.  */
 
@@ -1548,7 +1503,7 @@ gimple_fold_call (gimple_stmt_iterator *
   callee = gimple_call_fn (stmt);
   if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
     {
-      tree binfo, fndecl, delta, obj;
+      tree binfo, fndecl, obj;
       HOST_WIDE_INT token;
 
       if (gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)) != NULL_TREE)
@@ -1562,10 +1517,9 @@ gimple_fold_call (gimple_stmt_iterator *
       if (!binfo)
 	return false;
       token = TREE_INT_CST_LOW (OBJ_TYPE_REF_TOKEN (callee));
-      fndecl = gimple_get_virt_method_for_binfo (token, binfo, &delta);
+      fndecl = gimple_get_virt_method_for_binfo (token, binfo);
       if (!fndecl)
 	return false;
-      gcc_assert (integer_zerop (delta));
       gimple_call_set_fndecl (stmt, fndecl);
       return true;
     }
@@ -3471,6 +3425,60 @@ fold_const_aggregate_ref (tree t)
   return fold_const_aggregate_ref_1 (t, NULL);
 }
 
+/* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
+   is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
+   KNOWN_BINFO carries the binfo describing the true type of
+   OBJ_TYPE_REF_OBJECT(REF).  */
+
+tree
+gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo)
+{
+  unsigned HOST_WIDE_INT offset, size;
+  tree v, fn;
+
+  v = BINFO_VTABLE (known_binfo);
+  /* If there is no virtual methods table, leave the OBJ_TYPE_REF alone.  */
+  if (!v)
+    return NULL_TREE;
+
+  if (TREE_CODE (v) == POINTER_PLUS_EXPR)
+    {
+      offset = tree_low_cst (TREE_OPERAND (v, 1), 1) * BITS_PER_UNIT;
+      v = TREE_OPERAND (v, 0);
+    }
+  else
+    offset = 0;
+
+  if (TREE_CODE (v) != ADDR_EXPR)
+    return NULL_TREE;
+  v = TREE_OPERAND (v, 0);
+
+  if (TREE_CODE (v) != VAR_DECL
+      || !DECL_VIRTUAL_P (v)
+      || !DECL_INITIAL (v))
+    return NULL_TREE;
+  gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
+  size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))), 1);
+  offset += token * size;
+  fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), DECL_INITIAL (v),
+			    offset, size);
+  if (!fn)
+    return NULL_TREE;
+  gcc_assert (TREE_CODE (fn) == ADDR_EXPR
+	      || TREE_CODE (fn) == FDESC_EXPR);
+  fn = TREE_OPERAND (fn, 0);
+  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+  /* When cgraph node is missing and function is not public, we cannot
+     devirtualize.  This can happen in WHOPR when the actual method
+     ends up in other partition, because we found devirtualization
+     possibility too late.  */
+  if (!can_refer_decl_in_current_unit_p (fn))
+    return NULL_TREE;
+
+  return fn;
+}
+
 /* Return true iff VAL is a gimple expression that is known to be
    non-negative.  Restricted to floating-point inputs.  */
 
Index: src/gcc/tree.c
===================================================================
--- src.orig/gcc/tree.c
+++ src/gcc/tree.c
@@ -4397,7 +4397,7 @@ free_lang_data_in_one_sizepos (tree *exp
 
 
 /* Reset all the fields in a binfo node BINFO.  We only keep
-   BINFO_VIRTUALS, which is used by gimple_fold_obj_type_ref.  */
+   BINFO_VTABLE, which is used by gimple_fold_obj_type_ref.  */
 
 static void
 free_lang_data_in_binfo (tree binfo)
@@ -4407,7 +4407,7 @@ free_lang_data_in_binfo (tree binfo)
 
   gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
 
-  BINFO_VTABLE (binfo) = NULL_TREE;
+  BINFO_VIRTUALS (binfo) = NULL_TREE;
   BINFO_BASE_ACCESSES (binfo) = NULL;
   BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
   BINFO_SUBVTT_INDEX (binfo) = NULL_TREE;
Index: src/gcc/testsuite/g++.dg/ipa/ivinline-7.C
===================================================================
--- src.orig/gcc/testsuite/g++.dg/ipa/ivinline-7.C
+++ src/gcc/testsuite/g++.dg/ipa/ivinline-7.C
@@ -75,5 +75,6 @@ int main (int argc, char *argv[])
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  } } */
+/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo"  "inline"  } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  { xfail *-*-* } } } */
 /* { dg-final { cleanup-ipa-dump "inline" } } */
Index: src/gcc/testsuite/g++.dg/ipa/ivinline-9.C
===================================================================
--- src.orig/gcc/testsuite/g++.dg/ipa/ivinline-9.C
+++ src/gcc/testsuite/g++.dg/ipa/ivinline-9.C
@@ -89,5 +89,6 @@ int main (int argc, char *argv[])
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  } } */
+/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo"  "inline"  } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  { xfail *-*-* } } } */
 /* { dg-final { cleanup-ipa-dump "inline" } } */
Index: src/gcc/cgraph.c
===================================================================
--- src.orig/gcc/cgraph.c
+++ src/gcc/cgraph.c
@@ -835,7 +835,7 @@ cgraph_set_call_stmt (struct cgraph_edge
       struct cgraph_node *new_callee = cgraph_get_node (decl);
 
       gcc_checking_assert (new_callee);
-      cgraph_make_edge_direct (e, new_callee, 0);
+      cgraph_make_edge_direct (e, new_callee);
     }
 
   push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
@@ -1161,11 +1161,9 @@ cgraph_redirect_edge_callee (struct cgra
    pointer (first parameter) to compensate for skipping a thunk adjustment.  */
 
 void
-cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee,
-			 HOST_WIDE_INT delta)
+cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee)
 {
   edge->indirect_unknown_callee = 0;
-  edge->indirect_info->thunk_delta = delta;
 
   /* Get the edge out of the indirect edge list. */
   if (edge->prev_callee)
Index: src/gcc/cgraph.h
===================================================================
--- src.orig/gcc/cgraph.h
+++ src/gcc/cgraph.h
@@ -314,9 +314,6 @@ struct GTY(()) cgraph_indirect_call_info
   HOST_WIDE_INT anc_offset;
   /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set).  */
   HOST_WIDE_INT otr_token;
-  /* Delta by which must be added to this parameter to compensate for a skipped
-     this adjusting thunk.  */
-  HOST_WIDE_INT thunk_delta;
   /* Type of the object from OBJ_TYPE_REF_OBJECT. */
   tree otr_type;
   /* Index of the parameter that is called.  */
@@ -507,8 +504,7 @@ struct cgraph_node * cgraph_clone_node (
 struct cgraph_node *cgraph_create_function_alias (tree, tree);
 
 void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
-void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *,
-			      HOST_WIDE_INT);
+void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *);
 bool cgraph_only_called_directly_p (struct cgraph_node *);
 
 struct cgraph_asm_node *cgraph_add_asm_node (tree);
Index: src/gcc/cgraphunit.c
===================================================================
--- src.orig/gcc/cgraphunit.c
+++ src/gcc/cgraphunit.c
@@ -2367,7 +2367,6 @@ cgraph_redirect_edge_call_stmt_to_callee
   tree decl = gimple_call_fndecl (e->call_stmt);
   gimple new_stmt;
   gimple_stmt_iterator gsi;
-  bool gsi_computed = false;
 #ifdef ENABLE_CHECKING
   struct cgraph_node *node;
 #endif
@@ -2398,21 +2397,6 @@ cgraph_redirect_edge_call_stmt_to_callee
 	}
     }
 
-  if (e->indirect_info &&
-      e->indirect_info->thunk_delta != 0
-      && (!e->callee->clone.combined_args_to_skip
-	  || !bitmap_bit_p (e->callee->clone.combined_args_to_skip, 0)))
-    {
-      if (cgraph_dump_file)
-	fprintf (cgraph_dump_file, "          Thunk delta is "
-		 HOST_WIDE_INT_PRINT_DEC "\n", e->indirect_info->thunk_delta);
-      gsi = gsi_for_stmt (e->call_stmt);
-      gsi_computed = true;
-      gimple_adjust_this_by_delta (&gsi,
-				   size_int (e->indirect_info->thunk_delta));
-      e->indirect_info->thunk_delta = 0;
-    }
-
   if (e->callee->clone.combined_args_to_skip)
     {
       int lp_nr;
@@ -2426,8 +2410,7 @@ cgraph_redirect_edge_call_stmt_to_callee
 	  && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
 	SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
 
-      if (!gsi_computed)
-	gsi = gsi_for_stmt (e->call_stmt);
+      gsi = gsi_for_stmt (e->call_stmt);
       gsi_replace (&gsi, new_stmt, false);
       /* We need to defer cleaning EH info on the new statement to
          fixup-cfg.  We may not have dominator information at this point
Index: src/gcc/gimple.h
===================================================================
--- src.orig/gcc/gimple.h
+++ src/gcc/gimple.h
@@ -909,7 +909,7 @@ unsigned get_gimple_rhs_num_ops (enum tr
 gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
 const char *gimple_decl_printable_name (tree, int);
 bool gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace);
-tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree, tree *);
+tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree);
 void gimple_adjust_this_by_delta (gimple_stmt_iterator *, tree);
 tree gimple_extract_devirt_binfo_from_cst (tree);
 /* Returns true iff T is a valid GIMPLE statement.  */
Index: src/gcc/ipa-cp.c
===================================================================
--- src.orig/gcc/ipa-cp.c
+++ src/gcc/ipa-cp.c
@@ -1110,11 +1110,10 @@ propagate_constants_accross_call (struct
 
 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
    (which can contain both constants and binfos) or KNOWN_BINFOS (which can be
-   NULL) return the destination.  If simple thunk delta must be applied too,
-   store it to DELTA.  */
+   NULL) return the destination.  */
 
 static tree
-get_indirect_edge_target (struct cgraph_edge *ie, tree *delta,
+get_indirect_edge_target (struct cgraph_edge *ie,
 			  VEC (tree, heap) *known_vals,
 			  VEC (tree, heap) *known_binfos)
 {
@@ -1132,10 +1131,7 @@ get_indirect_edge_target (struct cgraph_
       if (t &&
 	  TREE_CODE (t) == ADDR_EXPR
 	  && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
-	{
-	  *delta = NULL_TREE;
-	  return TREE_OPERAND (t, 0);
-	}
+	return TREE_OPERAND (t, 0);
       else
 	return NULL_TREE;
     }
@@ -1159,7 +1155,7 @@ get_indirect_edge_target (struct cgraph_
       binfo = get_binfo_at_offset (binfo, anc_offset, otr_type);
       if (!binfo)
 	return NULL_TREE;
-      return gimple_get_virt_method_for_binfo (token, binfo, delta);
+      return gimple_get_virt_method_for_binfo (token, binfo);
     }
   else
     {
@@ -1168,7 +1164,7 @@ get_indirect_edge_target (struct cgraph_
       binfo = get_binfo_at_offset (t, anc_offset, otr_type);
       if (!binfo)
 	return NULL_TREE;
-      return gimple_get_virt_method_for_binfo (token, binfo, delta);
+      return gimple_get_virt_method_for_binfo (token, binfo);
     }
 }
 
@@ -1187,9 +1183,9 @@ devirtualization_time_bonus (struct cgra
     {
       struct cgraph_node *callee;
       struct inline_summary *isummary;
-      tree delta, target;
+      tree target;
 
-      target = get_indirect_edge_target (ie, &delta, known_csts, known_binfos);
+      target = get_indirect_edge_target (ie, known_csts, known_binfos);
       if (!target)
 	continue;
 
@@ -1674,12 +1670,12 @@ ipcp_discover_new_direct_edges (struct c
 
   for (ie = node->indirect_calls; ie; ie = next_ie)
     {
-      tree delta, target;
+      tree target;
 
       next_ie = ie->next_callee;
-      target = get_indirect_edge_target (ie, &delta, known_vals, NULL);
+      target = get_indirect_edge_target (ie, known_vals, NULL);
       if (target)
-	ipa_make_edge_direct_to_target (ie, target, delta);
+	ipa_make_edge_direct_to_target (ie, target);
     }
 }
 
Index: src/gcc/ipa-prop.c
===================================================================
--- src.orig/gcc/ipa-prop.c
+++ src/gcc/ipa-prop.c
@@ -1614,12 +1614,10 @@ update_jump_functions_after_inlining (st
 }
 
 /* If TARGET is an addr_expr of a function declaration, make it the destination
-   of an indirect edge IE and return the edge.  Otherwise, return NULL.  Delta,
-   if non-NULL, is an integer constant that must be added to this pointer
-   (first parameter).  */
+   of an indirect edge IE and return the edge.  Otherwise, return NULL.  */
 
 struct cgraph_edge *
-ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, tree delta)
+ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
 {
   struct cgraph_node *callee;
 
@@ -1632,11 +1630,11 @@ ipa_make_edge_direct_to_target (struct c
     return NULL;
   ipa_check_create_node_params ();
 
-  /* We can not make edges to inline clones.  It is bug that someone removed the cgraph
-     node too early.  */
+  /* We can not make edges to inline clones.  It is bug that someone removed
+     the cgraph node too early.  */
   gcc_assert (!callee->global.inlined_to);
 
-  cgraph_make_edge_direct (ie, callee, delta ? tree_low_cst (delta, 0) : 0);
+  cgraph_make_edge_direct (ie, callee);
   if (dump_file)
     {
       fprintf (dump_file, "ipa-prop: Discovered %s call to a known target "
@@ -1648,13 +1646,6 @@ ipa_make_edge_direct_to_target (struct c
 	print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
       else
 	fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
-
-      if (delta)
-	{
-	  fprintf (dump_file, "          Thunk delta is ");
-	  print_generic_expr (dump_file, delta, 0);
-	  fprintf (dump_file, "\n");
-	}
     }
   callee = cgraph_function_or_thunk_node (callee, NULL);
 
@@ -1683,7 +1674,7 @@ try_make_edge_direct_simple_call (struct
   else
     return NULL;
 
-  return ipa_make_edge_direct_to_target (ie, target, NULL_TREE);
+  return ipa_make_edge_direct_to_target (ie, target);
 }
 
 /* Try to find a destination for indirect edge IE that corresponds to a
@@ -1695,7 +1686,7 @@ static struct cgraph_edge *
 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
 				   struct ipa_jump_func *jfunc)
 {
-  tree binfo, type, target, delta;
+  tree binfo, type, target;
   HOST_WIDE_INT token;
 
   if (jfunc->type == IPA_JF_KNOWN_TYPE)
@@ -1710,12 +1701,12 @@ try_make_edge_direct_virtual_call (struc
   type = ie->indirect_info->otr_type;
   binfo = get_binfo_at_offset (binfo, ie->indirect_info->anc_offset, type);
   if (binfo)
-    target = gimple_get_virt_method_for_binfo (token, binfo, &delta);
+    target = gimple_get_virt_method_for_binfo (token, binfo);
   else
     return NULL;
 
   if (target)
-    return ipa_make_edge_direct_to_target (ie, target, delta);
+    return ipa_make_edge_direct_to_target (ie, target);
   else
     return NULL;
 }
Index: src/gcc/ipa-prop.h
===================================================================
--- src.orig/gcc/ipa-prop.h
+++ src/gcc/ipa-prop.h
@@ -367,8 +367,7 @@ bool ipa_propagate_indirect_call_infos (
 					VEC (cgraph_edge_p, heap) **new_edges);
 
 /* Indirect edge and binfo processing.  */
-struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
-						    tree);
+struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree);
 
 /* Functions related to both.  */
 void ipa_analyze_node (struct cgraph_node *);
Index: src/gcc/lto-cgraph.c
===================================================================
--- src.orig/gcc/lto-cgraph.c
+++ src/gcc/lto-cgraph.c
@@ -1501,22 +1501,9 @@ input_cgraph (void)
 /* True when we need optimization summary for NODE.  */
 
 static int
-output_cgraph_opt_summary_p (struct cgraph_node *node, cgraph_node_set set)
+output_cgraph_opt_summary_p (struct cgraph_node *node,
+			     cgraph_node_set set ATTRIBUTE_UNUSED)
 {
-  struct cgraph_edge *e;
-
-  if (cgraph_node_in_set_p (node, set))
-    {
-      for (e = node->callees; e; e = e->next_callee)
-	if (e->indirect_info
-	    && e->indirect_info->thunk_delta != 0)
-	  return true;
-
-      for (e = node->indirect_calls; e; e = e->next_callee)
-	if (e->indirect_info->thunk_delta != 0)
-	  return true;
-    }
-
   return (node->clone_of
 	  && (node->clone.tree_map
 	      || node->clone.args_to_skip
@@ -1525,13 +1512,9 @@ output_cgraph_opt_summary_p (struct cgra
 
 /* Output optimization summary for EDGE to OB.  */
 static void
-output_edge_opt_summary (struct output_block *ob,
-			 struct cgraph_edge *edge)
+output_edge_opt_summary (struct output_block *ob ATTRIBUTE_UNUSED,
+			 struct cgraph_edge *edge ATTRIBUTE_UNUSED)
 {
-  if (edge->indirect_info)
-    streamer_write_hwi (ob, edge->indirect_info->thunk_delta);
-  else
-    streamer_write_hwi (ob, 0);
 }
 
 /* Output optimization summary for NODE to OB.  */
@@ -1631,17 +1614,9 @@ output_cgraph_opt_summary (cgraph_node_s
 /* Input optimisation summary of EDGE.  */
 
 static void
-input_edge_opt_summary (struct cgraph_edge *edge,
-			struct lto_input_block *ib_main)
+input_edge_opt_summary (struct cgraph_edge *edge ATTRIBUTE_UNUSED,
+			struct lto_input_block *ib_main ATTRIBUTE_UNUSED)
 {
-  HOST_WIDE_INT thunk_delta;
-  thunk_delta = streamer_read_hwi (ib_main);
-  if (thunk_delta != 0)
-    {
-      gcc_assert (!edge->indirect_info);
-      edge->indirect_info = cgraph_allocate_init_indirect_info ();
-      edge->indirect_info->thunk_delta = thunk_delta;
-    }
 }
 
 /* Input optimisation summary of NODE.  */
Index: src/gcc/tree-streamer-in.c
===================================================================
--- src.orig/gcc/tree-streamer-in.c
+++ src/gcc/tree-streamer-in.c
@@ -841,7 +841,6 @@ lto_input_ts_binfo_tree_pointers (struct
 
   BINFO_OFFSET (expr) = stream_read_tree (ib, data_in);
   BINFO_VTABLE (expr) = stream_read_tree (ib, data_in);
-  BINFO_VIRTUALS (expr) = stream_read_tree (ib, data_in);
   BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in);
 
   len = streamer_read_uhwi (ib);
Index: src/gcc/tree-streamer-out.c
===================================================================
--- src.orig/gcc/tree-streamer-out.c
+++ src/gcc/tree-streamer-out.c
@@ -701,11 +701,6 @@ write_ts_binfo_tree_pointers (struct out
 
   stream_write_tree (ob, BINFO_OFFSET (expr), ref_p);
   stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
-  /* BINFO_VIRTUALS is used to drive type based devirtualizatoin.  It often links
-     together large portions of programs making it harder to partition.  Becuase
-     devirtualization is interesting before inlining, only, there is no real
-     need to ship it into ltrans partition.  */
-  stream_write_tree (ob, flag_wpa ? NULL : BINFO_VIRTUALS (expr), ref_p);
   stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p);
 
   streamer_write_uhwi (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
Index: src/gcc/testsuite/g++.dg/ipa/devirt-3.C
===================================================================
--- src.orig/gcc/testsuite/g++.dg/ipa/devirt-3.C
+++ src/gcc/testsuite/g++.dg/ipa/devirt-3.C
@@ -9,6 +9,7 @@ class A
 {
 public:
   int data;
+  virtual float distraction (float f);
   virtual int foo (int i);
 };
 
@@ -24,6 +25,12 @@ public:
   virtual int foo (int i);
 };
 
+float A::distraction (float f)
+{
+  f += 6.2;
+  return f/2;
+}
+
 int A::foo (int i)
 {
   return i + 1;


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