diff mbox

Fix undefined symbols seen at -O3 -fwhopr mozilla build

Message ID 20100916212642.GC6006@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Sept. 16, 2010, 9:26 p.m. UTC
Hi,
building Mozilla with -O3 -fwhopr leads to undefined sybols.  Sadly I did not managed
to reduce the testcase since what happens is bit slipperly (and usual ways of
reducing with -r -nostdlib are pointless for undefined symbols of course).

When inlining functions we always clone the function representing original call.
When inlining function that has already inlined function, we produce clone of clone
since we clone the inline clones.  This is correct since we want to keep
the knowledge we put in while inlining (just as turning indirect calls into
direct).

When streaming we for each clone stream also its master function. In this case
we stream inline clone as master of another inline clone as well as original
function.

While reading in, we assume that decl pointers are unique in input_overwrite_node
and we declare function EXTERN that later causes us to not output it.

I also noticed that code in lto_materialize_function is setting function flags
while it doesn't need to do so (it is already done by WHOPR partitioning).
In this case it messed up the function to be both extenral and static,
so I simply killed it.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

	* lto-cgraph.c (input_overwrite_node): Do not set DECL_EXTERNAL when
	processing clone.

	* lto.c (lto_materialize_function): Do not tamper with STATIC and
	EXTERNAL flags.
diff mbox

Patch

Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c	(revision 164344)
+++ lto-cgraph.c	(working copy)
@@ -956,7 +957,16 @@  input_overwrite_node (struct lto_file_de
   node->lowered = bp_unpack_value (bp, 1);
   node->analyzed = tag == LTO_cgraph_analyzed_node;
   node->in_other_partition = bp_unpack_value (bp, 1);
-  if (node->in_other_partition)
+  if (node->in_other_partition
+      /* Avoid updating decl when we are seeing just inline clone.
+	 When inlining function that has functions already inlined into it,
+	 we produce clones of inline clones.
+
+	 WPA partitioning might put each clone into different unit and
+	 we might end up streaming inline clone from other partition
+	 to support clone we are interested in. */
+      && (!node->clone_of
+	  || node->clone_of->decl != node->decl))
     {
       DECL_EXTERNAL (node->decl) = 1;
       TREE_STATIC (node->decl) = 0;
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 164344)
+++ lto/lto.c	(working copy)
@@ -160,9 +160,6 @@  lto_materialize_function (struct cgraph_
      and also functions that are needed to produce virtual clones.  */
   if (node->analyzed || has_analyzed_clone_p (node))
     {
-      /* This function has a definition.  */
-      TREE_STATIC (decl) = 1;
-
       /* Clones don't need to be read.  */
       if (node->clone_of)
 	return;
@@ -198,8 +195,6 @@  lto_materialize_function (struct cgraph_
       if (!flag_wpa)
 	ggc_collect ();
     }
-  else
-    DECL_EXTERNAL (decl) = 1;
 
   /* Let the middle end know about the function.  */
   rest_of_decl_compilation (decl, 1, 0);