This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

IMA: backward-compatible behavior from lhd_set_decl_assembler_name


One of the biggest stumbling blocks to re-enabling IMA has been the C
front end's special set_decl_assembler_name hook.  It exists because
the generic hook isn't aware of the special significance of having
DECL_CONTEXT point to a TRANSLATION_UNIT_DECL.  The generic hook's
behavior is formally correct when DECL_CONTEXT points to a T_U_D, but
is not backward compatible for file-scope declarations with internal
linkage.  Theoretically, nothing should care what the object-file
symbol name of such a declaration is; in practice, people have scripts
that munge the .s file, or the nm output, or whatever, that break.
Therefore the C front end overrides that with backward-compatible
behavior when there's just one input file in play.

The problem with all this is that the C front end's override hook only
works properly if *every* declaration with internal linkage has its
DECL_CONTEXT set at the point when the hook is called.  I've spent the
past two weeks trying to make that be true, and I got maybe 96% there,
but it just doesn't look feasible to do for the remaining 4% (which
are mainly synthetic declarations created by language-independent code
that doesn't have the ability to hook into the C front end's scoping
structures - nor should it have to).  So instead, this patch
rearranges the generic hook to give backward-compatible behavior
without help from the C front end.

The new behavior is: Declarations with internal linkage at file scope in
the first input file get DECL_ASSEMBLER_NAME set equal to DECL_NAME.
This is what the aforementioned scripts expect.  Declarations with
internal linkage at file scope in the second and successive input files
get DECL_NAME + "." + a number; the number chosen is the DECL_UID of the
containing TRANSLATION_UNIT_DECL.  This number will always be in the
range 1 ... num_in_fnames-1; make_node and so on are adjusted such that
DECL_UIDs 0 through num_in_fnames are reserved for TRANSLATION_UNIT_DECLs.

Declarations with internal linkage at block scope also get a numeric
suffix, which is what we've always done with them, but I changed it from
a sequence number to the declaration's own DECL_UID, which allowed me to
remove PCH's grubby little fingers from langhooks.c.  (Technically we
could use the declaration's own DECL_UID for the file-scope declarations
in the second and successive input files as well, but using the T_U_D's
number is a useful sanity check that the language hasn't messed up and
created two declarations with the same name -- it's already constrained
not to do so in the first input file, and we want consistency.)

Internal linkage declarations with null DECL_CONTEXT also get no numeric
suffix.  For C, this should only happen for synthetic declarations
created by language-independent code (e.g. cgraph_build_static_cdtor).
I believe this to be harmless wrt IMA - these things tend to be created
just once in the entire object file, anyway.

The only wart is that reserving the first few DECL_UIDs for
TRANSLATION_UNIT_DECLs places a new constraint on front ends: they must
not create any DECL nodes prior to calling build_common_tree_nodes.  The
only front end that did that was C++ and it didn't have to; I just moved
the call to build_common_tree_nodes a few lines up in cxx_init.  The
*proper* fix here would be to call build_common_tree_nodes from
language-independent code, just before lang_hooks.init, but that would
require me to untangle flag_signed_char which is too tangential.

Bootstrapped i686-linux (all languages but Ada); committed.

zw

        * langhooks.c: Don't include gt-langhooks.h.
        (var_labelno): Delete.
        (lhd_set_decl_assembler_name): Do not append a distinguishing
        number to file-scope internal-linkage declarations for the first
        input file, even if they have DECL_CONTEXT set.  Use DECL_UID of
        the declaration itself (if at block scope), or its containing 
        TRANSLATION_UNIT_DECL (if at file scope) for the distinguishing
        number.

        * opts.c (cur_in_fname): New global.
        * opts.h: Declare it.
        * tree.c: Include opts.h.
        (make_node_stat): If creating a TRANSLATION_UNIT_DECL, give it
        DECL_UID equal to cur_in_fname.
        (copy_node_stat): Do not change DECL_UID when copying a
        TRANSLATION_UNIT_DECL.
        (build_common_tree_nodes): Adjust next_decl_uid to reserve the
        range 0 .. num_in_fnames-1 for TRANSLATION_UNIT_DECLs.

        * c-decl.c (c_static_assembler_name): Delete.
        * c-tree.h (c_static_assembler_name): Delete prototype.
        * c-lang.c, objc/objc-lang.c: Don't override
        LANG_HOOKS_SET_DECL_ASSEMBLER_NAME.

        * Makefile.in (tree.o): Update dependencies.
        (GTFILES): Remove langhooks.c.

cp:
        * decl.c (cxx_init_decl_processing): Call
        build_common_tree_nodes before creating the global NAMESPACE_DECL.

===================================================================
Index: Makefile.in
--- Makefile.in	4 Jul 2004 17:18:59 -0000	1.1317
+++ Makefile.in	5 Jul 2004 17:04:17 -0000
@@ -1569,7 +1569,7 @@ langhooks.o : langhooks.c $(CONFIG_H) $(
    $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) gt-langhooks.h diagnostic.h
 tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(FLAGS_H) function.h \
    toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
