aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2009-11-29 11:32:08 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2009-11-29 10:32:08 +0000
commit6744a6abc335d55f98ba226f4ff169a55cf3fb94 (patch)
tree2260e6f71c9022e13476588b282bc487939fa1e4 /gcc/cp
parente55690913ecef32cb80d5f169a9aa50fd5ae4a98 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/cp-objcp-common.h2
-rw-r--r--gcc/cp/method.c164
-rw-r--r--gcc/cp/optimize.c5
-rw-r--r--gcc/cp/semantics.c1
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--;
}