[LTO] [PATCH] Avoid middle/back-end use of set_decl_assembler_name and tree_size lang hooks

Robert Kennedy jimbob@google.com
Thu Mar 15 21:39:00 GMT 2007


This patch eliminates the set_decl_assembler_name and tree_size
lang-hooks from the call graph of LTO. They are still present for
source language front ends; the LTO front end sets the
set_decl_assembler_name to a stub that amounts to gcc_unreachable(),
and leaves the tree_size hook set to the default stub that does the
same.

OK for the LTO branch?

	-- Robert

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 120246)
+++ ChangeLog	(working copy)
@@ -1,3 +1,18 @@
+2007-03-14 Robert Kennedy  <jimbob@google.com>
+
+	Eliminate lang_hooks.set_decl_assembler_name from LTO
+	* tree.h (MBE_DECL_RTL) Define.
+	* optabs.c (init_one_libfunc) Use MBE_DECL_RTL.
+	* varasm.c (pre_name_make_decl_rtl_processing) New function.
+	(post_name_make_decl_rtl_processing) New function.
+	(mbe_make_decl_rtl) New function.
+	(make_decl_rtl) Use pre_name_make_decl_rtl_processing and
+	post_name_make_decl_rtl_processing.
+	* passes.c (rest_of_decl_compilation) Use mbe_make_decl_rtl.
+	* lto/lto.c (lto_read_subroutine_type_subprogram_DIE) Get DECL
+	assembler name from DWARF.
+	* lto/lto-lang.c (lto_set_decl_assembler_name) New function.
+	
 2006-05-22  Gerald Pfeifer  <gerald@pfeifer.com>
 
 	* doc/install.texi (Configuration): Remove reference to CrossGCC
Index: tree.h
===================================================================
--- tree.h	(revision 120246)
+++ tree.h	(working copy)
@@ -2632,14 +2632,42 @@
 #define SET_DECL_VALUE_EXPR(NODE, VAL)			\
   (decl_value_expr_insert (DECL_WRTL_CHECK (NODE), VAL))
 
+/* DECL_RTL should be invoked only from a source language front end
+   because it does source-language-specific processing to determine
+   the assembler name of the DECL.  In particular, it must never be
+   called during LTO.  Apart from language front ends, code such as
+   LTO which needs the RTL for a DECL should use MBE_DECL_RTL.
+
+   Background information: Link-time optimization (LTO) needs to avoid
+   use of lang hooks because at LTO time there is no source language
+   front end running.  Therefore certain routines such as
+   MAKE_DECL_RTL have forked into two routines, one suitable for use
+   at source language compilation time, and the other suitable for use
+   at middle- and back-end time (which includes LTO time).
+
+   One invocation of MAKE_DECL_RTL takes place in the DECL_RTL macro,
+   so forking MAKE_DECL_RTL has necessitated forking the DECL_RTL
+   macro as well.  */
+
 /* Holds the RTL expression for the value of a variable or function.
    This value can be evaluated lazily for functions, variables with
    static storage duration, and labels.  */
 #define DECL_RTL(NODE)					\
   (DECL_WRTL_CHECK (NODE)->decl_with_rtl.rtl		\
-   ? (NODE)->decl_with_rtl.rtl					\
+   ? (NODE)->decl_with_rtl.rtl				\
    : (make_decl_rtl (NODE), (NODE)->decl_with_rtl.rtl))
 
+/* Middle/back-end version of DECL_RTL, which holds the RTL expression
+   for the value of a variable or function.  This value can be
+   evaluated lazily for functions, variables with static storage
+   duration, and labels.  The difference from DECL_RTL is that this
+   macro and mbe_make_decl_rtl require that the DECL's assembler name
+   be specified by the caller, not worked out by a lang-hook.  */
+#define MBE_DECL_RTL(NODE, ASM_NAME)			\
+  (DECL_WRTL_CHECK (NODE)->decl_with_rtl.rtl		\
+   ? (NODE)->decl_with_rtl.rtl				\
+   : (mbe_make_decl_rtl (NODE, ASM_NAME), (NODE)->decl_with_rtl.rtl))
+
 /* Set the DECL_RTL for NODE to RTL.  */
 #define SET_DECL_RTL(NODE, RTL) set_decl_rtl (NODE, RTL)
 
@@ -4479,6 +4507,7 @@
                                                 unsigned int);
 /* varasm.c */
 extern void make_decl_rtl (tree);
+extern void mbe_make_decl_rtl (tree, const char *);
 extern void make_decl_one_only (tree);
 extern int supports_one_only (void);
 extern void resolve_unique_section (tree, int, int);
Index: optabs.c
===================================================================
--- optabs.c	(revision 120246)
+++ optabs.c	(working copy)
@@ -5128,7 +5128,8 @@
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
 
-  symbol = XEXP (DECL_RTL (decl), 0);
+  symbol = XEXP (MBE_DECL_RTL (decl, name), 0);
+  gcc_assert (DECL_ASSEMBLER_NAME (decl));
 
   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
      are the flags assigned by targetm.encode_section_info.  */
Index: varasm.c
===================================================================
--- varasm.c	(revision 120246)
+++ varasm.c	(working copy)
@@ -981,20 +981,12 @@
   return true;
 }
 
