cgraphunit.c (add_new_function): Fix logic when adding from late IPA pass.
* cgraphunit.c (add_new_function): Fix logic when adding from late IPA pass. (assemble_thunk): Rename to ... (expand_thunk); .. this one; export; get it working with general functions; make produced gimple valid. * cgraph.h (expand_thunk): Declare. From-SVN: r201463
This commit is contained in:
parent
0e8853eefb
commit
bc0ec02766
3 changed files with 85 additions and 61 deletions
|
@ -1,3 +1,12 @@
|
|||
2013-08-02 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraphunit.c (add_new_function): Fix logic when adding from
|
||||
late IPA pass.
|
||||
(assemble_thunk): Rename to ...
|
||||
(expand_thunk); .. this one; export; get it working with general functions;
|
||||
make produced gimple valid.
|
||||
* cgraph.h (expand_thunk): Declare.
|
||||
|
||||
2013-08-02 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* ipa-cp.c (gather_context_independent_values): Use ipa_get_param_move_cost.
|
||||
|
|
|
@ -716,6 +716,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree);
|
|||
IN_SSA is true if the gimple is in SSA. */
|
||||
basic_block init_lowered_empty_function (tree, bool);
|
||||
void cgraph_reset_node (struct cgraph_node *);
|
||||
void expand_thunk (struct cgraph_node *);
|
||||
|
||||
/* In cgraphclones.c */
|
||||
|
||||
|
|
136
gcc/cgraphunit.c
136
gcc/cgraphunit.c
|
@ -323,13 +323,10 @@ cgraph_process_new_functions (void)
|
|||
if (!node->symbol.analyzed)
|
||||
analyze_function (node);
|
||||
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
|
||||
if ((cgraph_state == CGRAPH_STATE_IPA_SSA
|
||||
if (cgraph_state == CGRAPH_STATE_IPA_SSA
|
||||
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
|
||||
/* When not optimizing, be sure we run early local passes anyway
|
||||
to expand OMP. */
|
||||
|| !optimize)
|
||||
execute_pass_list (pass_early_local_passes.pass.sub);
|
||||
else
|
||||
else if (inline_summary_vec != NULL)
|
||||
compute_inline_parameters (node, true);
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
|
@ -1327,8 +1324,8 @@ thunk_adjust (gimple_stmt_iterator * bsi,
|
|||
|
||||
/* Produce assembler for thunk NODE. */
|
||||
|
||||
static void
|
||||
assemble_thunk (struct cgraph_node *node)
|
||||
void
|
||||
expand_thunk (struct cgraph_node *node)
|
||||
{
|
||||
bool this_adjusting = node->thunk.this_adjusting;
|
||||
HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
|
||||
|
@ -1420,7 +1417,9 @@ assemble_thunk (struct cgraph_node *node)
|
|||
/* Build call to the function being thunked. */
|
||||
if (!VOID_TYPE_P (restype))
|
||||
{
|
||||
if (!is_gimple_reg_type (restype))
|
||||
if (DECL_BY_REFERENCE (resdecl))
|
||||
restmp = gimple_fold_indirect_ref (resdecl);
|
||||
else if (!is_gimple_reg_type (restype))
|
||||
{
|
||||
restmp = resdecl;
|
||||
add_local_decl (cfun, restmp);
|
||||
|
@ -1436,74 +1435,91 @@ assemble_thunk (struct cgraph_node *node)
|
|||
if (this_adjusting)
|
||||
vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
|
||||
virtual_offset));
|
||||
else
|
||||
else if (nargs)
|
||||
vargs.quick_push (a);
|
||||
for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
|
||||
vargs.quick_push (arg);
|
||||
|
||||
if (nargs)
|
||||
for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
|
||||
vargs.quick_push (arg);
|
||||
call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
|
||||
vargs.release ();
|
||||
gimple_call_set_from_thunk (call, true);
|
||||
if (restmp)
|
||||
gimple_call_set_lhs (call, restmp);
|
||||
{
|
||||
gimple_call_set_lhs (call, restmp);
|
||||
gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
|
||||
TREE_TYPE (TREE_TYPE (alias))));
|
||||
}
|
||||
gsi_insert_after (&bsi, call, GSI_NEW_STMT);
|
||||
|
||||
if (restmp && !this_adjusting)
|
||||
{
|
||||
tree true_label = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
|
||||
if (!(gimple_call_flags (call) & ECF_NORETURN))
|
||||
{
|
||||
if (restmp && !this_adjusting
|
||||
&& (fixed_offset || virtual_offset))
|
||||
{
|
||||
gimple stmt;
|
||||
/* 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. */
|
||||
then_bb = create_basic_block (NULL, (void *) 0, bb);
|
||||
return_bb = create_basic_block (NULL, (void *) 0, then_bb);
|
||||
else_bb = create_basic_block (NULL, (void *) 0, else_bb);
|
||||
add_bb_to_loop (then_bb, bb->loop_father);
|
||||
add_bb_to_loop (return_bb, bb->loop_father);
|
||||
add_bb_to_loop (else_bb, bb->loop_father);
|
||||
remove_edge (single_succ_edge (bb));
|
||||
true_label = gimple_block_label (then_bb);
|
||||
stmt = gimple_build_cond (NE_EXPR, restmp,
|
||||
build_zero_cst (TREE_TYPE (restmp)),
|
||||
NULL_TREE, NULL_TREE);
|
||||
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
|
||||
make_edge (bb, then_bb, EDGE_TRUE_VALUE);
|
||||
make_edge (bb, else_bb, EDGE_FALSE_VALUE);
|
||||
make_edge (return_bb, EXIT_BLOCK_PTR, 0);
|
||||
make_edge (then_bb, return_bb, EDGE_FALLTHRU);
|
||||
make_edge (else_bb, return_bb, EDGE_FALLTHRU);
|
||||
bsi = gsi_last_bb (then_bb);
|
||||
}
|
||||
tree true_label = NULL_TREE;
|
||||
|
||||
restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
|
||||
fixed_offset, virtual_offset);
|
||||
if (true_label)
|
||||
{
|
||||
gimple stmt;
|
||||
bsi = gsi_last_bb (else_bb);
|
||||
stmt = gimple_build_assign (restmp,
|
||||
build_zero_cst (TREE_TYPE (restmp)));
|
||||
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
|
||||
bsi = gsi_last_bb (return_bb);
|
||||
if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
|
||||
{
|
||||
gimple stmt;
|
||||
/* 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. */
|
||||
then_bb = create_basic_block (NULL, (void *) 0, bb);
|
||||
return_bb = create_basic_block (NULL, (void *) 0, then_bb);
|
||||
else_bb = create_basic_block (NULL, (void *) 0, else_bb);
|
||||
add_bb_to_loop (then_bb, bb->loop_father);
|
||||
add_bb_to_loop (return_bb, bb->loop_father);
|
||||
add_bb_to_loop (else_bb, bb->loop_father);
|
||||
remove_edge (single_succ_edge (bb));
|
||||
true_label = gimple_block_label (then_bb);
|
||||
stmt = gimple_build_cond (NE_EXPR, restmp,
|
||||
build_zero_cst (TREE_TYPE (restmp)),
|
||||
NULL_TREE, NULL_TREE);
|
||||
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
|
||||
make_edge (bb, then_bb, EDGE_TRUE_VALUE);
|
||||
make_edge (bb, else_bb, EDGE_FALSE_VALUE);
|
||||
make_edge (return_bb, EXIT_BLOCK_PTR, 0);
|
||||
make_edge (then_bb, return_bb, EDGE_FALLTHRU);
|
||||
make_edge (else_bb, return_bb, EDGE_FALLTHRU);
|
||||
bsi = gsi_last_bb (then_bb);
|
||||
}
|
||||
|
||||
restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
|
||||
fixed_offset, virtual_offset);
|
||||
if (true_label)
|
||||
{
|
||||
gimple stmt;
|
||||
bsi = gsi_last_bb (else_bb);
|
||||
stmt = gimple_build_assign (restmp,
|
||||
build_zero_cst (TREE_TYPE (restmp)));
|
||||
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
|
||||
bsi = gsi_last_bb (return_bb);
|
||||
}
|
||||
}
|
||||
else
|
||||
gimple_call_set_tail (call, true);
|
||||
|
||||
/* Build return value. */
|
||||
ret = gimple_build_return (restmp);
|
||||
gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
|
||||
}
|
||||
else
|
||||
gimple_call_set_tail (call, true);
|
||||
|
||||
/* Build return value. */
|
||||
ret = gimple_build_return (restmp);
|
||||
gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
|
||||
{
|
||||
gimple_call_set_tail (call, true);
|
||||
remove_edge (single_succ_edge (bb));
|
||||
}
|
||||
|
||||
delete_unreachable_blocks ();
|
||||
update_ssa (TODO_update_ssa);
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_flow_info ();
|
||||
#endif
|
||||
|
||||
/* Since we want to emit the thunk, we explicitly mark its name as
|
||||
referenced. */
|
||||
node->thunk.thunk_p = false;
|
||||
cgraph_node_remove_callees (node);
|
||||
rebuild_cgraph_edges ();
|
||||
cgraph_add_new_function (thunk_fndecl, true);
|
||||
bitmap_obstack_release (NULL);
|
||||
}
|
||||
|
@ -1511,8 +1527,6 @@ assemble_thunk (struct cgraph_node *node)
|
|||
set_cfun (NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assemble thunks and aliases associated to NODE. */
|
||||
|
||||
static void
|
||||
|
@ -1529,7 +1543,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
|
|||
|
||||
e = e->next_caller;
|
||||
assemble_thunks_and_aliases (thunk);
|
||||
assemble_thunk (thunk);
|
||||
expand_thunk (thunk);
|
||||
}
|
||||
else
|
||||
e = e->next_caller;
|
||||
|
|
Loading…
Add table
Reference in a new issue