diff options
author | Martin Jambor <mjambor@suse.cz> | 2019-09-20 00:25:04 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2019-09-20 00:25:04 +0200 |
commit | ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4 (patch) | |
tree | 21de4e26dd766dab8b60b2be7190a6b86bad2b38 /gcc/ipa-cp.c | |
parent | 6889a3acfeed47265886676c6d43b04ef799fb82 (diff) | |
download | gcc-ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4.zip gcc-ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4.tar.gz gcc-ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4.tar.bz2 |
New IPA-SRA
2019-09-20 Martin Jambor <mjambor@suse.cz>
* coretypes.h (cgraph_edge): Declare.
* ipa-param-manipulation.c: Rewrite.
* ipa-param-manipulation.h: Likewise.
* Makefile.in (GTFILES): Added ipa-param-manipulation.h and ipa-sra.c.
(OBJS): Added ipa-sra.o.
* cgraph.h (ipa_replace_map): Removed fields old_tree, replace_p
and ref_p, added fields param_adjustments and performed_splits.
(struct cgraph_clone_info): Remove ags_to_skip and
combined_args_to_skip, new field param_adjustments.
(cgraph_node::create_clone): Changed parameters to use
ipa_param_adjustments.
(cgraph_node::create_virtual_clone): Likewise.
(cgraph_node::create_virtual_clone_with_body): Likewise.
(tree_function_versioning): Likewise.
(cgraph_build_function_type_skip_args): Removed.
* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Convert to
using ipa_param_adjustments.
(clone_of_p): Likewise.
* cgraphclones.c (cgraph_build_function_type_skip_args): Removed.
(build_function_decl_skip_args): Likewise.
(duplicate_thunk_for_node): Adjust parameters using
ipa_param_body_adjustments, copy param_adjustments instead of
args_to_skip.
(cgraph_node::create_clone): Convert to using ipa_param_adjustments.
(cgraph_node::create_virtual_clone): Likewise.
(cgraph_node::create_version_clone_with_body): Likewise.
(cgraph_materialize_clone): Likewise.
(symbol_table::materialize_all_clones): Likewise.
* ipa-fnsummary.c (ipa_fn_summary_t::duplicate): Simplify
ipa_replace_map check.
* ipa-cp.c (get_replacement_map): Do not initialize removed fields.
(initialize_node_lattices): Make aware that some parameters might have
already been removed.
(want_remove_some_param_p): New function.
(create_specialized_node): Convert to using ipa_param_adjustments and
deal with possibly pre-existing adjustments.
* lto-cgraph.c (output_cgraph_opt_summary_p): Likewise.
(output_node_opt_summary): Do not stream removed fields. Stream
parameter adjustments instead of argumetns to skip.
(input_node_opt_summary): Likewise.
(input_node_opt_summary): Likewise.
* lto-section-in.c (lto_section_name): Added ipa-sra section.
* lto-streamer.h (lto_section_type): Likewise.
* tree-inline.h (copy_body_data): New fields killed_new_ssa_names and
param_body_adjs.
(copy_decl_to_var): Declare.
* tree-inline.c (update_clone_info): Do not remap old_tree.
(remap_gimple_stmt): Use ipa_param_body_adjustments to modify gimple
statements, walk all extra generated statements and remap their
operands.
(redirect_all_calls): Add killed SSA names to a hash set.
(remap_ssa_name): Do not remap killed SSA names.
(copy_arguments_for_versioning): Renames to copy_arguments_nochange,
half of functionality moved to ipa_param_body_adjustments.
(copy_decl_to_var): Make exported.
(copy_body): Destroy killed_new_ssa_names hash set.
(expand_call_inline): Remap performed splits.
(update_clone_info): Likewise.
(tree_function_versioning): Simplify tree_map processing. Updated to
accept ipa_param_adjustments and use ipa_param_body_adjustments.
* omp-simd-clone.c (simd_clone_vector_of_formal_parm_types): Adjust
for the new interface.
(simd_clone_clauses_extract): Likewise, make args an auto_vec.
(simd_clone_compute_base_data_type): Likewise.
(simd_clone_init_simd_arrays): Adjust for the new interface.
(simd_clone_adjust_argument_types): Likewise.
(struct modify_stmt_info): Likewise.
(ipa_simd_modify_stmt_ops): Likewise.
(ipa_simd_modify_function_body): Likewise.
(simd_clone_adjust): Likewise.
* tree-sra.c: Removed IPA-SRA. Include tree-sra.h.
(type_internals_preclude_sra_p): Make public.
* tree-sra.h: New file.
* ipa-inline-transform.c (save_inline_function_body): Update to
refelct new tree_function_versioning signature.
* ipa-prop.c (adjust_agg_replacement_values): Use a helper from
ipa_param_adjustments to get current parameter indices.
(ipcp_modif_dom_walker::before_dom_children): Likewise.
(ipcp_update_bits): Likewise.
(ipcp_update_vr): Likewise.
* ipa-split.c (split_function): Convert to using ipa_param_adjustments.
* ipa-sra.c: New file.
* multiple_target.c (create_target_clone): Update to reflet new type
of create_version_clone_with_body.
* trans-mem.c (ipa_tm_create_version): Update to reflect new type of
tree_function_versioning.
(modify_function): Update to reflect new type of
tree_function_versioning.
* params.def (PARAM_IPA_SRA_MAX_REPLACEMENTS): New.
* passes.def: Remove old IPA-SRA and add new one.
* tree-pass.h (make_pass_early_ipa_sra): Remove declaration.
(make_pass_ipa_sra): Declare.
* dbgcnt.def: Remove eipa_sra. Added ipa_sra_params and
ipa_sra_retvalues.
* doc/invoke.texi (ipa-sra-max-replacements): New.
testsuite/
* g++.dg/ipa/pr81248.C: Adjust dg-options and dump-scan.
* gcc.dg/ipa/ipa-sra-1.c: Likewise.
* gcc.dg/ipa/ipa-sra-10.c: Likewise.
* gcc.dg/ipa/ipa-sra-11.c: Likewise.
* gcc.dg/ipa/ipa-sra-3.c: Likewise.
* gcc.dg/ipa/ipa-sra-4.c: Likewise.
* gcc.dg/ipa/ipa-sra-5.c: Likewise.
* gcc.dg/ipa/ipacost-2.c: Disable ipa-sra.
* gcc.dg/ipa/ipcp-agg-9.c: Likewise.
* gcc.dg/ipa/pr78121.c: Adjust scan pattern.
* gcc.dg/ipa/vrp1.c: Likewise.
* gcc.dg/ipa/vrp2.c: Likewise.
* gcc.dg/ipa/vrp3.c: Likewise.
* gcc.dg/ipa/vrp7.c: Likewise.
* gcc.dg/ipa/vrp8.c: Likewise.
* gcc.dg/noreorder.c: use noipa attribute instead of noinline.
* gcc.dg/ipa/20040703-wpa.c: New test.
* gcc.dg/ipa/ipa-sra-12.c: New test.
* gcc.dg/ipa/ipa-sra-13.c: Likewise.
* gcc.dg/ipa/ipa-sra-14.c: Likewise.
* gcc.dg/ipa/ipa-sra-15.c: Likewise.
* gcc.dg/ipa/ipa-sra-16.c: Likewise.
* gcc.dg/ipa/ipa-sra-17.c: Likewise.
* gcc.dg/ipa/ipa-sra-18.c: Likewise.
* gcc.dg/ipa/ipa-sra-19.c: Likewise.
* gcc.dg/ipa/ipa-sra-20.c: Likewise.
* gcc.dg/ipa/ipa-sra-21.c: Likewise.
* gcc.dg/ipa/ipa-sra-22.c: Likewise.
* gcc.dg/sso/ipa-sra-1.c: Likewise.
* g++.dg/ipa/ipa-sra-2.C: Likewise.
* g++.dg/ipa/ipa-sra-3.C: Likewise.
* gcc.dg/tree-ssa/ipa-cp-1.c: Make return value used.
* g++.dg/ipa/devirt-19.C: Add missing return, add -fipa-cp-clone
option.
* g++.dg/lto/devirt-19_0.C: Add -fipa-cp-clone option.
* gcc.dg/ipa/ipa-sra-2.c: Removed.
* gcc.dg/ipa/ipa-sra-6.c: Likewise.
From-SVN: r275982
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r-- | gcc/ipa-cp.c | 172 |
1 files changed, 137 insertions, 35 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 33d52fe..b4fb74e 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1184,7 +1184,10 @@ initialize_node_lattices (struct cgraph_node *node) int i; gcc_checking_assert (node->has_gimple_body_p ()); - if (node->local.local) + + if (!ipa_get_param_count (info)) + disable = true; + else if (node->local.local) { int caller_count = 0; node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, @@ -1206,32 +1209,72 @@ initialize_node_lattices (struct cgraph_node *node) disable = true; } - for (i = 0; i < ipa_get_param_count (info); i++) + if (dump_file && (dump_flags & TDF_DETAILS) + && !node->alias && !node->thunk.thunk_p) { - class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); - plats->m_value_range.init (); + fprintf (dump_file, "Initializing lattices of %s\n", + node->dump_name ()); + if (disable || variable) + fprintf (dump_file, " Marking all lattices as %s\n", + disable ? "BOTTOM" : "VARIABLE"); } - if (disable || variable) + auto_vec<bool, 16> surviving_params; + bool pre_modified = false; + if (!disable && node->clone.param_adjustments) { - for (i = 0; i < ipa_get_param_count (info); i++) + /* At the moment all IPA optimizations should use the number of + parameters of the prevailing decl as the m_always_copy_start. + Handling any other value would complicate the code below, so for the + time bing let's only assert it is so. */ + gcc_assert ((node->clone.param_adjustments->m_always_copy_start + == ipa_get_param_count (info)) + || node->clone.param_adjustments->m_always_copy_start < 0); + + pre_modified = true; + node->clone.param_adjustments->get_surviving_params (&surviving_params); + + if (dump_file && (dump_flags & TDF_DETAILS) + && !node->alias && !node->thunk.thunk_p) { - class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); - if (disable) + bool first = true; + for (int j = 0; j < ipa_get_param_count (info); j++) { - plats->itself.set_to_bottom (); - plats->ctxlat.set_to_bottom (); - set_agg_lats_to_bottom (plats); - plats->bits_lattice.set_to_bottom (); - plats->m_value_range.set_to_bottom (); + if (j < (int) surviving_params.length () + && surviving_params[j]) + continue; + if (first) + { + fprintf (dump_file, + " The following parameters are dead on arrival:"); + first = false; + } + fprintf (dump_file, " %u", j); } - else + if (!first) + fprintf (dump_file, "\n"); + } + } + + for (i = 0; i < ipa_get_param_count (info); i++) + { + ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); + if (disable + || (pre_modified && (surviving_params.length () <= (unsigned) i + || !surviving_params[i]))) + { + plats->itself.set_to_bottom (); + plats->ctxlat.set_to_bottom (); + set_agg_lats_to_bottom (plats); + plats->bits_lattice.set_to_bottom (); + plats->m_value_range.set_to_bottom (); + } + else + { + plats->m_value_range.init (); + if (variable) set_all_contains_variable (plats); } - if (dump_file && (dump_flags & TDF_DETAILS) - && !node->alias && !node->thunk.thunk_p) - fprintf (dump_file, "Marking all lattices of %s as %s\n", - node->dump_name (), disable ? "BOTTOM" : "VARIABLE"); } for (ie = node->indirect_calls; ie; ie = ie->next_callee) @@ -3654,12 +3697,8 @@ get_replacement_map (class ipa_node_params *info, tree value, int parm_num) print_generic_expr (dump_file, value); fprintf (dump_file, "\n"); } - replace_map->old_tree = NULL; replace_map->parm_num = parm_num; replace_map->new_tree = value; - replace_map->replace_p = true; - replace_map->ref_p = false; - return replace_map; } @@ -3797,6 +3836,35 @@ update_specialized_profile (struct cgraph_node *new_node, dump_profile_updates (orig_node, new_node); } +/* Return true if we would like to remove a parameter from NODE when cloning it + with KNOWN_CSTS scalar constants. */ + +static bool +want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts) +{ + auto_vec<bool, 16> surviving; + bool filled_vec = false; + ipa_node_params *info = IPA_NODE_REF (node); + int i, count = ipa_get_param_count (info); + + for (i = 0; i < count; i++) + { + if (!known_csts[i] && ipa_is_param_used (info, i)) + continue; + + if (!filled_vec) + { + if (!node->clone.param_adjustments) + return true; + node->clone.param_adjustments->get_surviving_params (&surviving); + filled_vec = true; + } + if (surviving.length() < (unsigned) i && surviving[i]) + return true; + } + return false; +} + /* Create a specialized version of NODE with known constants in KNOWN_CSTS, known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and redirect all edges in CALLERS to it. */ @@ -3810,31 +3878,65 @@ create_specialized_node (struct cgraph_node *node, { class ipa_node_params *new_info, *info = IPA_NODE_REF (node); vec<ipa_replace_map *, va_gc> *replace_trees = NULL; + vec<ipa_adjusted_param, va_gc> *new_params = NULL; struct ipa_agg_replacement_value *av; struct cgraph_node *new_node; int i, count = ipa_get_param_count (info); - bitmap args_to_skip; - + ipa_param_adjustments *old_adjustments = node->clone.param_adjustments; + ipa_param_adjustments *new_adjustments; gcc_assert (!info->ipcp_orig_node); + gcc_assert (node->local.can_change_signature + || !old_adjustments); - if (node->local.can_change_signature) + if (old_adjustments) { - args_to_skip = BITMAP_GGC_ALLOC (); - for (i = 0; i < count; i++) + /* At the moment all IPA optimizations should use the number of + parameters of the prevailing decl as the m_always_copy_start. + Handling any other value would complicate the code below, so for the + time bing let's only assert it is so. */ + gcc_assert (old_adjustments->m_always_copy_start == count + || old_adjustments->m_always_copy_start < 0); + int old_adj_count = vec_safe_length (old_adjustments->m_adj_params); + for (i = 0; i < old_adj_count; i++) { - tree t = known_csts[i]; + ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i]; + if (!node->local.can_change_signature + || old_adj->op != IPA_PARAM_OP_COPY + || (!known_csts[old_adj->base_index] + && ipa_is_param_used (info, old_adj->base_index))) + { + ipa_adjusted_param new_adj = *old_adj; - if (t || !ipa_is_param_used (info, i)) - bitmap_set_bit (args_to_skip, i); + new_adj.prev_clone_adjustment = true; + new_adj.prev_clone_index = i; + vec_safe_push (new_params, new_adj); + } } + bool skip_return = old_adjustments->m_skip_return; + new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ()) + ipa_param_adjustments (new_params, count, + skip_return)); } - else + else if (node->local.can_change_signature + && want_remove_some_param_p (node, known_csts)) { - args_to_skip = NULL; - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " cannot change function signature\n"); + ipa_adjusted_param adj; + memset (&adj, 0, sizeof (adj)); + adj.op = IPA_PARAM_OP_COPY; + for (i = 0; i < count; i++) + if (!known_csts[i] && ipa_is_param_used (info, i)) + { + adj.base_index = i; + adj.prev_clone_index = i; + vec_safe_push (new_params, adj); + } + new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ()) + ipa_param_adjustments (new_params, count, false)); } + else + new_adjustments = NULL; + replace_trees = vec_safe_copy (node->clone.tree_map); for (i = 0; i < count; i++) { tree t = known_csts[i]; @@ -3863,7 +3965,7 @@ create_specialized_node (struct cgraph_node *node, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME ( node->decl))); new_node = node->create_virtual_clone (callers, replace_trees, - args_to_skip, "constprop", + new_adjustments, "constprop", suffix_counter); suffix_counter++; |