Commit 44662f68 by Eric Botcazou Committed by Eric Botcazou

calls.c (expand_call): Try to do a tail call for thunks at -O0 too.

	* calls.c (expand_call): Try to do a tail call for thunks at -O0 too.
	* cgraph.h (struct cgraph_thunk_info): Add indirect_offset.
	(cgraph_node::create_thunk): Add indirect_offset parameter.
	(thunk_adjust): Likewise.
	* cgraph.c (cgraph_node::create_thunk): Add indirect_offset parameter
	and initialize the corresponding field with it.
	(cgraph_node::dump): Dump indirect_offset field.
	* cgraphclones.c (duplicate_thunk_for_node): Deal with indirect_offset.
	* cgraphunit.c (cgraph_node::analyze): Be prepared for external thunks.
	(thunk_adjust): Add indirect_offset parameter and deal with it.
	(cgraph_node::expand_thunk): Deal with the indirect_offset field and
	pass it to thunk_adjust.  Do not call the target hook if it's non-zero
	or if the thunk is external or local.  Fix formatting.  Do not chain
	the RESULT_DECL to BLOCK_VARS.  Pass the static chain to the target,
	if any, in the GIMPLE representation.
	* ipa-icf.c (sem_function::equals_wpa): Deal with indirect_offset.
	* lto-cgraph.c (lto_output_node): Write indirect_offset field.
	(input_node): Read indirect_offset field.
	* tree-inline.c (expand_call_inline): Pass indirect_offset field in the
	call to thunk_adjust.
	* tree-nested.c (struct nesting_info): Add thunk_p field.
	(create_nesting_tree): Set it.
	(convert_all_function_calls): Copy static chain from targets to thunks.
	(finalize_nesting_tree_1): Return early for thunks.
	(unnest_nesting_tree_1): Do not finalize thunks.
	(gimplify_all_functions): Do not gimplify thunks.
cp/
	* method.c (use_thunk): Adjust call to cgraph_node::create_thunk.
ada/
	* gcc-interface/decl.c (is_cplusplus_method): Do not require C++
	convention on Interfaces.
	* gcc-interface/trans.c (Subprogram_Body_to_gnu): Try to create a
	bona-fide thunk and hand it over to the middle-end.
	(get_controlling_type): New function.
	(use_alias_for_thunk_p): Likewise.
	(thunk_labelno): New static variable.
	(make_covariant_thunk): New function.
	(maybe_make_gnu_thunk): Likewise.
	* gcc-interface/utils.c (finish_subprog_decl): Set DECL_CONTEXT of the
	result DECL here instead of...
	(end_subprog_body): ...here.

Co-Authored-By: Pierre-Marie de Rodat <derodat@adacore.com>

