diff mbox

[4.8,PR,58789] Backport cgraph_get_create_real_symbol_node and PR 57084 fix

Message ID 20131029141644.GA29705@virgil.suse
State New
Headers show

Commit Message

Martin Jambor Oct. 29, 2013, 2:16 p.m. UTC
Hi,

PR 58789 has been fixed on trunk by revision 198743 which needs
cgraph_get_create_real_symbol_node introduced in revision 196750.
This patch backports both.  It has been pre-approved by Honza in
person and passed bootstrap and testing on the branch.  I am about
to commit it momentarily.

Thanks,

Martin


2013-10-25  Martin Jambor  <mjambor@suse.cz>

	PR middle-end/58789
	Backport from mainline
        2013-05-09  Martin Jambor  <mjambor@suse.cz>

	PR lto/57084
	* gimple-fold.c (canonicalize_constructor_val): Call
	cgraph_get_create_real_symbol_node instead of cgraph_get_create_node.

	Backport from mainline
	2013-03-16  Jan Hubicka  <jh@suse.cz>

	* cgraph.h (cgraph_get_create_real_symbol_node): Declare.
	* cgraph.c (cgraph_get_create_real_symbol_node): New function.
	* cgrpahbuild.c: Use cgraph_get_create_real_symbol_node instead
	of cgraph_get_create_node.
	* ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.
diff mbox

Patch

diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 8c1efb4..fd3aade 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -2596,4 +2596,47 @@  verify_cgraph (void)
   FOR_EACH_FUNCTION (node)
     verify_cgraph_node (node);
 }
+
+/* Create external decl node for DECL.
+   The difference i nbetween cgraph_get_create_node and
+   cgraph_get_create_real_symbol_node is that cgraph_get_create_node
+   may return inline clone, while cgraph_get_create_real_symbol_node
+   will create a new node in this case.
+   FIXME: This function should be removed once clones are put out of decl
+   hash.  */
+
+struct cgraph_node *
+cgraph_get_create_real_symbol_node (tree decl)
+{
+  struct cgraph_node *first_clone = cgraph_get_node (decl);
+  struct cgraph_node *node;
+  /* create symbol table node.  even if inline clone exists, we can not take
+     it as a target of non-inlined call.  */
+  node = cgraph_get_node (decl);
+  if (node && !node->global.inlined_to)
+    return node;
+
+  node = cgraph_create_node (decl);
+
+  /* ok, we previously inlined the function, then removed the offline copy and
+     now we want it back for external call.  this can happen when devirtualizing
+     while inlining function called once that happens after extern inlined and
+     virtuals are already removed.  in this case introduce the external node
+     and make it available for call.  */
+  if (first_clone)
+    {
+      first_clone->clone_of = node;
+      node->clones = first_clone;
+      symtab_prevail_in_asm_name_hash ((symtab_node) node);
+      symtab_insert_node_to_hashtable ((symtab_node) node);
+      if (dump_file)
+	fprintf (dump_file, "Introduced new external node "
+		 "(%s/%i) and turned into root of the clone tree.\n",
+		 xstrdup (cgraph_node_name (node)), node->uid);
+    }
+  else if (dump_file)
+    fprintf (dump_file, "Introduced new external node "
+	     "(%s/%i).\n", xstrdup (cgraph_node_name (node)), node->uid);
+  return node;
+}
 #include "gt-cgraph.h"
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 5df7fb4..8ab7ae1 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -575,6 +575,7 @@  struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
 struct cgraph_node * cgraph_create_node (tree);
 struct cgraph_node * cgraph_create_empty_node (void);
 struct cgraph_node * cgraph_get_create_node (tree);
