diff options
author | Jan Hubicka <jh@suse.cz> | 2013-09-14 17:27:21 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-09-14 15:27:21 +0000 |
commit | afdec9bd067cffe3242fe256e547dc5733006b2c (patch) | |
tree | 44cbc571bf525f510cf558c4af549858eb78da92 | |
parent | 7b86458e38ee3c88ca4e222c85ef6fa883267315 (diff) | |
download | gcc-afdec9bd067cffe3242fe256e547dc5733006b2c.zip gcc-afdec9bd067cffe3242fe256e547dc5733006b2c.tar.gz gcc-afdec9bd067cffe3242fe256e547dc5733006b2c.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cgraph.h | 2 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 65 | ||||
-rw-r--r-- | gcc/tree-into-ssa.c | 11 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 13 |
5 files changed, 82 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5113efd..08a9124 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +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> PR target/58269 diff --git a/gcc/cgraph.h b/gcc/cgraph.h index a6a0a243..50e8743 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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. */ basic_block init_lowered_empty_function (tree, bool); void cgraph_reset_node (struct cgraph_node *); -void expand_thunk (struct cgraph_node *); +bool expand_thunk (struct cgraph_node *, bool); /* In cgraphclones.c */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 8331f2e..1644ca9 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -592,15 +592,21 @@ analyze_function (struct cgraph_node *node) location_t saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (decl); - if (node->symbol.alias) - symtab_resolve_alias - ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target)); - else if (node->thunk.thunk_p) + if (node->thunk.thunk_p) { 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->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) { /* Generate the dispatcher body of multi-versioned functions. */ @@ -1432,10 +1438,12 @@ thunk_adjust (gimple_stmt_iterator * bsi, 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 -expand_thunk (struct cgraph_node *node) +bool +expand_thunk (struct cgraph_node *node, bool output_asm_thunks) { bool this_adjusting = node->thunk.this_adjusting; HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset; @@ -1445,14 +1453,6 @@ expand_thunk (struct cgraph_node *node) tree thunk_fndecl = node->symbol.decl; 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 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, @@ -1461,10 +1461,23 @@ expand_thunk (struct cgraph_node *node) const char *fnname; tree fn_block; 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) = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl), RESULT_DECL, 0, restype); + DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl)); /* The back end expects DECL_INITIAL to contain a BLOCK, so we @@ -1506,6 +1519,15 @@ expand_thunk (struct cgraph_node *node) gimple call; 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; bitmap_obstack_initialize (NULL); @@ -1520,6 +1542,7 @@ expand_thunk (struct cgraph_node *node) DECL_ARTIFICIAL (resdecl) = 1; DECL_IGNORED_P (resdecl) = 1; DECL_RESULT (thunk_fndecl) = resdecl; + DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; } else resdecl = DECL_RESULT (thunk_fndecl); @@ -1556,6 +1579,7 @@ expand_thunk (struct cgraph_node *node) 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); + node->callees->call_stmt = call; vargs.release (); gimple_call_set_from_thunk (call, true); if (restmp) @@ -1624,6 +1648,9 @@ expand_thunk (struct cgraph_node *node) 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 (); update_ssa (TODO_update_ssa); #ifdef ENABLE_CHECKING @@ -1633,12 +1660,12 @@ expand_thunk (struct cgraph_node *node) /* Since we want to emit the thunk, we explicitly mark its name as referenced. */ node->thunk.thunk_p = false; - rebuild_cgraph_edges (); - cgraph_add_new_function (thunk_fndecl, true); + node->lowered = true; bitmap_obstack_release (NULL); } current_function_decl = NULL; set_cfun (NULL); + return true; } /* Assemble thunks and aliases associated to NODE. */ @@ -1657,7 +1684,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node) e = e->next_caller; assemble_thunks_and_aliases (thunk); - expand_thunk (thunk); + expand_thunk (thunk, true); } else e = e->next_caller; diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index e6e8a3a..726744d 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -2409,6 +2409,14 @@ rewrite_into_ssa (void) 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 { @@ -2417,7 +2425,7 @@ const pass_data pass_data_build_ssa = GIMPLE_PASS, /* type */ "ssa", /* name */ OPTGROUP_NONE, /* optinfo_flags */ - false, /* has_gate */ + true, /* has_gate */ true, /* has_execute */ TV_TREE_SSA_OTHER, /* tv_id */ PROP_cfg, /* properties_required */ @@ -2435,6 +2443,7 @@ public: {} /* opt_pass methods: */ + bool gate () { return gate_into_ssa (); } unsigned int execute () { return rewrite_into_ssa (); } }; // class pass_build_ssa diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 48c997d..461bb52 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1084,10 +1084,20 @@ static unsigned int execute_init_datastructures (void) { /* Allocate hash tables, arrays and other structures. */ + gcc_assert (!cfun->gimple_df); init_tree_ssa (cfun); 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 { const pass_data pass_data_init_datastructures = @@ -1095,7 +1105,7 @@ const pass_data pass_data_init_datastructures = GIMPLE_PASS, /* type */ "*init_datastructures", /* name */ OPTGROUP_NONE, /* optinfo_flags */ - false, /* has_gate */ + true, /* has_gate */ true, /* has_execute */ TV_NONE, /* tv_id */ PROP_cfg, /* properties_required */ @@ -1113,6 +1123,7 @@ public: {} /* opt_pass methods: */ + bool gate () { return gate_init_datastructures (); } unsigned int execute () { return execute_init_datastructures (); } }; // class pass_init_datastructures |