i386.c (x86_output_mi_thunk): Don't pass MEM to %P0, just SYMBOL_REF.
authorJakub Jelinek <jakub@redhat.com>
Mon, 23 Jun 2003 20:52:14 +0000 (22:52 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 23 Jun 2003 20:52:14 +0000 (22:52 +0200)
* config/i386/i386.c (x86_output_mi_thunk): Don't pass MEM to %P0,
just SYMBOL_REF.
* config/s390/s390.c (s390_output_mi_thunk): Avoid .plt in -m31
mode, as it requires pic register loaded.

* 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.

From-SVN: r68389

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/s390/s390.c
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/config-lang.in
gcc/cp/method.c
gcc/tree.h
gcc/varasm.c

index 727e1f5657b0a890f326c6f8ec64db1ff3ea3f89..bb5a5ec1f60350246c906019b4262cb6ab84fdf9 100644 (file)
@@ -1,3 +1,14 @@
+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.
+       * config/s390/s390.c (s390_output_mi_thunk): Avoid .plt in -m31
+       mode, as it requires pic register loaded.
+
+       * varasm.c (resolve_unique_section): Remove prototype.  No longer
+       static.
+       * tree.h (resolve_unique_section): New prototype.
+
 2003-06-23  Andreas Schwab  <schwab@suse.de>
 
        PR debug/9905
index 479c4c91435966957a42452479ee24808b146d10..f08e80cd949b20fe15eabcc906b0c51b857cf80e 100644 (file)
@@ -15496,15 +15496,14 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
       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;
index 9ca394f8dd6cec4eb04ed21fef8e5a2442bcd2c2..4f0dd02542c6111af65808ac588c75aed66ffca0 100644 (file)
@@ -6480,13 +6480,16 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
      HOST_WIDE_INT vcall_offset;
      tree function;
 {
-  rtx op[9];
+  rtx op[10];
+  int nonlocal = 0;
 
   /* Operand 0 is the target function.  */
   op[0] = XEXP (DECL_RTL (function), 0);
   if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
     {
-      op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]), 113);
+      nonlocal = 1;
+      op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
+                             TARGET_64BIT ? 113 : flag_pic == 2 ? 112 : 110);
       op[0] = gen_rtx_CONST (Pmode, op[0]);
     }
 
@@ -6511,6 +6514,9 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
   op[7] = NULL_RTX;
   op[8] = NULL_RTX;
 
+  /* Operand 9 can be used for temporary register.  */
+  op[9] = NULL_RTX;
+
   /* Generate code.  */
   if (TARGET_64BIT)
     {
@@ -6641,14 +6647,39 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
 
       /* Jump to target.  */
       op[8] = gen_label_rtx ();
+
       if (!flag_pic)
        output_asm_insn ("l\t%4,%8-%5(%4)", op);
-      else
+      else if (!nonlocal)
        output_asm_insn ("a\t%4,%8-%5(%4)", op);
+      /* We cannot call through .plt, since .plt requires %r12 loaded.  */
+      else if (flag_pic == 1)
+       {
+         output_asm_insn ("a\t%4,%8-%5(%4)", op);
+         output_asm_insn ("l\t%4,%0(%4)", op);
+       }
+      else if (flag_pic == 2)
+       {
+         op[9] = gen_rtx_REG (Pmode, 0);
+         output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
+         output_asm_insn ("a\t%4,%8-%5(%4)", op);
+         output_asm_insn ("ar\t%4,%9", op);
+         output_asm_insn ("l\t%4,0(%4)", op);
+       }
+
       output_asm_insn ("br\t%4", op);
 
       /* Output literal pool.  */
       output_asm_insn (".align\t4", op);
+
+      if (nonlocal && flag_pic == 2)
+       output_asm_insn (".long\t%0", op);
+      if (nonlocal)
+       {
+         op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+         SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
+       }
+
       (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[8]));
       if (!flag_pic)
        output_asm_insn (".long\t%0", op);
index 641b4a298633870636568832869cfea806491929..ee9027446b8bde85f170c768ba0e1c618935c37c 100644 (file)
@@ -1,3 +1,14 @@
+2003-06-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * 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.
+
 Mon Jun 23 19:41:27 CEST 2003  Jan Hubicka  <jh@suse.cz>
 
        * decl.c (register_dtor_fn): Mark cleanup as used.
index ddada02bd6b8016d039cb26eb1cc2a68a359b8ba..e340987c08f3f0b9d0eae1b87ce24f21495ea4f3 100644 (file)
@@ -103,7 +103,7 @@ $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf
                $(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
 
 #\f
@@ -253,7 +253,7 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_
 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) \
index 2927606c12cc78f5258d38a1d8ab56e733c92eba..8ba5506e8fb1bec8e79f34065ea0cc1b3035dd80 100644 (file)
@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
 
 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"
index 2a08f70305b755a3d82082eef925c3d03e424f6f..9e00fff70c0c65fdc53f502ce30ee6ae5a45ce9a 100644 (file)
@@ -351,6 +351,53 @@ thunk_adjust (tree ptr, bool this_adjusting,
   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;
+  DECL_INITIAL (alias) = error_mark_node;
+  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 +405,7 @@ thunk_adjust (tree ptr, bool this_adjusting,
 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 +433,12 @@ use_thunk (tree thunk_fndecl, bool emit_p)
   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 +468,21 @@ use_thunk (tree thunk_fndecl, bool emit_p)
 
   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 +490,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
   
   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 +502,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
       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 +554,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
       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 +1122,5 @@ skip_artificial_parms_for (tree fn, tree list)
     list = TREE_CHAIN (list);
   return list;
 }
+
+#include "gt-cp-method.h"
index 26c79a8489b66379a5c6bc6303552023d7259762..93065c5f2fe714a5b943ca04a7d3c2276094107c 100644 (file)
@@ -2907,6 +2907,7 @@ extern int supports_one_only              PARAMS ((void));
 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));
index a76d23ae1cb5f69dd6b6bbf22b7ae4c2a3b02921..091bbb312099c7b203dc49b7257420792ee478ea 100644 (file)
@@ -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));
 \f
 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;