aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraphclones.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/cgraphclones.c
parent6889a3acfeed47265886676c6d43b04ef799fb82 (diff)
downloadgcc-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/cgraphclones.c')
-rw-r--r--gcc/cgraphclones.c213
1 files changed, 50 insertions, 163 deletions
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index fa75369..909407b 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -142,96 +142,6 @@ cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid,
return new_edge;
}
-/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
- return value if SKIP_RETURN is true. */
-
-tree
-cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
- bool skip_return)
-{
- tree new_type = NULL;
- tree args, new_args = NULL;
- tree new_reversed;
- int i = 0;
-
- for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node;
- args = TREE_CHAIN (args), i++)
- if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
- new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args);
-
- new_reversed = nreverse (new_args);
- if (args)
- {
- if (new_reversed)
- TREE_CHAIN (new_args) = void_list_node;
- else
- new_reversed = void_list_node;
- }
-
- /* Use copy_node to preserve as much as possible from original type
- (debug info, attribute lists etc.)
- Exception is METHOD_TYPEs must have THIS argument.
- When we are asked to remove it, we need to build new FUNCTION_TYPE
- instead. */
- if (TREE_CODE (orig_type) != METHOD_TYPE
- || !args_to_skip
- || !bitmap_bit_p (args_to_skip, 0))
- {
- new_type = build_distinct_type_copy (orig_type);
- TYPE_ARG_TYPES (new_type) = new_reversed;
- }
- else
- {
- new_type
- = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
- new_reversed));
- TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
- }
-
- if (skip_return)
- TREE_TYPE (new_type) = void_type_node;
-
- return new_type;
-}
-
-/* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the
- return value if SKIP_RETURN is true.
-
- Arguments from DECL_ARGUMENTS list can't be removed now, since they are
- linked by TREE_CHAIN directly. The caller is responsible for eliminating
- them when they are being duplicated (i.e. copy_arguments_for_versioning). */
-
-static tree
-build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
- bool skip_return)
-{
- tree new_decl = copy_node (orig_decl);
- tree new_type;
-
- new_type = TREE_TYPE (orig_decl);
- if (prototype_p (new_type)
- || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type))))
- new_type
- = cgraph_build_function_type_skip_args (new_type, args_to_skip,
- skip_return);
- TREE_TYPE (new_decl) = new_type;
-
- /* For declarations setting DECL_VINDEX (i.e. methods)
- we expect first argument to be THIS pointer. */
- if (args_to_skip && bitmap_bit_p (args_to_skip, 0))
- DECL_VINDEX (new_decl) = NULL_TREE;
-
- /* When signature changes, we need to clear builtin info. */
- if (fndecl_built_in_p (new_decl)
- && args_to_skip
- && !bitmap_empty_p (args_to_skip))
- set_decl_built_in_function (new_decl, NOT_BUILT_IN, 0);
- /* The FE might have information and assumptions about the other
- arguments. */
- DECL_LANG_SPECIFIC (new_decl) = NULL;
- return new_decl;
-}
-
/* Set flags of NEW_NODE and its decl. NEW_NODE is a newly created private
clone or its thunk. */
@@ -281,35 +191,21 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
return cs->caller;
tree new_decl;
- if (!node->clone.args_to_skip)
- new_decl = copy_node (thunk->decl);
- else
+ if (node->clone.param_adjustments)
{
/* We do not need to duplicate this_adjusting thunks if we have removed
this. */
if (thunk->thunk.this_adjusting
- && bitmap_bit_p (node->clone.args_to_skip, 0))
+ && !node->clone.param_adjustments->first_param_intact_p ())
return node;
- new_decl = build_function_decl_skip_args (thunk->decl,
- node->clone.args_to_skip,
- false);
- }
-
- tree *link = &DECL_ARGUMENTS (new_decl);
- int i = 0;
- for (tree pd = DECL_ARGUMENTS (thunk->decl); pd; pd = DECL_CHAIN (pd), i++)
- {
- if (!node->clone.args_to_skip
- || !bitmap_bit_p (node->clone.args_to_skip, i))
- {
- tree nd = copy_node (pd);
- DECL_CONTEXT (nd) = new_decl;
- *link = nd;
- link = &DECL_CHAIN (nd);
- }
+ new_decl = copy_node (thunk->decl);
+ ipa_param_body_adjustments body_adj (node->clone.param_adjustments,
+ new_decl);
+ body_adj.modify_formal_parameters ();
}
- *link = NULL_TREE;
+ else
+ new_decl = copy_node (thunk->decl);
gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl));
gcc_checking_assert (!DECL_INITIAL (new_decl));
@@ -331,8 +227,7 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
new_thunk->thunk = thunk->thunk;
new_thunk->unique_name = in_lto_p;
new_thunk->former_clone_of = thunk->decl;
- new_thunk->clone.args_to_skip = node->clone.args_to_skip;
- new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip;
+ new_thunk->clone.param_adjustments = node->clone.param_adjustments;
cgraph_edge *e = new_thunk->create_edge (node, NULL, new_thunk->count);
symtab->call_edge_duplication_hooks (thunk->callees, e);
@@ -415,7 +310,11 @@ dump_callgraph_transformation (const cgraph_node *original,
If the new node is being inlined into another one, NEW_INLINED_TO should be
the outline function the new one is (even indirectly) inlined to. All hooks
will see this in node's global.inlined_to, when invoked. Can be NULL if the
- node is not inlined. */
+ node is not inlined.
+
+ If PARAM_ADJUSTMENTS is non-NULL, the parameter manipulation information
+ will be overwritten by the new structure. Otherwise the new node will
+ share parameter manipulation information with the original node. */
cgraph_node *
cgraph_node::create_clone (tree new_decl, profile_count prof_count,
@@ -423,7 +322,8 @@ cgraph_node::create_clone (tree new_decl, profile_count prof_count,
vec<cgraph_edge *> redirect_callers,
bool call_duplication_hook,
cgraph_node *new_inlined_to,
- bitmap args_to_skip, const char *suffix)
+ ipa_param_adjustments *param_adjustments,
+ const char *suffix)
{
cgraph_node *new_node = symtab->create_empty ();
cgraph_edge *e;
@@ -467,19 +367,13 @@ cgraph_node::create_clone (tree new_decl, profile_count prof_count,
new_node->merged_comdat = merged_comdat;
new_node->thunk = thunk;
+ if (param_adjustments)
+ new_node->clone.param_adjustments = param_adjustments;
+ else
+ new_node->clone.param_adjustments = clone.param_adjustments;
new_node->clone.tree_map = NULL;
- new_node->clone.args_to_skip = args_to_skip;
+ new_node->clone.performed_splits = vec_safe_copy (clone.performed_splits);
new_node->split_part = split_part;
- if (!args_to_skip)
- new_node->clone.combined_args_to_skip = clone.combined_args_to_skip;
- else if (clone.combined_args_to_skip)
- {
- new_node->clone.combined_args_to_skip = BITMAP_GGC_ALLOC ();
- bitmap_ior (new_node->clone.combined_args_to_skip,
- clone.combined_args_to_skip, args_to_skip);
- }
- else
- new_node->clone.combined_args_to_skip = args_to_skip;
FOR_EACH_VEC_ELT (redirect_callers, i, e)
{
@@ -621,8 +515,8 @@ clone_function_name (tree decl, const char *suffix)
cgraph_node *
cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
vec<ipa_replace_map *, va_gc> *tree_map,
- bitmap args_to_skip, const char * suffix,
- unsigned num_suffix)
+ ipa_param_adjustments *param_adjustments,
+ const char * suffix, unsigned num_suffix)
{
tree old_decl = decl;
cgraph_node *new_node = NULL;
@@ -632,13 +526,16 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
char *name;
gcc_checking_assert (local.versionable);
- gcc_assert (local.can_change_signature || !args_to_skip);
+ /* TODO: It would be nice if we could recognize that param_adjustments do not
+ actually perform any changes, but at the moment let's require it simply
+ does not exist. */
+ gcc_assert (local.can_change_signature || !param_adjustments);
/* Make a new FUNCTION_DECL tree node */
- if (!args_to_skip)
+ if (!param_adjustments)
new_decl = copy_node (old_decl);
else
- new_decl = build_function_decl_skip_args (old_decl, args_to_skip, false);
+ new_decl = param_adjustments->adjust_decl (old_decl);
/* These pointers represent function body and will be populated only when clone
is materialized. */
@@ -662,7 +559,8 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
SET_DECL_RTL (new_decl, NULL);
new_node = create_clone (new_decl, count, false,
- redirect_callers, false, NULL, args_to_skip, suffix);
+ redirect_callers, false, NULL, param_adjustments,
+ suffix);
/* Update the properties.
Make clone visible only within this translation unit. Make sure
@@ -1021,9 +919,10 @@ cgraph_node::create_version_clone (tree new_decl,
cgraph_node *
cgraph_node::create_version_clone_with_body
(vec<cgraph_edge *> redirect_callers,
- vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip,
- bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block,
- const char *suffix, tree target_attributes)
+ vec<ipa_replace_map *, va_gc> *tree_map,
+ ipa_param_adjustments *param_adjustments,
+ bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix,
+ tree target_attributes)
{
tree old_decl = decl;
cgraph_node *new_version_node = NULL;
@@ -1032,14 +931,16 @@ cgraph_node::create_version_clone_with_body
if (!tree_versionable_function_p (old_decl))
return NULL;
- gcc_assert (local.can_change_signature || !args_to_skip);
+ /* TODO: Restore an assert that we do not change signature if
+ local.can_change_signature is false. We cannot just check that
+ param_adjustments is NULL because unfortunately ipa-split removes return
+ values from such functions. */
/* Make a new FUNCTION_DECL tree node for the new version. */
- if (!args_to_skip && !skip_return)
- new_decl = copy_node (old_decl);
+ if (param_adjustments)
+ new_decl = param_adjustments->adjust_decl (old_decl);
else
- new_decl
- = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
+ new_decl = copy_node (old_decl);
/* Generate a new name for the new version. */
DECL_NAME (new_decl) = clone_function_name_numbered (old_decl, suffix);
@@ -1076,8 +977,8 @@ cgraph_node::create_version_clone_with_body
new_version_node->ipa_transforms_to_apply
= ipa_transforms_to_apply.copy ();
/* Copy the OLD_VERSION_NODE function tree to the new version. */
- tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
- skip_return, bbs_to_copy, new_entry_block);
+ tree_function_versioning (old_decl, new_decl, tree_map, param_adjustments,
+ false, bbs_to_copy, new_entry_block);
/* Update the new version's properties.
Make The new version visible only within this translation unit. Make sure
@@ -1117,9 +1018,8 @@ cgraph_materialize_clone (cgraph_node *node)
node->former_clone_of = node->clone_of->former_clone_of;
/* Copy the OLD_VERSION_NODE function tree to the new version. */
tree_function_versioning (node->clone_of->decl, node->decl,
- node->clone.tree_map, true,
- node->clone.args_to_skip, false,
- NULL, NULL);
+ node->clone.tree_map, node->clone.param_adjustments,
+ true, NULL, NULL);
if (symtab->dump_file)
{
dump_function_to_file (node->clone_of->decl, symtab->dump_file,
@@ -1194,28 +1094,15 @@ symbol_table::materialize_all_clones (void)
{
ipa_replace_map *replace_info;
replace_info = (*node->clone.tree_map)[i];
- print_generic_expr (symtab->dump_file,
- replace_info->old_tree);
- fprintf (symtab->dump_file, " -> ");
+ fprintf (symtab->dump_file, "%i -> ",
+ (*node->clone.tree_map)[i]->parm_num);
print_generic_expr (symtab->dump_file,
replace_info->new_tree);
- fprintf (symtab->dump_file, "%s%s;",
- replace_info->replace_p ? "(replace)":"",
- replace_info->ref_p ? "(ref)":"");
}
fprintf (symtab->dump_file, "\n");
}
- if (node->clone.args_to_skip)
- {
- fprintf (symtab->dump_file, " args_to_skip: ");
- dump_bitmap (symtab->dump_file,
- node->clone.args_to_skip);
- }
- if (node->clone.args_to_skip)
- {
- fprintf (symtab->dump_file, " combined_args_to_skip:");
- dump_bitmap (symtab->dump_file, node->clone.combined_args_to_skip);
- }
+ if (node->clone.param_adjustments)
+ node->clone.param_adjustments->dump (symtab->dump_file);
}
cgraph_materialize_clone (node);
stabilized = false;