Commit 89ce1c8f by Jakub Jelinek Committed by Jakub Jelinek

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

	* 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
parent 11405c93
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> 2003-06-23 Andreas Schwab <schwab@suse.de>
PR debug/9905 PR debug/9905
......
...@@ -15496,15 +15496,14 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function) ...@@ -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); 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 (TARGET_64BIT)
{ {
if (!flag_pic || (*targetm.binds_local_p) (function)) if (!flag_pic || (*targetm.binds_local_p) (function))
output_asm_insn ("jmp\t%P0", xops); output_asm_insn ("jmp\t%P0", xops);
else else
{ {
tmp = XEXP (xops[0], 0); tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xops[0]), UNSPEC_GOTPCREL);
tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, tmp), UNSPEC_GOTPCREL);
tmp = gen_rtx_CONST (Pmode, tmp); tmp = gen_rtx_CONST (Pmode, tmp);
tmp = gen_rtx_MEM (QImode, tmp); tmp = gen_rtx_MEM (QImode, tmp);
xops[0] = tmp; xops[0] = tmp;
......
...@@ -6480,13 +6480,16 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function) ...@@ -6480,13 +6480,16 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
HOST_WIDE_INT vcall_offset; HOST_WIDE_INT vcall_offset;
tree function; tree function;
{ {
rtx op[9]; rtx op[10];
int nonlocal = 0;
/* Operand 0 is the target function. */ /* Operand 0 is the target function. */
op[0] = XEXP (DECL_RTL (function), 0); op[0] = XEXP (DECL_RTL (function), 0);
if (flag_pic && !SYMBOL_REF_LOCAL_P (op[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]); op[0] = gen_rtx_CONST (Pmode, op[0]);
} }
...@@ -6511,6 +6514,9 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function) ...@@ -6511,6 +6514,9 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
op[7] = NULL_RTX; op[7] = NULL_RTX;
op[8] = NULL_RTX; op[8] = NULL_RTX;
/* Operand 9 can be used for temporary register. */
op[9] = NULL_RTX;
/* Generate code. */ /* Generate code. */
if (TARGET_64BIT) if (TARGET_64BIT)
{ {
...@@ -6641,14 +6647,39 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function) ...@@ -6641,14 +6647,39 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Jump to target. */ /* Jump to target. */
op[8] = gen_label_rtx (); op[8] = gen_label_rtx ();
if (!flag_pic) if (!flag_pic)
output_asm_insn ("l\t%4,%8-%5(%4)", op); output_asm_insn ("l\t%4,%8-%5(%4)", op);
else else if (!nonlocal)
output_asm_insn ("a\t%4,%8-%5(%4)", op); 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_asm_insn ("br\t%4", op);
/* Output literal pool. */ /* Output literal pool. */
output_asm_insn (".align\t4", op); 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])); (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[8]));
if (!flag_pic) if (!flag_pic)
output_asm_insn (".long\t%0", op); output_asm_insn (".long\t%0", op);
......
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> Mon Jun 23 19:41:27 CEST 2003 Jan Hubicka <jh@suse.cz>
* decl.c (register_dtor_fn): Mark cleanup as used. * decl.c (register_dtor_fn): Mark cleanup as used.
......
...@@ -103,7 +103,7 @@ $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf ...@@ -103,7 +103,7 @@ $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf
$(srcdir)/cp/cfns.gperf > $(srcdir)/cp/cfns.h $(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 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 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) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_ ...@@ -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 \ cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
except.h except.h
cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_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/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/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) \ cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \
......
...@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)" ...@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
target_libs="target-libstdc++-v3 target-gperf" 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"
...@@ -351,6 +351,53 @@ thunk_adjust (tree ptr, bool this_adjusting, ...@@ -351,6 +351,53 @@ thunk_adjust (tree ptr, bool this_adjusting,
return ptr; 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 /* Emit the definition of a C++ multiple inheritance or covariant
return vtable thunk. If EMIT_P is nonzero, the thunk is emitted return vtable thunk. If EMIT_P is nonzero, the thunk is emitted
immediately. */ immediately. */
...@@ -358,7 +405,7 @@ thunk_adjust (tree ptr, bool this_adjusting, ...@@ -358,7 +405,7 @@ thunk_adjust (tree ptr, bool this_adjusting,
void void
use_thunk (tree thunk_fndecl, bool emit_p) use_thunk (tree thunk_fndecl, bool emit_p)
{ {
tree function; tree function, alias;
tree virtual_offset; tree virtual_offset;
HOST_WIDE_INT fixed_offset, virtual_value; HOST_WIDE_INT fixed_offset, virtual_value;
bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl); bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
...@@ -386,6 +433,12 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -386,6 +433,12 @@ use_thunk (tree thunk_fndecl, bool emit_p)
if (!emit_p) if (!emit_p)
return; return;
#ifdef ASM_OUTPUT_DEF
alias = make_alias_for_thunk (function);
#else
alias = function;
#endif
fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl); fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl); virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
...@@ -415,6 +468,21 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -415,6 +468,21 @@ use_thunk (tree thunk_fndecl, bool emit_p)
push_to_top_level (); 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 /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
create one. */ create one. */
DECL_INITIAL (thunk_fndecl) = make_node (BLOCK); DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
...@@ -422,7 +490,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -422,7 +490,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
if (this_adjusting if (this_adjusting
&& targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
virtual_value, function)) virtual_value, alias))
{ {
const char *fnname; const char *fnname;
current_function_decl = thunk_fndecl; current_function_decl = thunk_fndecl;
...@@ -434,7 +502,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -434,7 +502,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
assemble_start_function (thunk_fndecl, fnname); assemble_start_function (thunk_fndecl, fnname);
targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl, 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); assemble_end_function (thunk_fndecl, fnname);
current_function_decl = 0; current_function_decl = 0;
...@@ -486,7 +554,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -486,7 +554,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a)) for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
t = tree_cons (NULL_TREE, a, t); t = tree_cons (NULL_TREE, a, t);
t = nreverse (t); t = nreverse (t);
t = build_call (function, t); t = build_call (alias, t);
if (!this_adjusting) if (!this_adjusting)
t = thunk_adjust (t, /*this_adjusting=*/0, t = thunk_adjust (t, /*this_adjusting=*/0,
fixed_offset, virtual_offset); fixed_offset, virtual_offset);
...@@ -1054,3 +1122,5 @@ skip_artificial_parms_for (tree fn, tree list) ...@@ -1054,3 +1122,5 @@ skip_artificial_parms_for (tree fn, tree list)
list = TREE_CHAIN (list); list = TREE_CHAIN (list);
return list; return list;
} }
#include "gt-cp-method.h"
...@@ -2907,6 +2907,7 @@ extern int supports_one_only PARAMS ((void)); ...@@ -2907,6 +2907,7 @@ extern int supports_one_only PARAMS ((void));
extern void variable_section PARAMS ((tree, int)); extern void variable_section PARAMS ((tree, int));
enum tls_model decl_tls_model PARAMS ((tree)); enum tls_model decl_tls_model PARAMS ((tree));
enum symbol_visibility decl_visibility PARAMS ((tree)); enum symbol_visibility decl_visibility PARAMS ((tree));
extern void resolve_unique_section PARAMS ((tree, int, int));
/* In stmt.c */ /* In stmt.c */
extern void emit_nop PARAMS ((void)); extern void emit_nop PARAMS ((void));
......
...@@ -183,7 +183,6 @@ static void asm_output_aligned_bss ...@@ -183,7 +183,6 @@ static void asm_output_aligned_bss
static bool asm_emit_uninitialised PARAMS ((tree, const char*, static bool asm_emit_uninitialised PARAMS ((tree, const char*,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT)); unsigned HOST_WIDE_INT));
static void resolve_unique_section PARAMS ((tree, int, int));
static void mark_weak PARAMS ((tree)); static void mark_weak PARAMS ((tree));
enum in_section { no_section, in_text, in_data, in_named enum in_section { no_section, in_text, in_data, in_named
...@@ -460,7 +459,7 @@ named_section (decl, name, reloc) ...@@ -460,7 +459,7 @@ named_section (decl, name, reloc)
/* If required, set DECL_SECTION_NAME to a unique name. */ /* If required, set DECL_SECTION_NAME to a unique name. */
static void void
resolve_unique_section (decl, reloc, flag_function_or_data_sections) resolve_unique_section (decl, reloc, flag_function_or_data_sections)
tree decl; tree decl;
int reloc ATTRIBUTE_UNUSED; int reloc ATTRIBUTE_UNUSED;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment