summaryrefslogtreecommitdiff
path: root/gcc/ipa-cp.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2019-09-20 00:25:04 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2019-09-20 00:25:04 +0200
commitff6686d2e5f797d6c6a36ad14a7084bc1dc350e4 (patch)
tree21de4e26dd766dab8b60b2be7190a6b86bad2b38 /gcc/ipa-cp.c
parent6889a3acfeed47265886676c6d43b04ef799fb82 (diff)
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.c172
1 files changed, 137 insertions, 35 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 33d52fe5537..b4fb74e097e 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++;