diff options
author | Jan Hubicka <jh@suse.cz> | 2009-11-29 11:32:08 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2009-11-29 10:32:08 +0000 |
commit | 6744a6abc335d55f98ba226f4ff169a55cf3fb94 (patch) | |
tree | 2260e6f71c9022e13476588b282bc487939fa1e4 /gcc/cp | |
parent | e55690913ecef32cb80d5f169a9aa50fd5ae4a98 (diff) | |
download | gcc-6744a6abc335d55f98ba226f4ff169a55cf3fb94.zip gcc-6744a6abc335d55f98ba226f4ff169a55cf3fb94.tar.gz gcc-6744a6abc335d55f98ba226f4ff169a55cf3fb94.tar.bz2 |
cgraph.c (same_body_alias_1): Break out of
* cgraph.c (same_body_alias_1): Break out of
(same_body_alias): ... here; remove comdat check; it is handled
in cp already.
(cgraph_add_thunk): New.
(dump_cgraph_node): Dump aliases and thunks.
* cgraph.h (cgraph_thunk_info): New structure.
(struct cgraph_node): Add thunk info.
(cgraph_add_thunk): New.
* cgraphunit.c (cgraph_emit_thunks): Remove.
(cgraph_finalize_compilation_unit): Do not call cgraph_emit_thunks.
(assemble_thunk): New function.
(cgraph_expand_function): Handle thunks.
(thunk_adjust): New.
(init_lowered_empty_function): New.
* optimize.c (maybe_clone_body): Emit thunks associated to alias.
* Make-lang.in (method.o): Add dependency on gimple.h.
* method.c: Include gimple.h
(make_alias_for_thunk): Use same body alias instead of assemble_alias.
(use_thunk): Drop codegen; use cgraph_add_thunk; gimplify
generic thunks.
* semantics.c (expand_or_defer_fn): Emit associated thunks.
* cp-objcp-common.h (LANG_HOOKS_CALLGRAPH_EMIT_ASSOCIATED_THUNKS): Remove.
* lto-cgraph.c (lto_output_node): Stream thunk info.
(input_node): Likewise.
* langhooks.h (lang_hooks_for_callgraph): Remove emit_associated_thunks.
* langhooks-def.h (LANG_HOOKS_CALLGRAPH_EMIT_ASSOCIATED_THUNKS): Remove.
(LANG_HOOKS_CALLGRAPH_INITIALIZER): Update.
* i386.c (x86_output_mi_thunk): Make output prettier.
From-SVN: r154736
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.h | 2 | ||||
-rw-r--r-- | gcc/cp/method.c | 164 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 1 |
6 files changed, 30 insertions, 154 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4f58453..ab252ea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2009-11-29 Jan Hubicka <jh@suse.cz> + + * optimize.c (maybe_clone_body): Emit thunks associated to alias. + * Make-lang.in (method.o): Add dependency on gimple.h. + * method.c: Include gimple.h + (make_alias_for_thunk): Use same body alias instead of assemble_alias. + (use_thunk): Drop codegen; use cgraph_add_thunk; gimplify + generic thunks. + * semantics.c (expand_or_defer_fn): Emit associated thunks. + 2009-11-28 Dodji Seketeli <dodji@redhat.com> PR c++/36408 diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 6e10296..ef44201 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -275,7 +275,7 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) toplev.h \ cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) $(EXPR_H) \ toplev.h except.h $(TARGET_H) cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \ - $(TM_P_H) $(TARGET_H) $(DIAGNOSTIC_H) gt-cp-method.h + $(TM_P_H) $(TARGET_H) $(DIAGNOSTIC_H) gt-cp-method.h $(GIMPLE_H) cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h $(FLAGS_H) toplev.h \ convert.h $(TARGET_H) cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index 8f0cdc3..1a97ad2 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -104,8 +104,6 @@ extern bool cp_function_decl_explicit_p (tree decl); #undef LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR #define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR cxx_callgraph_analyze_expr -#undef LANG_HOOKS_CALLGRAPH_EMIT_ASSOCIATED_THUNKS -#define LANG_HOOKS_CALLGRAPH_EMIT_ASSOCIATED_THUNKS emit_associated_thunks #undef LANG_HOOKS_MAKE_TYPE #define LANG_HOOKS_MAKE_TYPE cxx_make_type diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 47f9e42..cda7ed3 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "diagnostic.h" #include "cgraph.h" +#include "gimple.h" /* Various flags to control the mangling process. */ @@ -58,7 +59,6 @@ enum mangling_flags typedef enum mangling_flags mangling_flags; -static tree thunk_adjust (tree, bool, HOST_WIDE_INT, tree); static void do_build_assign_ref (tree); static void do_build_copy_constructor (tree); static tree synthesize_exception_spec (tree, tree (*) (tree, void *), void *); @@ -205,56 +205,6 @@ finish_thunk (tree thunk) SET_DECL_ASSEMBLER_NAME (thunk, name); } -/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable - offset indicated by VIRTUAL_OFFSET, if that is - non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and - zero for a result adjusting thunk. */ - -static tree -thunk_adjust (tree ptr, bool this_adjusting, - HOST_WIDE_INT fixed_offset, tree virtual_offset) -{ - if (this_adjusting) - /* Adjust the pointer by the constant. */ - ptr = fold_build2_loc (input_location, - POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, - size_int (fixed_offset)); - - /* If there's a virtual offset, look up that value in the vtable and - adjust the pointer again. */ - if (virtual_offset) - { - tree vtable; - - ptr = save_expr (ptr); - /* The vptr is always at offset zero in the object. */ - vtable = build1 (NOP_EXPR, - build_pointer_type (build_pointer_type - (vtable_entry_type)), - ptr); - /* Form the vtable address. */ - vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable); - /* Find the entry with the vcall offset. */ - vtable = fold_build2_loc (input_location, - POINTER_PLUS_EXPR, TREE_TYPE (vtable), vtable, - fold_convert (sizetype, virtual_offset)); - /* Get the offset itself. */ - vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable); - /* Adjust the `this' pointer. */ - ptr = fold_build2_loc (input_location, - POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, - fold_convert (sizetype, vtable)); - } - - if (!this_adjusting) - /* Adjust the pointer by the constant. */ - ptr = fold_build2_loc (input_location, - POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, - size_int (fixed_offset)); - - return ptr; -} - static GTY (()) int thunk_labelno; /* Create a static alias to function. */ @@ -303,7 +253,11 @@ make_alias_for_thunk (tree function) alias = make_alias_for (function, get_identifier (buf)); if (!flag_syntax_only) - assemble_alias (alias, DECL_ASSEMBLER_NAME (function)); + { + bool ok = cgraph_same_body_alias (alias, function); + DECL_ASSEMBLER_NAME (function); + gcc_assert (ok); + } return alias; } @@ -416,42 +370,15 @@ use_thunk (tree thunk_fndecl, bool emit_p) } a = nreverse (t); DECL_ARGUMENTS (thunk_fndecl) = a; - - if (this_adjusting - && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, - virtual_value, alias)) - { - const char *fnname; - tree fn_block; - - current_function_decl = thunk_fndecl; - DECL_RESULT (thunk_fndecl) - = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl), - RESULT_DECL, 0, integer_type_node); - fnname = IDENTIFIER_POINTER (DECL_NAME (thunk_fndecl)); - /* The back end expects DECL_INITIAL to contain a BLOCK, so we - create one. */ - fn_block = make_node (BLOCK); - BLOCK_VARS (fn_block) = a; - DECL_INITIAL (thunk_fndecl) = fn_block; - init_function_start (thunk_fndecl); - cfun->is_thunk = 1; - assemble_start_function (thunk_fndecl, fnname); - - targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl, - fixed_offset, virtual_value, alias); - - assemble_end_function (thunk_fndecl, fnname); - init_insn_lengths (); - free_after_compilation (cfun); - current_function_decl = 0; - set_cfun (NULL); - TREE_ASM_WRITTEN (thunk_fndecl) = 1; - } - else + TREE_ASM_WRITTEN (thunk_fndecl) = 1; + cgraph_add_thunk (thunk_fndecl, function, + this_adjusting, fixed_offset, virtual_value, + virtual_offset, alias); + + if (!this_adjusting + || !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, + virtual_value, alias)) { - int i; - tree *argarray = (tree *) alloca (list_length (a) * sizeof (tree)); /* If this is a covariant thunk, or we don't have the necessary code for efficient thunks, generate a thunk function that just makes a call to the real function. Unfortunately, this @@ -460,69 +387,6 @@ use_thunk (tree thunk_fndecl, bool emit_p) if (varargs_function_p (function)) error ("generic thunk code fails for method %q#D which uses %<...%>", function); - - DECL_RESULT (thunk_fndecl) = NULL_TREE; - - start_preparsed_function (thunk_fndecl, NULL_TREE, SF_PRE_PARSED); - /* We don't bother with a body block for thunks. */ - - /* There's no need to check accessibility inside the thunk body. */ - push_deferring_access_checks (dk_no_check); - - t = a; - if (this_adjusting) - t = thunk_adjust (t, /*this_adjusting=*/1, - fixed_offset, virtual_offset); - - /* Build up the call to the real function. */ - argarray[0] = t; - for (i = 1, a = TREE_CHAIN (a); a; a = TREE_CHAIN (a), i++) - argarray[i] = a; - t = build_call_a (alias, i, argarray); - CALL_FROM_THUNK_P (t) = 1; - CALL_CANNOT_INLINE_P (t) = 1; - - if (VOID_TYPE_P (TREE_TYPE (t))) - finish_expr_stmt (t); - else - { - if (!this_adjusting) - { - tree cond = NULL_TREE; - - if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE) - { - /* If the return type is a pointer, we need to - protect against NULL. We know there will be an - adjustment, because that's why we're emitting a - thunk. */ - t = save_expr (t); - cond = cp_convert (boolean_type_node, t); - } - - t = thunk_adjust (t, /*this_adjusting=*/0, - fixed_offset, virtual_offset); - if (cond) - t = build3 (COND_EXPR, TREE_TYPE (t), cond, t, - cp_convert (TREE_TYPE (t), integer_zero_node)); - } - if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t))) - t = build_cplus_new (TREE_TYPE (t), t); - finish_return_stmt (t); - } - - /* Since we want to emit the thunk, we explicitly mark its name as - referenced. */ - mark_decl_referenced (thunk_fndecl); - - /* But we don't want debugging information about it. */ - DECL_IGNORED_P (thunk_fndecl) = 1; - - /* Re-enable access control. */ - pop_deferring_access_checks (); - - thunk_fndecl = finish_function (0); - cgraph_add_new_function (thunk_fndecl, false); } pop_from_top_level (); diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index c691f0b..838a730 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -250,7 +250,10 @@ maybe_clone_body (tree fn) && DECL_INTERFACE_KNOWN (fns[0]) && !DECL_ONE_ONLY (fns[0]) && cgraph_same_body_alias (clone, fns[0])) - alias = true; + { + alias = true; + emit_associated_thunks (clone); + } /* Build the delete destructor by calling complete destructor and delete function. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 5253df8..0a1a547 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3445,6 +3445,7 @@ expand_or_defer_fn (tree fn) /* Expand or defer, at the whim of the compilation unit manager. */ cgraph_finalize_function (fn, function_depth > 1); + emit_associated_thunks (fn); function_depth--; } |