public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [lto][patch] Update cgraph with the symbol resolution information
@ 2008-10-22 14:47 Rafael Espindola
  2008-10-22 15:01 ` Diego Novillo
  0 siblings, 1 reply; 2+ messages in thread
From: Rafael Espindola @ 2008-10-22 14:47 UTC (permalink / raw)
  To: gcc-patches; +Cc: Diego Novillo

[-- Attachment #1: Type: text/plain, Size: 1053 bytes --]

With this patch it is possible to have two .o with functions with the
same name and select among them by editing the resolution file passed
to lto1.

There is a remaining issue with extern inline functions. This can be
fixed by running the inliner during lgen (cc1/cc1plus). I am working
on that.

2008-10-07 Rafael Espindola  <espindola@google.com>

	* Make-lang.in (lto/lto-lang.o): Update dependencies.
	* lto-lang.c: Include lto/common.h and lto-tree-in.h.
	(input_overwrite_node): Don't call cgraph_mark_needed_node.
	(input_node): Just read the node. Don't update it to reflect that
	another node for the same decl might have been read.
	(input_edge): Don't create an edge if the caller has been preempted.
	Make sure the callee is the prevailing decl.
	(input_cgraph_1): Remove nodes corresponding to preempted decls.
	* lto.c (lto_main): Read the cgraph before calling lto_fixup_decls.

Cheers,
-- 
Rafael Avila de Espindola

Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: cgraph.patch --]
[-- Type: text/x-diff; name=cgraph.patch, Size: 8563 bytes --]

diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index 1678926..d6f45e7 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -91,7 +91,8 @@ LTO_TREE_H = lto/lto-tree.h $(PLUGIN_API_H)
 lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \
 	flags.h $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(SYSTEM_H) \
 	$(TM_H) $(LTO_TREE_H) $(LTO_H) $(GIMPLE_H) \
-	gtype-lto.h gt-lto-lto-lang.h except.h libfuncs.h
+	gtype-lto.h gt-lto-lto-lang.h except.h libfuncs.h lto/common.h \
+	lto-tree-in.h
 lto/lto.o: lto/lto.c $(CONFIG_H) $(CGRAPH_H) coretypes.h \
 	$(GGC_H) opts.h $(SYSTEM_H) toplev.h $(TM_H) $(LTO_H) langhooks.h \
 	$(LTO_TREE_H) dwarf2out.h tree-ssa-operands.h gt-lto-lto.h \
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 7dfcdc2..c2026d7 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -38,6 +38,8 @@ Boston, MA 02110-1301, USA.  */
 #include "libfuncs.h"
 #include "except.h"
 #include "cgraph.h"
+#include "lto/common.h"
+#include "lto-tree-in.h"
 
 static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
@@ -1099,8 +1101,6 @@ input_overwrite_node (struct lto_file_decl_data* file_data,
   node->needed = lto_get_flag (&flags);
   node->analyzed = node->local.finalized;
   node->lowered = node->local.finalized;
-  if (cgraph_decide_is_function_needed (node))
-    cgraph_mark_needed_node (node);
 }
 
 /* Read a node from input_block IB.  TAG is the node's tag just read. 
@@ -1120,14 +1120,13 @@ input_node (struct lto_file_decl_data* file_data,
   int self_insns = 0;
   unsigned decl_index;
   bool clone_p;
-  bool overwrite_p = false;
   int estimated_stack_size = 0;
   int stack_frame_offset = 0;
   int ref = LCC_NOT_FOUND;
   int insns = 0;
   int estimated_growth = 0;
   bool inlined = false;
-	  
+
   LTO_DEBUG_TOKEN ("clone_p");
   clone_p = lto_input_uleb128 (ib);
 
@@ -1175,50 +1174,21 @@ input_node (struct lto_file_decl_data* file_data,
       inlined = lto_input_uleb128 (ib);
     }
 
-  switch (tag)
-    {
-    case LTO_cgraph_avail_node:
-      /* We cannot have two avail functions that are the same.  */
-      gcc_assert (((enum LTO_cgraph_tags)(node->aux))
-		  != LTO_cgraph_avail_node);
-      overwrite_p = true;
-      break;
-	      
-    case LTO_cgraph_unavail_node:
-      /* We only overwrite the node if this is a brand new node.  */
-      if (!node->aux)
-	overwrite_p = true;
-      break;
-      
-    case LTO_cgraph_overwritable_node:
-      /* FIXME lto: This code is written to take the last
-	 overwrittable version.  I do not speak linker but if the
-	 linker supposed to take the first one, then we need to
-	 change the test.  */
-      if (((enum LTO_cgraph_tags)(node->aux)) != LTO_cgraph_avail_node)
-	overwrite_p = true;
-      break;
-      
-    default:
-      gcc_unreachable ();
-    }
+  gcc_assert (!node->aux);
 
-  if (overwrite_p)
+  input_overwrite_node (file_data, node, tag, flags, stack_size,
+			self_insns);
+  if (flag_ltrans)
     {
-      input_overwrite_node (file_data, node, tag, flags, stack_size,
-			    self_insns);
-      if (flag_ltrans)
-	{
-	  node->global.estimated_stack_size = estimated_stack_size;
-	  node->global.stack_frame_offset = stack_frame_offset;
-	  node->global.insns = insns;
-	  if (ref != LCC_NOT_FOUND)
-	    node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
-	  else
-	    node->global.inlined_to = NULL;
-	  node->global.estimated_growth = estimated_growth;
-	  node->global.inlined = inlined;
-	}
+      node->global.estimated_stack_size = estimated_stack_size;
+      node->global.stack_frame_offset = stack_frame_offset;
+      node->global.insns = insns;
+      if (ref != LCC_NOT_FOUND)
+	node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
+      else
+	node->global.inlined_to = NULL;
+      node->global.estimated_growth = estimated_growth;
+      node->global.inlined = inlined;
     }
 
   return node;
@@ -1238,15 +1208,29 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
   unsigned int nest;
   cgraph_inline_failed_t inline_failed;
   unsigned HOST_WIDEST_INT flags;
+  tree prevailing;
+  enum ld_plugin_symbol_resolution caller_resolution;
 
   LTO_DEBUG_TOKEN ("caller");
   caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
   gcc_assert (caller);
+  gcc_assert (caller->decl);
 
   LTO_DEBUG_TOKEN ("callee");
   callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
   gcc_assert (callee);
-	  
+  gcc_assert (callee->decl);
+
+  caller_resolution = lto_symtab_get_resolution (caller->decl);
+
+  /* FIXME lto: The following assert would currently fail since for bodies
+     of extern inline functions. */
+
+/*   gcc_assert (caller_resolution == LDPR_PREVAILING_DEF */
+/* 	      || caller_resolution == LDPR_PREVAILING_DEF_IRONLY */
+/* 	      || caller_resolution == LDPR_PREEMPTED_REG */
+/* 	      || caller_resolution == LDPR_PREEMPTED_IR); */
+
   LTO_DEBUG_TOKEN ("stmt");
   stmt_id = lto_input_uleb128 (ib);
   LTO_DEBUG_TOKEN ("inline_failed");
@@ -1259,7 +1243,35 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
   nest = lto_input_uleb128 (ib);
   LTO_DEBUG_TOKEN ("flags");
   flags = lto_input_uleb128 (ib);
-	  
+
+  /* If the caller was preempted, don't create the edge. */
+  if (caller_resolution == LDPR_PREEMPTED_REG
+      || caller_resolution == LDPR_PREEMPTED_IR)
+      return;
+
+  /* Make sure the callee is the prevailing decl. */
+  prevailing = lto_symtab_prevailing_decl (callee->decl);
+
+  /* FIXME lto: remove this once extern inline in handled in lgen. */
+  if (caller_resolution != LDPR_PREVAILING_DEF
+      && caller_resolution != LDPR_PREVAILING_DEF_IRONLY
+      && caller_resolution != LDPR_PREEMPTED_REG
+      && caller_resolution != LDPR_PREEMPTED_IR)
+    {
+      /* If we have a extern inline, make sure it is the prevailing. */
+      gcc_assert (prevailing == callee->decl);
+    }
+
+  if (prevailing != callee->decl)
+    {
+      /* We cannot replace a clone! */
+      gcc_assert (callee == cgraph_node (callee->decl));
+
+
+      callee = cgraph_node (prevailing);
+      gcc_assert (callee);
+    }
+
   edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
   edge->lto_stmt_uid = stmt_id;
   edge->inline_failed = inline_failed;
@@ -1278,7 +1290,9 @@ input_cgraph_1 (struct lto_file_decl_data* file_data,
 {
   enum LTO_cgraph_tags tag;
   VEC(cgraph_node_ptr, heap) *nodes = NULL;
+  VEC(cgraph_node_ptr, heap) *del_list = NULL;
   struct cgraph_node *node;
+  unsigned i;
 
   tag = lto_input_uleb128 (ib);
   while (tag)
@@ -1290,6 +1304,8 @@ input_cgraph_1 (struct lto_file_decl_data* file_data,
       else 
 	{
 	  node = input_node (file_data, ib, tag, nodes);
+	  gcc_assert (node);
+	  gcc_assert (node->decl);
 	  VEC_safe_push (cgraph_node_ptr, heap, nodes, node);
 	}
 
@@ -1297,7 +1313,23 @@ input_cgraph_1 (struct lto_file_decl_data* file_data,
       tag = lto_input_uleb128 (ib);
     }
 
+  for (node = cgraph_nodes; node; node = node->next)
+    {
+      tree prevailing = lto_symtab_prevailing_decl (node->decl);
+
+      if (prevailing != node->decl)
+	VEC_safe_push (cgraph_node_ptr, heap, del_list, node);
+    }
+
+   for (i = 0; VEC_iterate (cgraph_node_ptr, del_list, i, node); i++)
+     cgraph_remove_node (node);
+
+   for (node = cgraph_nodes; node; node = node->next)
+     if (cgraph_decide_is_function_needed (node))
+       cgraph_mark_needed_node (node);
+
   VEC_free (cgraph_node_ptr, heap, nodes);
+  VEC_free (cgraph_node_ptr, heap, del_list);
 }
 
 /* Input and merge the cgraph from each of the .o files passed to
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index bc097de..370dc6d 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1026,12 +1026,14 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
 
   all_file_decl_data[j] = NULL;
 
-  lto_fixup_decls (all_file_decl_data);
-
   /* Set the hooks so that all of the ipa passes can read in their data.  */
   lto_set_in_hooks (all_file_decl_data, get_section_data,
 		    free_section_data);
 
+  ipa_read_summaries ();
+
+  lto_fixup_decls (all_file_decl_data);
+
   /* FIXME!!! This loop needs to be changed to use the pass manager to
      call the ipa passes directly.  */
   for (i = 0; i < j; i++)
@@ -1041,8 +1043,6 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
       lto_materialize_constructors_and_inits (file_data);
     }
 
-  ipa_read_summaries ();
-
   if (flag_wpa)
     lto_1_to_1_map ();
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [lto][patch] Update cgraph with the symbol resolution information
  2008-10-22 14:47 [lto][patch] Update cgraph with the symbol resolution information Rafael Espindola
@ 2008-10-22 15:01 ` Diego Novillo
  0 siblings, 0 replies; 2+ messages in thread
From: Diego Novillo @ 2008-10-22 15:01 UTC (permalink / raw)
  To: Rafael Espindola; +Cc: gcc-patches

On Wed, Oct 22, 2008 at 09:49, Rafael Espindola <espindola@google.com> wrote:

> 2008-10-07 Rafael Espindola  <espindola@google.com>
>
>        * Make-lang.in (lto/lto-lang.o): Update dependencies.
>        * lto-lang.c: Include lto/common.h and lto-tree-in.h.
>        (input_overwrite_node): Don't call cgraph_mark_needed_node.
>        (input_node): Just read the node. Don't update it to reflect that
>        another node for the same decl might have been read.
>        (input_edge): Don't create an edge if the caller has been preempted.
>        Make sure the callee is the prevailing decl.
>        (input_cgraph_1): Remove nodes corresponding to preempted decls.
>        * lto.c (lto_main): Read the cgraph before calling lto_fixup_decls.

OK.


Diego.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-10-22 14:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-22 14:47 [lto][patch] Update cgraph with the symbol resolution information Rafael Espindola
2008-10-22 15:01 ` Diego Novillo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).