This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][RFC] Emit thunks from the frontends
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 2 Dec 2008 14:22:22 +0100 (CET)
- Subject: [PATCH][RFC] Emit thunks from the frontends
This builds up on the gimplification unit-at-a-time patch and makes sure
to emit thunks when the FE is still in control (during
cgraph_finalize_function).
There is two adjustments necessary in the C++ FE, one is to not emit
thunks for functions we are not going to emit (like extern templates),
one is to make the aliases verification code in varasm.c ignore the
"broken" aliases the C++ FE creates.
A more suitable solution would be to always generate tree thunks and
let the cgraph deal with figuring out which thunks/functions are needed.
But transitioning away from asm thunks isn't really what this is about
(though it is probably needed for LTO anyway).
Bootstrapped / tested on x86_64-unknown-linux-gnu with the
gimplification unit-at-a-time patch applied.
Comments?
Thanks,
Richard.
2008-12-02 Richard Guenther <rguenther@suse.de>
* cgraph.c (cgraph_add_new_function): Remove gimplification.
* cgraphunit.c (cgraph_finalize_function): Emit associated
thunks from here.
(cgraph_expand_function): Not from here.
* varasm.c (finish_aliases_1): Ignore errorneous aliases used
by thunks.
cp/
* method.c (use_thunk): Use cgraph_finalize_function to hand
off thunks to the cgraph.
* semantics.c (emit_associated_thunks): Do not emit thunks
for really extern functions.
Index: trunk/gcc/cgraph.c
===================================================================
*** trunk.orig/gcc/cgraph.c 2008-12-01 17:50:56.000000000 +0100
--- trunk/gcc/cgraph.c 2008-12-01 17:51:03.000000000 +0100
*************** cgraph_add_new_function (tree fndecl, bo
*** 1494,1502 ****
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
current_function_decl = fndecl;
gimple_register_cfg_hooks ();
- /* C++ Thunks are emitted late via this function, gimplify them. */
- if (!gimple_body (fndecl))
- gimplify_function_tree (fndecl);
tree_lowering_passes (fndecl);
bitmap_obstack_initialize (NULL);
if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
--- 1494,1499 ----
Index: trunk/gcc/cgraphunit.c
===================================================================
*** trunk.orig/gcc/cgraphunit.c 2008-12-01 17:50:56.000000000 +0100
--- trunk/gcc/cgraphunit.c 2008-12-02 13:47:27.000000000 +0100
*************** cgraph_finalize_function (tree decl, boo
*** 529,534 ****
--- 529,537 ----
if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
cgraph_mark_reachable_node (node);
+ if (lang_hooks.callgraph.emit_associated_thunks)
+ lang_hooks.callgraph.emit_associated_thunks (decl);
+
/* If we've not yet emitted decl, tell the debug info about it. */
if (!TREE_ASM_WRITTEN (decl))
(*debug_hooks->deferred_inline_function) (decl);
*************** cgraph_expand_function (struct cgraph_no
*** 1058,1065 ****
gcc_assert (node->lowered);
/* Generate RTL for the body of DECL. */
- if (lang_hooks.callgraph.emit_associated_thunks)
- lang_hooks.callgraph.emit_associated_thunks (decl);
tree_rest_of_compilation (decl);
/* Make sure that BE didn't give up on compiling. */
--- 1061,1066 ----
Index: trunk/gcc/cp/method.c
===================================================================
*** trunk.orig/gcc/cp/method.c 2008-12-01 17:50:56.000000000 +0100
--- trunk/gcc/cp/method.c 2008-12-01 17:51:03.000000000 +0100
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 522,528 ****
pop_deferring_access_checks ();
thunk_fndecl = finish_function (0);
! cgraph_add_new_function (thunk_fndecl, false);
}
pop_from_top_level ();
--- 522,528 ----
pop_deferring_access_checks ();
thunk_fndecl = finish_function (0);
! cgraph_finalize_function (thunk_fndecl, false);
}
pop_from_top_level ();
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c 2008-12-01 17:50:56.000000000 +0100
--- trunk/gcc/varasm.c 2008-12-01 17:51:03.000000000 +0100
*************** finish_aliases_1 (void)
*** 5346,5351 ****
--- 5346,5356 ----
p->decl, IDENTIFIER_POINTER (p->target));
}
else if (DECL_EXTERNAL (target_decl)
+ /* We use local aliases for C++ thunks to force the tailcall
+ to bind locally. Of course this is a hack - to keep it
+ working do the following (which is not strictly correct). */
+ && (! TREE_CODE (target_decl) == FUNCTION_DECL
+ || ! TREE_STATIC (target_decl))
&& ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
error ("%q+D aliased to external symbol %qs",
p->decl, IDENTIFIER_POINTER (p->target));
Index: trunk/gcc/cp/semantics.c
===================================================================
*** trunk.orig/gcc/cp/semantics.c 2008-12-02 12:11:50.000000000 +0100
--- trunk/gcc/cp/semantics.c 2008-12-02 12:12:01.000000000 +0100
*************** emit_associated_thunks (tree fn)
*** 3133,3139 ****
is so that you can know statically the entire set of thunks that
will ever be needed for a given virtual function, thereby
enabling you to output all the thunks with the function itself. */
! if (DECL_VIRTUAL_P (fn))
{
tree thunk;
--- 3133,3141 ----
is so that you can know statically the entire set of thunks that
will ever be needed for a given virtual function, thereby
enabling you to output all the thunks with the function itself. */
! if (DECL_VIRTUAL_P (fn)
! /* Do not emit thunks for extern template instantiations. */
! && ! DECL_REALLY_EXTERN (fn))
{
tree thunk;