-   real.h gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H)
+   real.h gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) opts.h
 tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(C_TREE_H) $(FLAGS_H) langhooks.h toplev.h output.h c-pragma.h $(RTL_H) \
    $(GGC_H) $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) tree-iterator.h
@@ -2337,7 +2337,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/co
   $(srcdir)/fold-const.c $(srcdir)/function.c \
   $(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
   $(srcdir)/profile.c $(srcdir)/ra-build.c $(srcdir)/regclass.c \
-  $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/langhooks.c \
+  $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c \
   $(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
   $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
   $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
===================================================================
Index: c-decl.c
--- c-decl.c	3 Jul 2004 02:35:05 -0000	1.525
+++ c-decl.c	5 Jul 2004 17:04:17 -0000
@@ -6576,22 +6576,6 @@ make_pointer_declarator (tree type_quals
   return build1 (INDIRECT_REF, quals, itarget);
 }
 
-/* A wrapper around lhd_set_decl_assembler_name that gives static
-   variables their C names if they are at file scope and only one
-   translation unit is being compiled, for backwards compatibility
-   with certain bizarre assembler hacks (like crtstuff.c).  */
-
-void
-c_static_assembler_name (tree decl)
-{
-  if (num_in_fnames == 1
-      && !TREE_PUBLIC (decl) && DECL_CONTEXT (decl)
-      && TREE_CODE (DECL_CONTEXT (decl)) == TRANSLATION_UNIT_DECL)
-    SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
-  else
-    lhd_set_decl_assembler_name (decl);
-}
-
 /* Perform final processing on file-scope data.  */
 static void
 c_write_global_declarations_1 (tree globals)
===================================================================
Index: c-lang.c
--- c-lang.c	1 Jul 2004 08:52:25 -0000	1.128
+++ c-lang.c	5 Jul 2004 17:04:17 -0000
@@ -76,8 +76,6 @@ enum c_language_kind c_language = clk_c;
 #define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
 #undef LANG_HOOKS_STATICP
 #define LANG_HOOKS_STATICP c_staticp
-#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
-#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME c_static_assembler_name
 #undef LANG_HOOKS_NO_BODY_BLOCKS
 #define LANG_HOOKS_NO_BODY_BLOCKS true
 #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
===================================================================
Index: c-tree.h
--- c-tree.h	5 Jul 2004 09:35:23 -0000	1.160
+++ c-tree.h	5 Jul 2004 17:04:17 -0000
@@ -189,7 +189,6 @@ extern tree start_struct (enum tree_code
 extern void store_parm_decls (void);
 extern tree xref_tag (enum tree_code, tree);
 extern int c_expand_decl (tree);
-extern void c_static_assembler_name (tree);
 extern tree make_pointer_declarator (tree, tree);
 
 /* in c-objc-common.c */
===================================================================
Index: langhooks.c
--- langhooks.c	24 Jun 2004 22:45:57 -0000	1.65
+++ langhooks.c	5 Jul 2004 17:04:17 -0000
@@ -157,11 +157,6 @@ lhd_warn_unused_global_decl (tree decl)
   return true;
 }
 
-/* Number for making the label on the next
-   static variable internal to a function.  */
-
-static GTY(()) int var_labelno;
-
 /* Set the DECL_ASSEMBLER_NAME for DECL.  */
 void
 lhd_set_decl_assembler_name (tree decl)
@@ -184,18 +179,33 @@ lhd_set_decl_assembler_name (tree decl)
 
          Can't use just the variable's own name for a variable whose
 	 scope is less than the whole compilation.  Concatenate a
-	 distinguishing number.  */
-      if (!TREE_PUBLIC (decl) && DECL_CONTEXT (decl))
+	 distinguishing number.  If the decl is at block scope, the
+	 number assigned is the DECL_UID; if the decl is at file
+	 scope, the number is the DECL_UID of the surrounding
+	 TRANSLATION_UNIT_DECL, except for the T_U_D with UID 0.
+	 Those (the file-scope internal-linkage declarations from the
+	 first input file) get no suffix, which is consistent with
+	 what has historically been done for file-scope declarations
+	 with internal linkage.  */
+      if (TREE_PUBLIC (decl)
+	  || DECL_CONTEXT (decl) == NULL_TREE
+	  || (TREE_CODE (DECL_CONTEXT (decl)) == TRANSLATION_UNIT_DECL
+	      && DECL_UID (DECL_CONTEXT (decl)) == 0))
+	SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+      else
 	{
 	  const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
 	  char *label;
-	  
-	  ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
-	  var_labelno++;
+	  unsigned int uid;
+
+	  if (TREE_CODE (DECL_CONTEXT (decl)) == TRANSLATION_UNIT_DECL)
+	    uid = DECL_UID (DECL_CONTEXT (decl));
+	  else
+	    uid = DECL_UID (decl);
+
+	  ASM_FORMAT_PRIVATE_NAME (label, name, uid);
 	  SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
 	}
-      else
-	SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
     }
   else
     /* Nobody should ever be asking for the DECL_ASSEMBLER_NAME of
@@ -581,5 +591,3 @@ lhd_make_node (enum tree_code code)
 {
   return make_node (code);
 }
-
-#include "gt-langhooks.h"
===================================================================
Index: opts.c
--- opts.c	29 Jun 2004 01:53:02 -0000	1.71
+++ opts.c	5 Jul 2004 17:04:17 -0000
@@ -92,6 +92,7 @@ static bool flag_peel_loops_set, flag_br
 /* Input file names.  */
 const char **in_fnames;
 unsigned num_in_fnames;
+unsigned cur_in_fname;
 
 static size_t find_opt (const char *, int);
 static int common_handle_option (size_t scode, const char *arg, int value);
===================================================================
Index: opts.h
--- opts.h	14 Jun 2004 14:17:56 -0000	1.14
+++ opts.h	5 Jul 2004 17:04:17 -0000
@@ -57,4 +57,8 @@ extern const char **in_fnames;
 
 extern unsigned num_in_fnames;
 
+/* Current input filename index.  */
+
+extern unsigned cur_in_fname;
+
 #endif
===================================================================
Index: tree.c
--- tree.c	5 Jul 2004 09:35:26 -0000	1.387
+++ tree.c	5 Jul 2004 17:04:17 -0000
@@ -48,6 +48,7 @@ Software Foundation, 59 Temple Place - S
 #include "tree-iterator.h"
 #include "basic-block.h"
 #include "tree-flow.h"
+#include "opts.h"
 
 /* obstack.[ch] explicitly declined to prototype this.  */
 extern int _obstack_allocated_p (struct obstack *h, void *obj);
@@ -309,7 +310,10 @@ make_node_stat (enum tree_code code MEM_
       DECL_USER_ALIGN (t) = 0;
       DECL_IN_SYSTEM_HEADER (t) = in_system_header;
       DECL_SOURCE_LOCATION (t) = input_location;
-      DECL_UID (t) = next_decl_uid++;
+      if (code == TRANSLATION_UNIT_DECL)
+	DECL_UID (t) = cur_in_fname;
+      else
+	DECL_UID (t) = next_decl_uid++;
 
       /* We have not yet computed the alias set for this declaration.  */
       DECL_POINTER_ALIAS_SET (t) = -1;
@@ -382,7 +386,7 @@ copy_node_stat (tree node MEM_STAT_DECL)
   TREE_VISITED (t) = 0;
   t->common.ann = 0;
 
-  if (TREE_CODE_CLASS (code) == 'd')
+  if (TREE_CODE_CLASS (code) == 'd' && code != TRANSLATION_UNIT_DECL)
     DECL_UID (t) = next_decl_uid++;
   else if (TREE_CODE_CLASS (code) == 't')
     {
@@ -5310,6 +5314,14 @@ make_or_reuse_type (unsigned size, int u
 void
 build_common_tree_nodes (int signed_char)
 {
+  /* This function is called after command line parsing is complete,
+     but before any DECL nodes should have been created.  Therefore,
+     now is the appropriate time to adjust next_decl_uid so that the
+     range 0 .. num_in_fnames-1 is reserved for TRANSLATION_UNIT_DECLs.  */
+  if (next_decl_uid)
+    abort ();
+  next_decl_uid = num_in_fnames;
+
   error_mark_node = make_node (ERROR_MARK);
   TREE_TYPE (error_mark_node) = error_mark_node;
 
===================================================================
Index: cp/decl.c
--- cp/decl.c	2 Jul 2004 21:59:42 -0000	1.1233
+++ cp/decl.c	5 Jul 2004 17:04:18 -0000
@@ -2887,6 +2887,8 @@ cxx_init_decl_processing (void)
   tree void_ftype;
   tree void_ftype_ptr;
 
+  build_common_tree_nodes (flag_signed_char);
+
   /* Create all the identifiers we need.  */
   initialize_predefined_identifiers ();
 
@@ -2926,8 +2928,6 @@ cxx_init_decl_processing (void)
   /* Initially, C.  */
   current_lang_name = lang_name_c;
 
-  build_common_tree_nodes (flag_signed_char);
-
   error_mark_list = build_tree_list (error_mark_node, error_mark_node);
   TREE_TYPE (error_mark_list) = error_mark_node;
 
===================================================================
Index: objc/objc-lang.c
--- objc/objc-lang.c	1 Jul 2004 08:52:27 -0000	1.46
+++ objc/objc-lang.c	5 Jul 2004 17:04:18 -0000
@@ -73,8 +73,6 @@ enum c_language_kind c_language = clk_ob
 #define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
 #undef LANG_HOOKS_STATICP
 #define LANG_HOOKS_STATICP c_staticp
-#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
-#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME c_static_assembler_name
 #undef LANG_HOOKS_NO_BODY_BLOCKS
 #define LANG_HOOKS_NO_BODY_BLOCKS true
 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]