Commit afdec9bd by Jan Hubicka Committed by Jan Hubicka

tree-into-ssa.c (gate_into_ssa): New.


	* tree-into-ssa.c (gate_into_ssa): New.
	(pass_data_build_ssa): Use it.
	* cgraph.h (expand_thunk): Update prototype.
	* cgraphunit.c (analyze_function): Expand thunks early.
	(expand_thunk): Fix DECL_CONTEXT of reust_decl;
	build proper cgraph; set in_ssa_p; clear bogus TREE_ASM_WRITTEN;
	set lowered flag; do not add new function.
	(assemble_thunks_and_aliases): Update.
	* tree-ssa.c (gate_init_datastructures): New gate.
	(pass_data_init_datastructures): Use it.

From-SVN: r202592
parent 7b86458e
2013-09-14 Jan Hubicka <jh@suse.cz>
* tree-into-ssa.c (gate_into_ssa): New.
(pass_data_build_ssa): Use it.
* cgraph.h (expand_thunk): Update prototype.
* cgraphunit.c (analyze_function): Expand thunks early.
(expand_thunk): Fix DECL_CONTEXT of reust_decl;
build proper cgraph; set in_ssa_p; clear bogus TREE_ASM_WRITTEN;
set lowered flag; do not add new function.
(assemble_thunks_and_aliases): Update.
* tree-ssa.c (gate_init_datastructures): New gate.
(pass_data_init_datastructures): Use it.
2013-09-14 Iain Sandoe <iain@codesourcery.com> 2013-09-14 Iain Sandoe <iain@codesourcery.com>
PR target/58269 PR target/58269
......
...@@ -757,7 +757,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree); ...@@ -757,7 +757,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree);
IN_SSA is true if the gimple is in SSA. */ IN_SSA is true if the gimple is in SSA. */
basic_block init_lowered_empty_function (tree, bool); basic_block init_lowered_empty_function (tree, bool);
void cgraph_reset_node (struct cgraph_node *); void cgraph_reset_node (struct cgraph_node *);
void expand_thunk (struct cgraph_node *); bool expand_thunk (struct cgraph_node *, bool);
/* In cgraphclones.c */ /* In cgraphclones.c */
......
...@@ -592,15 +592,21 @@ analyze_function (struct cgraph_node *node) ...@@ -592,15 +592,21 @@ analyze_function (struct cgraph_node *node)
location_t saved_loc = input_location; location_t saved_loc = input_location;
input_location = DECL_SOURCE_LOCATION (decl); input_location = DECL_SOURCE_LOCATION (decl);
if (node->symbol.alias) if (node->thunk.thunk_p)
symtab_resolve_alias
((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
else if (node->thunk.thunk_p)
{ {
cgraph_create_edge (node, cgraph_get_node (node->thunk.alias), cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
NULL, 0, CGRAPH_FREQ_BASE); NULL, 0, CGRAPH_FREQ_BASE);
if (!expand_thunk (node, false))
{
node->thunk.alias = NULL; node->thunk.alias = NULL;
node->symbol.analyzed = true;
return;
} }
node->thunk.alias = NULL;
}
if (node->symbol.alias)
symtab_resolve_alias
((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
else if (node->dispatcher_function) else if (node->dispatcher_function)
{ {
/* Generate the dispatcher body of multi-versioned functions. */ /* Generate the dispatcher body of multi-versioned functions. */
...@@ -1432,10 +1438,12 @@ thunk_adjust (gimple_stmt_iterator * bsi, ...@@ -1432,10 +1438,12 @@ thunk_adjust (gimple_stmt_iterator * bsi,
return ret; return ret;
} }
/* Produce assembler for thunk NODE. */ /* Expand thunk NODE to gimple if possible.
When OUTPUT_ASM_THUNK is true, also produce assembler for
thunks that are not lowered. */
void bool
expand_thunk (struct cgraph_node *node) expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
{ {
bool this_adjusting = node->thunk.this_adjusting; bool this_adjusting = node->thunk.this_adjusting;
HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset; HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
...@@ -1445,14 +1453,6 @@ expand_thunk (struct cgraph_node *node) ...@@ -1445,14 +1453,6 @@ expand_thunk (struct cgraph_node *node)
tree thunk_fndecl = node->symbol.decl; tree thunk_fndecl = node->symbol.decl;
tree a; tree a;
if (in_lto_p)
cgraph_get_body (node);
a = DECL_ARGUMENTS (thunk_fndecl);
current_function_decl = thunk_fndecl;
/* Ensure thunks are emitted in their correct sections. */
resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
if (this_adjusting if (this_adjusting
&& targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
...@@ -1462,9 +1462,22 @@ expand_thunk (struct cgraph_node *node) ...@@ -1462,9 +1462,22 @@ expand_thunk (struct cgraph_node *node)
tree fn_block; tree fn_block;
tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl)); tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
if (!output_asm_thunks)
return false;
if (in_lto_p)
cgraph_get_body (node);
a = DECL_ARGUMENTS (thunk_fndecl);
current_function_decl = thunk_fndecl;
/* Ensure thunks are emitted in their correct sections. */
resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
DECL_RESULT (thunk_fndecl) DECL_RESULT (thunk_fndecl)
= build_decl (DECL_SOURCE_LOCATION (thunk_fndecl), = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
RESULT_DECL, 0, restype); RESULT_DECL, 0, restype);
DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl)); fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
/* The back end expects DECL_INITIAL to contain a BLOCK, so we /* The back end expects DECL_INITIAL to contain a BLOCK, so we
...@@ -1506,6 +1519,15 @@ expand_thunk (struct cgraph_node *node) ...@@ -1506,6 +1519,15 @@ expand_thunk (struct cgraph_node *node)
gimple call; gimple call;
gimple ret; gimple ret;
if (in_lto_p)
cgraph_get_body (node);
a = DECL_ARGUMENTS (thunk_fndecl);
current_function_decl = thunk_fndecl;
/* Ensure thunks are emitted in their correct sections. */
resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
DECL_IGNORED_P (thunk_fndecl) = 1; DECL_IGNORED_P (thunk_fndecl) = 1;
bitmap_obstack_initialize (NULL); bitmap_obstack_initialize (NULL);
...@@ -1520,6 +1542,7 @@ expand_thunk (struct cgraph_node *node) ...@@ -1520,6 +1542,7 @@ expand_thunk (struct cgraph_node *node)
DECL_ARTIFICIAL (resdecl) = 1; DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1; DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (thunk_fndecl) = resdecl; DECL_RESULT (thunk_fndecl) = resdecl;
DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
} }
else else
resdecl = DECL_RESULT (thunk_fndecl); resdecl = DECL_RESULT (thunk_fndecl);
...@@ -1556,6 +1579,7 @@ expand_thunk (struct cgraph_node *node) ...@@ -1556,6 +1579,7 @@ expand_thunk (struct cgraph_node *node)
for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg)) for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
vargs.quick_push (arg); vargs.quick_push (arg);
call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
node->callees->call_stmt = call;
vargs.release (); vargs.release ();
gimple_call_set_from_thunk (call, true); gimple_call_set_from_thunk (call, true);
if (restmp) if (restmp)
...@@ -1624,6 +1648,9 @@ expand_thunk (struct cgraph_node *node) ...@@ -1624,6 +1648,9 @@ expand_thunk (struct cgraph_node *node)
remove_edge (single_succ_edge (bb)); remove_edge (single_succ_edge (bb));
} }
cfun->gimple_df->in_ssa_p = true;
/* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
TREE_ASM_WRITTEN (thunk_fndecl) = false;
delete_unreachable_blocks (); delete_unreachable_blocks ();
update_ssa (TODO_update_ssa); update_ssa (TODO_update_ssa);
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
...@@ -1633,12 +1660,12 @@ expand_thunk (struct cgraph_node *node) ...@@ -1633,12 +1660,12 @@ expand_thunk (struct cgraph_node *node)
/* Since we want to emit the thunk, we explicitly mark its name as /* Since we want to emit the thunk, we explicitly mark its name as
referenced. */ referenced. */
node->thunk.thunk_p = false; node->thunk.thunk_p = false;
rebuild_cgraph_edges (); node->lowered = true;
cgraph_add_new_function (thunk_fndecl, true);
bitmap_obstack_release (NULL); bitmap_obstack_release (NULL);
} }
current_function_decl = NULL; current_function_decl = NULL;
set_cfun (NULL); set_cfun (NULL);
return true;
} }
/* Assemble thunks and aliases associated to NODE. */ /* Assemble thunks and aliases associated to NODE. */
...@@ -1657,7 +1684,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node) ...@@ -1657,7 +1684,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
e = e->next_caller; e = e->next_caller;
assemble_thunks_and_aliases (thunk); assemble_thunks_and_aliases (thunk);
expand_thunk (thunk); expand_thunk (thunk, true);
} }
else else
e = e->next_caller; e = e->next_caller;
......
...@@ -2409,6 +2409,14 @@ rewrite_into_ssa (void) ...@@ -2409,6 +2409,14 @@ rewrite_into_ssa (void)
return 0; return 0;
} }
/* Gate for IPCP optimization. */
static bool
gate_into_ssa (void)
{
/* Do nothing for funcions that was produced already in SSA form. */
return !(cfun->curr_properties & PROP_ssa);
}
namespace { namespace {
...@@ -2417,7 +2425,7 @@ const pass_data pass_data_build_ssa = ...@@ -2417,7 +2425,7 @@ const pass_data pass_data_build_ssa =
GIMPLE_PASS, /* type */ GIMPLE_PASS, /* type */
"ssa", /* name */ "ssa", /* name */
OPTGROUP_NONE, /* optinfo_flags */ OPTGROUP_NONE, /* optinfo_flags */
false, /* has_gate */ true, /* has_gate */
true, /* has_execute */ true, /* has_execute */
TV_TREE_SSA_OTHER, /* tv_id */ TV_TREE_SSA_OTHER, /* tv_id */
PROP_cfg, /* properties_required */ PROP_cfg, /* properties_required */
...@@ -2435,6 +2443,7 @@ public: ...@@ -2435,6 +2443,7 @@ public:
{} {}
/* opt_pass methods: */ /* opt_pass methods: */
bool gate () { return gate_into_ssa (); }
unsigned int execute () { return rewrite_into_ssa (); } unsigned int execute () { return rewrite_into_ssa (); }
}; // class pass_build_ssa }; // class pass_build_ssa
......
...@@ -1084,10 +1084,20 @@ static unsigned int ...@@ -1084,10 +1084,20 @@ static unsigned int
execute_init_datastructures (void) execute_init_datastructures (void)
{ {
/* Allocate hash tables, arrays and other structures. */ /* Allocate hash tables, arrays and other structures. */
gcc_assert (!cfun->gimple_df);
init_tree_ssa (cfun); init_tree_ssa (cfun);
return 0; return 0;
} }
/* Gate for IPCP optimization. */
static bool
gate_init_datastructures (void)
{
/* Do nothing for funcions that was produced already in SSA form. */
return !(cfun->curr_properties & PROP_ssa);
}
namespace { namespace {
const pass_data pass_data_init_datastructures = const pass_data pass_data_init_datastructures =
...@@ -1095,7 +1105,7 @@ const pass_data pass_data_init_datastructures = ...@@ -1095,7 +1105,7 @@ const pass_data pass_data_init_datastructures =
GIMPLE_PASS, /* type */ GIMPLE_PASS, /* type */
"*init_datastructures", /* name */ "*init_datastructures", /* name */
OPTGROUP_NONE, /* optinfo_flags */ OPTGROUP_NONE, /* optinfo_flags */
false, /* has_gate */ true, /* has_gate */
true, /* has_execute */ true, /* has_execute */
TV_NONE, /* tv_id */ TV_NONE, /* tv_id */
PROP_cfg, /* properties_required */ PROP_cfg, /* properties_required */
...@@ -1113,6 +1123,7 @@ public: ...@@ -1113,6 +1123,7 @@ public:
{} {}
/* opt_pass methods: */ /* opt_pass methods: */
bool gate () { return gate_init_datastructures (); }
unsigned int execute () { return execute_init_datastructures (); } unsigned int execute () { return execute_init_datastructures (); }
}; // class pass_init_datastructures }; // class pass_init_datastructures
......
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