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][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;
  


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