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]

[PATCH] Make calls in virtual thunks local if possible


Hi!

If ASM_OUTPUT_DEF is supported, this patch creates a static alias to methods
which need thunks and makes thunks call these static aliases instead of the
real method symbols. This is possible since thunks are always emitted
together with the methods they are calling.
If a method is emitted in a linkonce section, it will emit the thunk into
the same linkonce section as well, since local symbols in linkonce sections
cannot be safely accessed from other sections.
The patch revealed a bug in x86_output_mi_thunk, which for pic hidden x86_64
functions would emit
jmp .LTHUNK0(%rip)
instead of the desired
jmp .LTHUNK0
(there was a mem around the rtl which was not supposed to be there).

Tested on gcc-3_3-rhl-branch, will bootstrap/regtest this on the trunk
tonight. Ok to commit if it passes?

2003-06-23  Jakub Jelinek  <jakub@redhat.com>

	* config/i386/i386.c (x86_output_mi_thunk): Don't pass MEM to %P0,
	just SYMBOL_REF.

	* varasm.c (resolve_unique_section): Remove prototype.  No longer
	static.
	* tree.h (resolve_unique_section): New prototype.
cp/
	* method.c (thunk_labelno): New variable.
	(make_alias_for_thunk): New function.
	(use_thunk): Use it if defined ASM_OUTPUT_DEF.  Put the thunk
	into the same section as the function it is calling.
	Include gt-cp-method.h.
	* Make-lang.in (gt-cp-method.h): Depend on s-gtype.
	(cp/method.o): Depend on gt-cp-method.h.
	* config-lang.in (gtfiles): Add $(srcdir)/cp/method.c.

--- gcc/cp/method.c.jj	2003-06-21 05:11:42.000000000 -0400
+++ gcc/cp/method.c	2003-06-23 11:08:17.000000000 -0400
@@ -351,6 +351,52 @@ thunk_adjust (tree ptr, bool this_adjust
   return ptr;
 }
 
+static GTY (()) int thunk_labelno;
+
+/* Create a static alias to function.  */
+
+static tree
+make_alias_for_thunk (tree function)
+{
+  tree alias;
+  char buf[256];
+
+  ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
+  thunk_labelno++;
+  alias = build_decl (FUNCTION_DECL, get_identifier (buf),
+		      TREE_TYPE (function));
+  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
+  cxx_dup_lang_specific_decl (alias);
+  DECL_CONTEXT (alias) = NULL;
+  TREE_READONLY (alias) = TREE_READONLY (function);
+  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function);
+  TREE_PUBLIC (alias) = 0;
+  DECL_INTERFACE_KNOWN (alias) = 1;
+  DECL_NOT_REALLY_EXTERN (alias) = 1;
+  DECL_THIS_STATIC (alias) = 1;
+  DECL_SAVED_FUNCTION_DATA (alias) = NULL;
+  DECL_DESTRUCTOR_P (alias) = 0;
+  DECL_CONSTRUCTOR_P (alias) = 0;
+  DECL_CLONED_FUNCTION (alias) = NULL_TREE;
+  DECL_EXTERNAL (alias) = 0;
+  DECL_ARTIFICIAL (alias) = 1;
+  DECL_NO_STATIC_CHAIN (alias) = 1;
+  DECL_PENDING_INLINE_P (alias) = 0;
+  DECL_INLINE (alias) = 0;
+  DECL_DECLARED_INLINE_P (alias) = 0;
+  DECL_DEFERRED_FN (alias) = 0;
+  DECL_USE_TEMPLATE (alias) = 0;
+  DECL_TEMPLATE_INSTANTIATED (alias) = 0;
+  DECL_TEMPLATE_INFO (alias) = NULL;
+  TREE_ADDRESSABLE (alias) = 1;
+  TREE_USED (alias) = 1;
+  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
+  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
+  if (!flag_syntax_only)
+    assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
+  return alias;
+}
+
 /* Emit the definition of a C++ multiple inheritance or covariant
    return vtable thunk.  If EMIT_P is nonzero, the thunk is emitted
    immediately.  */