From-SVN: r264701
parent 5c441345
2018-09-28 Eric Botcazou <ebotcazou@adacore.com>
Pierre-Marie de Rodat <derodat@adacore.com>
* calls.c (expand_call): Try to do a tail call for thunks at -O0 too.
* cgraph.h (struct cgraph_thunk_info): Add indirect_offset.
(cgraph_node::create_thunk): Add indirect_offset parameter.
(thunk_adjust): Likewise.
* cgraph.c (cgraph_node::create_thunk): Add indirect_offset parameter
and initialize the corresponding field with it.
(cgraph_node::dump): Dump indirect_offset field.
* cgraphclones.c (duplicate_thunk_for_node): Deal with indirect_offset.
* cgraphunit.c (cgraph_node::analyze): Be prepared for external thunks.
(thunk_adjust): Add indirect_offset parameter and deal with it.
(cgraph_node::expand_thunk): Deal with the indirect_offset field and
pass it to thunk_adjust. Do not call the target hook if it's non-zero
or if the thunk is external or local. Fix formatting. Do not chain
the RESULT_DECL to BLOCK_VARS. Pass the static chain to the target,
if any, in the GIMPLE representation.
* ipa-icf.c (sem_function::equals_wpa): Deal with indirect_offset.
* lto-cgraph.c (lto_output_node): Write indirect_offset field.
(input_node): Read indirect_offset field.
* tree-inline.c (expand_call_inline): Pass indirect_offset field in the
call to thunk_adjust.
* tree-nested.c (struct nesting_info): Add thunk_p field.
(create_nesting_tree): Set it.
(convert_all_function_calls): Copy static chain from targets to thunks.
(finalize_nesting_tree_1): Return early for thunks.
(unnest_nesting_tree_1): Do not finalize thunks.
(gimplify_all_functions): Do not gimplify thunks.
2018-09-28 David Malcolm <dmalcolm@redhat.com>
* opt-suggestions.c (option_proposer::build_option_suggestions):
......
2018-09-28 Eric Botcazou <ebotcazou@adacore.com>
Pierre-Marie de Rodat <derodat@adacore.com>
* gcc-interface/decl.c (is_cplusplus_method): Do not require C++
convention on Interfaces.
* gcc-interface/trans.c (Subprogram_Body_to_gnu): Try to create a
bona-fide thunk and hand it over to the middle-end.
(get_controlling_type): New function.
(use_alias_for_thunk_p): Likewise.
(thunk_labelno): New static variable.
(make_covariant_thunk): New function.
(maybe_make_gnu_thunk): Likewise.
* gcc-interface/utils.c (finish_subprog_decl): Set DECL_CONTEXT of the
result DECL here instead of...
(end_subprog_body): ...here.
2018-09-27 Martin Sebor <msebor@redhat.com>
* gcc-interface/utils.c (make_packable_type): Introduce a temporary
......
......@@ -4851,15 +4851,15 @@ is_cplusplus_method (Entity_Id gnat_entity)
if (Convention (gnat_entity) != Convention_CPP)
return false;
/* And that the type of the first parameter (indirectly) has it too. */
/* And that the type of the first parameter (indirectly) has it too, but
we make an exception for Interfaces because they need not be imported. */
Entity_Id gnat_first = First_Formal (gnat_entity);
if (No (gnat_first))
return false;
Entity_Id gnat_type = Etype (gnat_first);
if (Is_Access_Type (gnat_type))
gnat_type = Directly_Designated_Type (gnat_type);
if (Convention (gnat_type) != Convention_CPP)
if (Convention (gnat_type) != Convention_CPP && !Is_Interface (gnat_type))
return false;
/* This is the main case: a C++ virtual method imported as a primitive
......
......@@ -3294,6 +3294,7 @@ finish_subprog_decl (tree decl, tree asm_name, tree type)
DECL_ARTIFICIAL (result_decl) = 1;
DECL_IGNORED_P (result_decl) = 1;
DECL_CONTEXT (result_decl) = decl;
DECL_BY_REFERENCE (result_decl) = TREE_ADDRESSABLE (type);
DECL_RESULT (decl) = result_decl;
......@@ -3369,9 +3370,6 @@ end_subprog_body (tree body)
DECL_INITIAL (fndecl) = current_binding_level->block;
gnat_poplevel ();
/* Mark the RESULT_DECL as being in this subprogram. */
DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
/* The body should be a BIND_EXPR whose BLOCK is the top-level one. */
if (TREE_CODE (body) == BIND_EXPR)
{
......
......@@ -3610,9 +3610,8 @@ expand_call (tree exp, rtx target, int ignore)
pushed these optimizations into -O2. Don't try if we're already
expanding a call, as that means we're an argument. Don't try if
there's cleanups, as we know there's code to follow the call. */
if (currently_expanding_call++ != 0
|| !flag_optimize_sibling_calls
|| (!flag_optimize_sibling_calls && !CALL_FROM_THUNK_P (exp))
|| args_size.var
|| dbg_cnt (tail_call) == false)
try_tail_call = 0;
......
......@@ -617,6 +617,7 @@ cgraph_node *
cgraph_node::create_thunk (tree alias, tree, bool this_adjusting,
HOST_WIDE_INT fixed_offset,
HOST_WIDE_INT virtual_value,
HOST_WIDE_INT indirect_offset,
tree virtual_offset,
tree real_alias)
{
......@@ -635,6 +636,7 @@ cgraph_node::create_thunk (tree alias, tree, bool this_adjusting,
node->thunk.fixed_offset = fixed_offset;
node->thunk.virtual_value = virtual_value;
node->thunk.indirect_offset = indirect_offset;
node->thunk.alias = real_alias;
node->thunk.this_adjusting = this_adjusting;
node->thunk.virtual_offset_p = virtual_offset != NULL;
......@@ -2099,10 +2101,11 @@ cgraph_node::dump (FILE *f)
fprintf (f, " of %s (asm: %s)",
lang_hooks.decl_printable_name (thunk.alias, 2),
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk.alias)));
fprintf (f, " fixed offset %i virtual value %i has "
"virtual offset %i)\n",
fprintf (f, " fixed offset %i virtual value %i indirect_offset %i "
"has virtual offset %i\n",
(int)thunk.fixed_offset,
(int)thunk.virtual_value,
(int)thunk.indirect_offset,
(int)thunk.virtual_offset_p);
}
if (alias && thunk.alias
......
......@@ -666,6 +666,10 @@ struct GTY(()) cgraph_thunk_info {
VIRTUAL_OFFSET_P is true. */
HOST_WIDE_INT virtual_value;
/* Offset from "this" to get the offset to adjust "this". Zero means: this
offset is to be ignored. */
HOST_WIDE_INT indirect_offset;
/* Thunk target, i.e. the method that this thunk wraps. Depending on the
TARGET_USE_LOCAL_THUNK_ALIAS_P macro, this may have to be a new alias. */
tree alias;
......@@ -1033,6 +1037,7 @@ public:
cgraph_node * create_thunk (tree alias, tree, bool this_adjusting,
HOST_WIDE_INT fixed_offset,
HOST_WIDE_INT virtual_value,
HOST_WIDE_INT indirect_offset,
tree virtual_offset,
tree real_alias);
......@@ -2373,7 +2378,8 @@ void cgraphunit_c_finalize (void);
IN_SSA is true if the gimple is in SSA. */
basic_block init_lowered_empty_function (tree, bool, profile_count);
tree thunk_adjust (gimple_stmt_iterator *, tree, bool, HOST_WIDE_INT, tree);
tree thunk_adjust (gimple_stmt_iterator *, tree, bool, HOST_WIDE_INT, tree,
HOST_WIDE_INT);
/* In cgraphclones.c */
tree clone_function_name_1 (const char *, const char *);
......
......@@ -274,10 +274,11 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
cgraph_edge *cs;
for (cs = node->callers; cs; cs = cs->next_caller)
if (cs->caller->thunk.thunk_p
&& cs->caller->thunk.this_adjusting == thunk->thunk.this_adjusting
&& cs->caller->thunk.fixed_offset == thunk->thunk.fixed_offset
&& cs->caller->thunk.virtual_offset_p == thunk->thunk.virtual_offset_p
&& cs->caller->thunk.virtual_value == thunk->thunk.virtual_value)
&& cs->caller->thunk.virtual_value == thunk->thunk.virtual_value
&& cs->caller->thunk.indirect_offset == thunk->thunk.indirect_offset
&& cs->caller->thunk.this_adjusting == thunk->thunk.this_adjusting
&& cs->caller->thunk.virtual_offset_p == thunk->thunk.virtual_offset_p)
return cs->caller;
tree new_decl;
......
......@@ -623,20 +623,18 @@ cgraph_node::analyze (void)
callees->can_throw_external = !TREE_NOTHROW (t->decl);
/* Target code in expand_thunk may need the thunk's target
to be analyzed, so recurse here. */
if (!t->analyzed)
if (!t->analyzed && t->definition)
t->analyze ();
if (t->alias)
{
t = t->get_alias_target ();
if (!t->analyzed)
if (!t->analyzed && t->definition)
t->analyze ();
}
if (!expand_thunk (false, false))
{
thunk.alias = NULL;
return;
}
bool ret = expand_thunk (false, false);
thunk.alias = NULL;
if (!ret)
return;
}
if (alias)
resolve_alias (cgraph_node::get (alias_target), transparent_alias);
......@@ -1609,15 +1607,16 @@ init_lowered_empty_function (tree decl, bool in_ssa, profile_count count)
return bb;
}
/* 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. */
/* Adjust PTR by the constant FIXED_OFFSET, by the vtable offset indicated by
VIRTUAL_OFFSET, and by the indirect offset indicated by INDIRECT_OFFSET, if
it is non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and zero
for a result adjusting thunk. */
tree
thunk_adjust (gimple_stmt_iterator * bsi,
tree ptr, bool this_adjusting,
HOST_WIDE_INT fixed_offset, tree virtual_offset)
HOST_WIDE_INT fixed_offset, tree virtual_offset,
HOST_WIDE_INT indirect_offset)
{
gassign *stmt;
tree ret;
......@@ -1632,6 +1631,16 @@ thunk_adjust (gimple_stmt_iterator * bsi,
gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
}
if (!vtable_entry_type && (virtual_offset || indirect_offset != 0))
{
tree vfunc_type = make_node (FUNCTION_TYPE);
TREE_TYPE (vfunc_type) = integer_type_node;
TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
layout_type (vfunc_type);
vtable_entry_type = build_pointer_type (vfunc_type);
}
/* If there's a virtual offset, look up that value in the vtable and
adjust the pointer again. */
if (virtual_offset)
......@@ -1640,16 +1649,6 @@ thunk_adjust (gimple_stmt_iterator * bsi,
tree vtabletmp2;
tree vtabletmp3;
if (!vtable_entry_type)
{
tree vfunc_type = make_node (FUNCTION_TYPE);
TREE_TYPE (vfunc_type) = integer_type_node;
TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
layout_type (vfunc_type);
vtable_entry_type = build_pointer_type (vfunc_type);
}
vtabletmp =
create_tmp_reg (build_pointer_type
(build_pointer_type (vtable_entry_type)), "vptr");
......@@ -1687,6 +1686,41 @@ thunk_adjust (gimple_stmt_iterator * bsi,
GSI_CONTINUE_LINKING);
}
/* Likewise for an offset that is stored in the object that contains the
vtable. */
if (indirect_offset != 0)
{
tree offset_ptr, offset_tree;
/* Get the address of the offset. */
offset_ptr
= create_tmp_reg (build_pointer_type
(build_pointer_type (vtable_entry_type)),
"offset_ptr");
stmt = gimple_build_assign (offset_ptr,
build1 (NOP_EXPR, TREE_TYPE (offset_ptr),
ptr));
gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
stmt = gimple_build_assign
(offset_ptr,
fold_build_pointer_plus_hwi_loc (input_location, offset_ptr,
indirect_offset));
gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
/* Get the offset itself. */
offset_tree = create_tmp_reg (TREE_TYPE (TREE_TYPE (offset_ptr)),
"offset");
stmt = gimple_build_assign (offset_tree,
build_simple_mem_ref (offset_ptr));
gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
/* Adjust the `this' pointer. */
ptr = fold_build_pointer_plus_loc (input_location, ptr, offset_tree);
ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
GSI_CONTINUE_LINKING);
}
if (!this_adjusting
&& fixed_offset != 0)
/* Adjust the pointer by the constant. */
......@@ -1725,6 +1759,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
bool this_adjusting = thunk.this_adjusting;
HOST_WIDE_INT fixed_offset = thunk.fixed_offset;
HOST_WIDE_INT virtual_value = thunk.virtual_value;
HOST_WIDE_INT indirect_offset = thunk.indirect_offset;
tree virtual_offset = NULL;
tree alias = callees->callee->decl;
tree thunk_fndecl = decl;
......@@ -1735,7 +1770,11 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
if (thunk.add_pointer_bounds_args)
return false;
if (!force_gimple_thunk && this_adjusting
if (!force_gimple_thunk
&& this_adjusting
&& indirect_offset == 0
&& !DECL_EXTERNAL (alias)
&& !DECL_STATIC_CHAIN (alias)
&& targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
virtual_value, alias))
{
......@@ -1838,8 +1877,8 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1;
DECL_CONTEXT (resdecl) = thunk_fndecl;
DECL_RESULT (thunk_fndecl) = resdecl;
DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
}
else
resdecl = DECL_RESULT (thunk_fndecl);
......@@ -1876,8 +1915,11 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
restmp = resdecl;
if (VAR_P (restmp))
add_local_decl (cfun, restmp);
BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
{
add_local_decl (cfun, restmp);
BLOCK_VARS (DECL_INITIAL (current_function_decl))
= restmp;
}
}
else
restmp = create_tmp_var (restype, "retval");
......@@ -1894,7 +1936,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
if (this_adjusting)
{
vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
virtual_offset));
virtual_offset, indirect_offset));
arg = DECL_CHAIN (a);
i = 1;
}
......@@ -1919,6 +1961,25 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
callees->call_stmt = call;
gimple_call_set_from_thunk (call, true);
if (DECL_STATIC_CHAIN (alias))
{
tree p = DECL_STRUCT_FUNCTION (alias)->static_chain_decl;
tree type = TREE_TYPE (p);
tree decl = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
PARM_DECL, create_tmp_var_name ("CHAIN"),
type);
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
TREE_USED (decl) = 1;
DECL_CONTEXT (decl) = thunk_fndecl;
DECL_ARG_TYPE (decl) = type;
TREE_READONLY (decl) = 1;
struct function *sf = DECL_STRUCT_FUNCTION (thunk_fndecl);
sf->static_chain_decl = decl;
gimple_call_set_chain (call, decl);
}
/* Return slot optimization is always possible and in fact requred to
return values with DECL_BY_REFERENCE. */
......@@ -1979,7 +2040,8 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
}
restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
fixed_offset, virtual_offset);
fixed_offset, virtual_offset,
indirect_offset);
if (true_label)
{
gimple *stmt;
......
2018-09-28 Eric Botcazou <ebotcazou@adacore.com>
Pierre-Marie de Rodat <derodat@adacore.com>
* method.c (use_thunk): Adjust call to cgraph_node::create_thunk.
2018-09-28 Richard Biener <rguenther@suse.de>
* error.c (cp_print_error_function): Simplify by eliding
......
......@@ -375,7 +375,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
gcc_checking_assert (funcn);
thunk_node = funcn->create_thunk (thunk_fndecl, function,
this_adjusting, fixed_offset, virtual_value,
virtual_offset, alias);
0, virtual_offset, alias);
if (DECL_ONE_ONLY (function))
thunk_node->add_to_same_comdat_group (funcn);
......
......@@ -593,6 +593,8 @@ sem_function::equals_wpa (sem_item *item,
return return_false_with_msg ("thunk fixed_offset mismatch");
if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value)
return return_false_with_msg ("thunk virtual_value mismatch");
if (cnode->thunk.indirect_offset != cnode2->thunk.indirect_offset)
return return_false_with_msg ("thunk indirect_offset mismatch");
if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting)
return return_false_with_msg ("thunk this_adjusting mismatch");
if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p)
......
......@@ -556,6 +556,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
+ (node->thunk.add_pointer_bounds_args != 0) * 8);
streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
streamer_write_uhwi_stream (ob->main_stream, node->thunk.indirect_offset);
}
streamer_write_hwi_stream (ob->main_stream, node->profile_id);
if (DECL_STATIC_CONSTRUCTOR (node->decl))
......@@ -1271,10 +1272,12 @@ input_node (struct lto_file_decl_data *file_data,
int type = streamer_read_uhwi (ib);
HOST_WIDE_INT fixed_offset = streamer_read_uhwi (ib);
HOST_WIDE_INT virtual_value = streamer_read_uhwi (ib);
HOST_WIDE_INT indirect_offset = streamer_read_uhwi (ib);
node->thunk.fixed_offset = fixed_offset;
node->thunk.this_adjusting = (type & 2);
node->thunk.virtual_value = virtual_value;
node->thunk.indirect_offset = indirect_offset;
node->thunk.this_adjusting = (type & 2);
node->thunk.virtual_offset_p = (type & 4);
node->thunk.add_pointer_bounds_args = (type & 8);
}
......
......@@ -4473,7 +4473,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
GSI_NEW_STMT);
gcc_assert (id->src_node->thunk.this_adjusting);
op = thunk_adjust (&iter, op, 1, id->src_node->thunk.fixed_offset,
virtual_offset);
virtual_offset, id->src_node->thunk.indirect_offset);
gimple_call_set_arg (stmt, 0, op);
gimple_call_set_fndecl (stmt, edge->callee->decl);
......
......@@ -104,6 +104,7 @@ struct nesting_info
tree chain_decl;
tree nl_goto_field;
bool thunk_p;
bool any_parm_remapped;
bool any_tramp_created;
bool any_descr_created;
......@@ -834,6 +835,7 @@ create_nesting_tree (struct cgraph_node *cgn)
info->mem_refs = new hash_set<tree *>;
info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
info->context = cgn->decl;
info->thunk_p = cgn->thunk.thunk_p;
for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
{
......@@ -2786,6 +2788,8 @@ convert_all_function_calls (struct nesting_info *root)
within the debugger. */
FOR_EACH_NEST_INFO (n, root)
{
if (n->thunk_p)
continue;
tree decl = n->context;
if (!optimize)
{
......@@ -2806,6 +2810,14 @@ convert_all_function_calls (struct nesting_info *root)
chain_count += DECL_STATIC_CHAIN (decl);
}
FOR_EACH_NEST_INFO (n, root)
if (n->thunk_p)
{
tree decl = n->context;
tree alias = cgraph_node::get (decl)->thunk.alias;
DECL_STATIC_CHAIN (decl) = DECL_STATIC_CHAIN (alias);
}
/* Walk the functions and perform transformations. Note that these
transformations can induce new uses of the static chain, which in turn
require re-examining all users of the decl. */
......@@ -2825,12 +2837,22 @@ convert_all_function_calls (struct nesting_info *root)
FOR_EACH_NEST_INFO (n, root)
{
if (n->thunk_p)
continue;
tree decl = n->context;
walk_function (convert_tramp_reference_stmt,
convert_tramp_reference_op, n);
walk_function (convert_gimple_call, NULL, n);
chain_count += DECL_STATIC_CHAIN (decl);
}
FOR_EACH_NEST_INFO (n, root)
if (n->thunk_p)
{
tree decl = n->context;
tree alias = cgraph_node::get (decl)->thunk.alias;
DECL_STATIC_CHAIN (decl) = DECL_STATIC_CHAIN (alias);
}
}
while (chain_count != old_chain_count);
......@@ -3055,12 +3077,13 @@ build_init_call_stmt (struct nesting_info *info, tree decl, tree field,
static void
finalize_nesting_tree_1 (struct nesting_info *root)
{
gimple_seq stmt_list;
gimple_seq stmt_list = NULL;
gimple *stmt;
tree context = root->context;
struct function *sf;
stmt_list = NULL;
if (root->thunk_p)
return;
/* If we created a non-local frame type or decl, we need to lay them
out at this time. */
......@@ -3340,7 +3363,8 @@ unnest_nesting_tree_1 (struct nesting_info *root)
if (node->origin)
{
node->unnest ();
cgraph_node::finalize_function (root->context, true);
if (!root->thunk_p)
cgraph_node::finalize_function (root->context, true);
}
}
......@@ -3380,7 +3404,8 @@ gimplify_all_functions (struct cgraph_node *root)
if (!gimple_body (root->decl))
gimplify_function_tree (root->decl);
for (iter = root->nested; iter; iter = iter->next_nested)
gimplify_all_functions (iter);
if (!iter->thunk.thunk_p)
gimplify_all_functions (iter);
}
/* Main entry point for this pass. Process FNDECL and all of its nested
......
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