[lto] Fix thinko in alias pairs streaming

Diego Novillo dnovillo@google.com
Mon Dec 22 23:37:00 GMT 2008


In WPA, we split the call graph into sets which are assigned to
files for LTRANS to convert to final code.  In splitting up the
callgraph, we also assign alias pairs that correspond to each
set.

The problem with this scheme is that I was wrongly retrieving the
cgraph node for the alias, not the target.  We need to retrieve
the the cgraph node for the *assembler name* of the target, as
that's the real function we are interested in.

Bootstrapped and tested on x86_64.


Diego.


2008-12-22  Diego Novillo  <dnovillo@google.com>

	* lto-function-out.c (output_alias_pair_p): New.
	Retrieve the cgraph node for the target of the alias pair.
	(output_constructors_and_inits): Call it.

testsuite/ChangeLog.lto:

2008-12-22  Chris Demetriou  <cgd@google.com>

	* gcc.dg/lto/20081222_0.c: New.
	* gcc.dg/lto/20081222_1.c: New.
	* gcc.dg/lto/20081222_0.h: New.

Index: lto-function-out.c
===================================================================
--- lto-function-out.c	(revision 142855)
+++ lto-function-out.c	(working copy)
@@ -2368,6 +2368,35 @@ output_all_constructors_and_inits (struc
     }
 }
 
+
+/* Return true if alias pair P belongs to the set of cgraph nodes in
+   SET.  If P is a an alias for a VAR_DECL, it can always be emitted.
+   However, for FUNCTION_DECL aliases, we should only output the pair
+   if it belongs to a function whose cgraph node is in SET.
+   Otherwise, the LTRANS phase will get into trouble when finalizing
+   aliases because the alias will refer to a function not defined in
+   the file processed by LTRANS.  */
+
+static bool
+output_alias_pair_p (alias_pair *p, cgraph_node_set set)
+{
+  cgraph_node_set_iterator csi;
+  struct cgraph_node *target_node;
+
+  /* Always emit VAR_DECLs.  FIXME lto, we should probably only emit
+     those VAR_DECLs that are instantiated in this file partition, but
+     we have no easy way of knowing this based on SET.  */
+  if (TREE_CODE (p->decl) == VAR_DECL)
+    return true;
+
+  /* Check if the assembler name for P->TARGET has its cgraph node in SET.  */
+  gcc_assert (TREE_CODE (p->decl) == FUNCTION_DECL);
+  target_node = cgraph_node_for_asm (p->target);
+  csi = cgraph_node_set_find (set, target_node);
+  return (!csi_end_p (csi));
+}
+
+
 /* Output constructors and inits of all vars.  SET is the current
    cgraph node set being output.  */
 
@@ -2407,23 +2436,7 @@ output_constructors_and_inits (cgraph_no
   /* Emit the alias pairs for the nodes in SET.  */
   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++)
     {
-      bool output_p = false;
-
-      /* We only output the alias set for VAR_DECLs and FUNCTION_DECLs
-	 whose cgraph node is in SET.  This prevents problems when
-	 finalizing aliases during LTRANS (where the alias ends up
-	 referring to a function undefined in this file.  */
-      if (TREE_CODE (p->decl) == VAR_DECL)
-	output_p = true;
-      else
-	{
-	  cgraph_node_set_iterator csi;
-	  gcc_assert (TREE_CODE (p->decl) == FUNCTION_DECL);
-	  csi = cgraph_node_set_find (set, cgraph_node (p->decl));
-	  output_p = !csi_end_p (csi);
-	}
-
-      if (output_p)
+      if (output_alias_pair_p (p, set))
 	{
 	  output_expr_operand (ob, p->decl);
 	  LTO_DEBUG_TOKEN ("alias_target");
Index: testsuite/gcc.dg/lto/20081222_0.c
===================================================================
--- testsuite/gcc.dg/lto/20081222_0.c	(revision 0)
+++ testsuite/gcc.dg/lto/20081222_0.c	(revision 0)
@@ -0,0 +1,11 @@
+#include "20081222_0.h"
+
+extern void abort (void);
+
+int
+main ()
+{
+  if (x () == 7)
+    return 0;
+  abort ();
+}
Index: testsuite/gcc.dg/lto/20081222_1.c
===================================================================
--- testsuite/gcc.dg/lto/20081222_1.c	(revision 0)
+++ testsuite/gcc.dg/lto/20081222_1.c	(revision 0)
@@ -0,0 +1,16 @@
+#include "20081222_0.h"
+
+/* Actually, call "x" "INT_X", and make it hidden.  */
+extern __typeof (x) x
+	__asm__ ("INT_x")
+	__attribute__ ((__visibility__ ("hidden")));
+
+int x ()
+{
+  return 7;
+}
+
+/* Make an externally-visible symbol "X" that's an alias for INT_x.  */
+extern __typeof (x) EXT_x
+	__asm__ ("x")
+	__attribute__ ((__alias__ ("INT_x")));
Index: testsuite/gcc.dg/lto/20081222_0.h
===================================================================
--- testsuite/gcc.dg/lto/20081222_0.h	(revision 0)
+++ testsuite/gcc.dg/lto/20081222_0.h	(revision 0)
@@ -0,0 +1 @@
+int x();



More information about the Gcc-patches mailing list