+struct cgraph_node * cgraph_get_create_real_symbol_node (tree);
 struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree);
 struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT,
 				       HOST_WIDE_INT, tree, tree);
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index fb01f24..a74a4c0 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -73,7 +73,7 @@  record_reference (tree *tp, int *walk_subtrees, void *data)
       decl = get_base_var (*tp);
       if (TREE_CODE (decl) == FUNCTION_DECL)
 	{
-	  struct cgraph_node *node = cgraph_get_create_node (decl);
+	  struct cgraph_node *node = cgraph_get_create_real_symbol_node (decl);
 	  if (!ctx->only_vars)
 	    cgraph_mark_address_taken_node (node);
 	  ipa_record_reference ((symtab_node)ctx->varpool_node,
@@ -143,7 +143,7 @@  record_eh_tables (struct cgraph_node *node, struct function *fun)
     {
       struct cgraph_node *per_node;
 
-      per_node = cgraph_get_create_node (DECL_FUNCTION_PERSONALITY (node->symbol.decl));
+      per_node = cgraph_get_create_real_symbol_node (DECL_FUNCTION_PERSONALITY (node->symbol.decl));
       ipa_record_reference ((symtab_node)node, (symtab_node)per_node, IPA_REF_ADDR, NULL);
       cgraph_mark_address_taken_node (per_node);
     }
@@ -223,7 +223,7 @@  mark_address (gimple stmt, tree addr, void *data)
   addr = get_base_address (addr);
   if (TREE_CODE (addr) == FUNCTION_DECL)
     {
-      struct cgraph_node *node = cgraph_get_create_node (addr);
+      struct cgraph_node *node = cgraph_get_create_real_symbol_node (addr);
       cgraph_mark_address_taken_node (node);
       ipa_record_reference ((symtab_node)data,
 			    (symtab_node)node,
@@ -252,7 +252,7 @@  mark_load (gimple stmt, tree t, void *data)
     {
       /* ??? This can happen on platforms with descriptors when these are
 	 directly manipulated in the code.  Pretend that it's an address.  */
-      struct cgraph_node *node = cgraph_get_create_node (t);
+      struct cgraph_node *node = cgraph_get_create_real_symbol_node (t);
       cgraph_mark_address_taken_node (node);
       ipa_record_reference ((symtab_node)data,
 			    (symtab_node)node,
@@ -330,7 +330,7 @@  build_cgraph_edges (void)
 	    {
 	      tree fn = gimple_omp_parallel_child_fn (stmt);
 	      ipa_record_reference ((symtab_node)node,
-				    (symtab_node)cgraph_get_create_node (fn),
+				    (symtab_node)cgraph_get_create_real_symbol_node (fn),
 				    IPA_REF_ADDR, stmt);
 	    }
 	  if (gimple_code (stmt) == GIMPLE_OMP_TASK)
@@ -338,12 +338,12 @@  build_cgraph_edges (void)
 	      tree fn = gimple_omp_task_child_fn (stmt);
 	      if (fn)
 		ipa_record_reference ((symtab_node)node,
-				      (symtab_node) cgraph_get_create_node (fn),
+				      (symtab_node) cgraph_get_create_real_symbol_node (fn),
 				      IPA_REF_ADDR, stmt);
 	      fn = gimple_omp_task_copy_fn (stmt);
 	      if (fn)
 		ipa_record_reference ((symtab_node)node,
-				      (symtab_node)cgraph_get_create_node (fn),
+				      (symtab_node)cgraph_get_create_real_symbol_node (fn),
 				      IPA_REF_ADDR, stmt);
 	    }
 	}
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index b9211a9..06edced 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -178,7 +178,7 @@  canonicalize_constructor_val (tree cval, tree from_decl)
 	  /* Make sure we create a cgraph node for functions we'll reference.
 	     They can be non-existent if the reference comes from an entry
 	     of an external vtable for example.  */
-	  cgraph_get_create_node (base);
+	  cgraph_get_create_real_symbol_node (base);
 	}
       /* Fixup types in global initializers.  */
       if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index c62dc68..33e8d4d 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2126,7 +2126,6 @@  ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
      we may create the first reference to the object in the unit.  */
   if (!callee || callee->global.inlined_to)
     {
-      struct cgraph_node *first_clone = callee;
 
       /* We are better to ensure we can refer to it.
 	 In the case of static functions we are out of luck, since we already	
@@ -2142,31 +2141,7 @@  ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
 		     xstrdup (cgraph_node_name (ie->callee)), ie->callee->uid);
 	  return NULL;
 	}
-
-      /* Create symbol table node.  Even if inline clone exists, we can not take
-	 it as a target of non-inlined call.  */
-      callee = cgraph_create_node (target);
-
-      /* OK, we previously inlined the function, then removed the offline copy and
-	 now we want it back for external call.  This can happen when devirtualizing
-	 while inlining function called once that happens after extern inlined and
-	 virtuals are already removed.  In this case introduce the external node
-	 and make it available for call.  */
-      if (first_clone)
-	{
-	  first_clone->clone_of = callee;
-	  callee->clones = first_clone;
-	  symtab_prevail_in_asm_name_hash ((symtab_node)callee);
-	  symtab_insert_node_to_hashtable ((symtab_node)callee);
-	  if (dump_file)
-	    fprintf (dump_file, "ipa-prop: Introduced new external node "
-		     "(%s/%i) and turned into root of the clone tree.\n",
-		     xstrdup (cgraph_node_name (callee)), callee->uid);
-	}
-      else if (dump_file)
-	fprintf (dump_file, "ipa-prop: Introduced new external node "
-		 "(%s/%i).\n",
-		 xstrdup (cgraph_node_name (callee)), callee->uid);
+      callee = cgraph_get_create_real_symbol_node (target);
     }
   ipa_check_create_node_params ();