@@ -358,7 +404,7 @@ thunk_adjust (tree ptr, bool this_adjust
 void
 use_thunk (tree thunk_fndecl, bool emit_p)
 {
-  tree function;
+  tree function, alias;
   tree virtual_offset;
   HOST_WIDE_INT fixed_offset, virtual_value;
   bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
@@ -386,6 +432,12 @@ use_thunk (tree thunk_fndecl, bool emit_
   if (!emit_p)
     return;
 
+#ifdef ASM_OUTPUT_DEF
+  alias = make_alias_for_thunk (function);
+#else
+  alias = function;
+#endif
+
   fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
   virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
 
@@ -415,6 +467,21 @@ use_thunk (tree thunk_fndecl, bool emit_
 
   push_to_top_level ();
 
+#ifdef ASM_OUTPUT_DEF
+  if (targetm.have_named_sections)
+    {
+      resolve_unique_section (function, 0, flag_function_sections);
+
+      if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
+	{
+	  resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
+
+	  /* Output the thunk into the same section as function.  */
+	  DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
+	}
+    }
+#endif
+
   /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
      create one.  */
   DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
@@ -422,7 +489,7 @@ use_thunk (tree thunk_fndecl, bool emit_
   
   if (this_adjusting
       && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
-					      virtual_value, function))
+					      virtual_value, alias))
     {
       const char *fnname;
       current_function_decl = thunk_fndecl;
@@ -434,7 +501,7 @@ use_thunk (tree thunk_fndecl, bool emit_
       assemble_start_function (thunk_fndecl, fnname);
 
       targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
-				       fixed_offset, virtual_value, function);
+				       fixed_offset, virtual_value, alias);
 
       assemble_end_function (thunk_fndecl, fnname);
       current_function_decl = 0;
@@ -486,7 +553,7 @@ use_thunk (tree thunk_fndecl, bool emit_
       for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
 	t = tree_cons (NULL_TREE, a, t);
       t = nreverse (t);
-      t = build_call (function, t);
+      t = build_call (alias, t);
       if (!this_adjusting)
 	t = thunk_adjust (t, /*this_adjusting=*/0,
 			  fixed_offset, virtual_offset);
@@ -1054,3 +1121,5 @@ skip_artificial_parms_for (tree fn, tree
     list = TREE_CHAIN (list);
   return list;
 }
+
+#include "gt-cp-method.h"
--- gcc/cp/Make-lang.in.jj	2003-06-21 05:11:42.000000000 -0400
+++ gcc/cp/Make-lang.in	2003-06-21 05:12:59.000000000 -0400
@@ -103,7 +103,7 @@ $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.g
 		$(srcdir)/cp/cfns.gperf > $(srcdir)/cp/cfns.h
 
 gtype-cp.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h : s-gtype; @true
-gt-cp-pt.h gt-cp-repo.h gt-cp-parser.h : s-gtype; @true
+gt-cp-pt.h gt-cp-repo.h gt-cp-parser.h gt-cp-method.h : s-gtype; @true
 gt-cp-tree.h gt-cp-mangle.h gt-cp-name-lookup.h: s-gtype; @true
 
 #
@@ -253,7 +253,7 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) $
 cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
   except.h
 cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \
-  $(TM_P_H) $(TARGET_H)
+  $(TM_P_H) $(TARGET_H) gt-cp-method.h
 cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h
 cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) stack.h flags.h toplev.h $(RTL_H)
 cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \
--- gcc/cp/config-lang.in.jj	2003-06-21 05:11:42.000000000 -0400
+++ gcc/cp/config-lang.in	2003-06-21 05:12:59.000000000 -0400
@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(ex
 
 target_libs="target-libstdc++-v3 target-gperf"
 
-gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
+gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
--- gcc/varasm.c.jj	2003-06-21 05:11:42.000000000 -0400
+++ gcc/varasm.c	2003-06-21 05:12:59.000000000 -0400
@@ -183,7 +183,6 @@ static void asm_output_aligned_bss
 static bool asm_emit_uninitialised	PARAMS ((tree, const char*,
 						 unsigned HOST_WIDE_INT,
 						 unsigned HOST_WIDE_INT));
-static void resolve_unique_section	PARAMS ((tree, int, int));
 static void mark_weak                   PARAMS ((tree));
 
 enum in_section { no_section, in_text, in_data, in_named
@@ -460,7 +459,7 @@ named_section (decl, name, reloc)
 
 /* If required, set DECL_SECTION_NAME to a unique name.  */
 
-static void
+void
 resolve_unique_section (decl, reloc, flag_function_or_data_sections)
      tree decl;
      int reloc ATTRIBUTE_UNUSED;
--- gcc/config/i386/i386.c.jj	2003-06-21 05:09:27.000000000 -0400
+++ gcc/config/i386/i386.c	2003-06-23 11:09:26.000000000 -0400
@@ -15494,15 +15494,14 @@ x86_output_mi_thunk (file, thunk, delta,
       output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
     }
 
-  xops[0] = DECL_RTL (function);
+  xops[0] = XEXP (DECL_RTL (function), 0);
   if (TARGET_64BIT)
     {
       if (!flag_pic || (*targetm.binds_local_p) (function))
 	output_asm_insn ("jmp\t%P0", xops);
       else
 	{
-	  tmp = XEXP (xops[0], 0);
-	  tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, tmp), UNSPEC_GOTPCREL);
+	  tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xops[0]), UNSPEC_GOTPCREL);
 	  tmp = gen_rtx_CONST (Pmode, tmp);
 	  tmp = gen_rtx_MEM (QImode, tmp);
 	  xops[0] = tmp;
--- gcc/tree.h.jj	2003-06-21 05:11:41.000000000 -0400
+++ gcc/tree.h	2003-06-21 05:12:59.000000000 -0400
@@ -2907,6 +2907,7 @@ extern int supports_one_only		PARAMS ((v
 extern void variable_section		PARAMS ((tree, int));
 enum tls_model decl_tls_model		PARAMS ((tree));
 enum symbol_visibility decl_visibility	PARAMS ((tree));
+extern void resolve_unique_section	PARAMS ((tree, int, int));
 
 /* In stmt.c */
 extern void emit_nop			PARAMS ((void));

	Jakub


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