-/* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL should
-   have static storage duration.  In other words, it should not be an
-   automatic variable, including PARM_DECLs.
+/* Processing for make_decl_rtl that takes place before knowing the
+   assembler name for the DECL.  */
 
-   There is, however, one exception: this function handles variables
-   explicitly placed in a particular register by the user.
-
-   This is never called for PARM_DECL nodes.  */
-
-void
-make_decl_rtl (tree decl)
+static void
+pre_name_make_decl_rtl_processing (tree decl)
 {
-  const char *name = 0;
-  int reg_number;
   rtx x;
 
   /* Check that we are not being given an automatic variable.  */
@@ -1047,9 +1039,17 @@
 
       return;
     }
+}
 
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+/* Processing for make_decl_rtl that takes place after knowing the
+   assembler name for the DECL.  */
 
+static void
+post_name_make_decl_rtl_processing (tree decl, const char *name)
+{
+  int reg_number;
+  rtx x;
+
   if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL
       && DECL_REGISTER (decl))
     {
@@ -1160,6 +1160,48 @@
     mudflap_enqueue_decl (decl);
 }
 
+/* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL should
+   have static storage duration.  In other words, it should not be an
+   automatic variable, including PARM_DECLs.
+
+   There is, however, one exception: this function handles variables
+   explicitly placed in a particular register by the user.
+
+   This is never called for PARM_DECL nodes.  */
+
+void
+make_decl_rtl (tree decl)
+{
+  const char *name;
+  pre_name_make_decl_rtl_processing (decl);
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  post_name_make_decl_rtl_processing (decl, name);
+}
+
+/* A middle/back-end version of make_decl_rtl. This function requires
+   that the assembler name be specified as an argument. No lang-hooks!
+
+   Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL should
+   have static storage duration.  In other words, it should not be an
+   automatic variable, including PARM_DECLs.
+
+   There is, however, one exception: this function handles variables
+   explicitly placed in a particular register by the user.
+
+   This is never called for PARM_DECL nodes.  */
+
+void
+mbe_make_decl_rtl (tree decl, const char *name)
+{
+  pre_name_make_decl_rtl_processing (decl);
+  if (DECL_ASSEMBLER_NAME_SET_P (decl))
+    gcc_assert (strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
+                        name) == 0);
+  else
+    SET_DECL_ASSEMBLER_NAME (decl, get_identifier (ggc_strdup (name)));
+  post_name_make_decl_rtl_processing (decl, name);
+}
+
 /* Make the rtl for variable VAR be volatile.
    Use this only for static variables.  */
 
Index: passes.c
===================================================================
--- passes.c	(revision 120246)
+++ passes.c	(working copy)
@@ -138,7 +138,8 @@
   /* Can't defer this, because it needs to happen before any
      later function definitions are processed.  */
   if (DECL_ASSEMBLER_NAME_SET_P (decl) && DECL_REGISTER (decl))
-    make_decl_rtl (decl);
+    mbe_make_decl_rtl (decl,
+                       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
 
   /* Forward declarations for nested functions are not "external",
      but we need to treat them as if they were.  */
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 120246)
+++ lto/lto.c	(working copy)
@@ -2236,6 +2236,7 @@
   tree arg_types;
   tree type;
   tree name;
+  tree asm_name = NULL_TREE;
   bool external;
   VEC(tree,heap) *parms;
   unsigned n_parms;
@@ -2308,7 +2309,12 @@
 	case DW_AT_inline:
 	  inlined = attribute_value_as_int (&attr_data);
 	  break;
-	  
+
+        case DW_AT_MIPS_linkage_name:
+          /* Set the DECL_ASSEMBLER_NAME so we don't have to remangle
+             names in LTO.  */
+          asm_name = lto_get_identifier (&attr_data);
+          break;
 	}
       LTO_END_READ_ATTRS ();
     }
@@ -2386,6 +2392,10 @@
 	  || inlined == DW_INL_declared_not_inlined)
 	DECL_DECLARED_INLINE_P (result) = 1;
 
+      /* Set the DECL_ASSEMBLER_NAME for the function from the
+         information in the DIE.  */
+      SET_DECL_ASSEMBLER_NAME (result, asm_name ? asm_name : name);
+
       /* If the function has already been declared, merge the
 	 declarations.  */
       result = lto_symtab_merge_fn (result);
Index: lto/lto-lang.c
===================================================================
--- lto/lto-lang.c	(revision 120246)
+++ lto/lto-lang.c	(working copy)
@@ -105,6 +105,12 @@
   gcc_unreachable ();
 }
 
+static void
+lto_set_decl_assembler_name (tree decl ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
 static tree
 lto_pushdecl (tree t ATTRIBUTE_UNUSED)
 {
@@ -172,6 +178,8 @@
 #define LANG_HOOKS_UNSIGNED_TYPE lto_unsigned_type
 #define LANG_HOOKS_SIGNED_TYPE lto_signed_type
 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE lto_signed_or_unsigned_type
+#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lto_set_decl_assembler_name
 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
 #define LANG_HOOKS_GLOBAL_BINDINGS_P lto_global_bindings_p
 #undef LANG_HOOKS_INSERT_BLOCK



More information about the Gcc-patches mailing list