From e750838754c5243aa12a0afee22b9f8e831a2262 Mon Sep 17 00:00:00 2001 From: Olga Golovanevsky Date: Fri, 26 Feb 2016 19:01:29 -0800 Subject: Decompose function parameters: patch 7 --- gcc/cgraph.h | 11 ++++++++ gcc/cgraphclones.c | 59 +++++++++++++++++++++++++++++++++++----- gcc/ipa-prop.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++-------- gcc/lto-cgraph.c | 34 ++++++++++++++++++++++- gcc/tree-inline.c | 9 +++--- 5 files changed, 170 insertions(+), 23 deletions(-) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index c1c744bc3d2..7e6efd6b730 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -254,6 +254,14 @@ struct GTY(()) ipa_replace_map typedef struct ipa_replace_map *ipa_replace_map_p; +#define MAX_PARMS_TO_DECOMPOSE 20 +struct GTY(()) parms_added +{ + unsigned num; + int parms[MAX_PARMS_TO_DECOMPOSE]; +}; +typedef parms_added *parms_added_p; + struct GTY(()) cgraph_clone_info { vec *tree_map; @@ -263,6 +271,9 @@ struct GTY(()) cgraph_clone_info vec *combined_args_to_skip; bitmap args_to_decompose; vec *combined_args_to_decompose; + /* Number parameters added before those who will be decomposed. + We need it for adjusting aggregate replacements in ipcp transform. */ + vec *combined_parms_added; }; enum cgraph_simd_clone_arg_type diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 06613ef39ae..2fe507934c3 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -383,12 +383,14 @@ strip_type (tree type) static tree build_function_type_skip_decomp_args (tree orig_type, bitmap args_to_skip, - bitmap args_to_decompose, bool skip_return) + bitmap args_to_decompose, + parms_added_p parms, bool skip_return) { tree new_type = NULL; tree args, new_args = NULL, t; tree new_reversed; int i = 0; + unsigned j = 0; for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node; args = TREE_CHAIN (args), i++) @@ -398,6 +400,7 @@ build_function_type_skip_decomp_args (tree orig_type, bitmap args_to_skip, tree type = TREE_VALUE (args); tree stype = strip_type (type); tree t; + int num_new_parms = 0; gcc_assert (TREE_CODE (stype) == RECORD_TYPE); for (t = TYPE_FIELDS (stype); t; t = TREE_CHAIN (t)) @@ -405,12 +408,17 @@ build_function_type_skip_decomp_args (tree orig_type, bitmap args_to_skip, tree ntype = wrap_new_type (type, TREE_TYPE (t)); new_args = tree_cons (NULL_TREE, ntype, new_args); + num_new_parms++; } + parms->parms[j] = num_new_parms; + j++; } if (!args_to_skip || !bitmap_bit_p (args_to_skip, i)) new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args); } + if (parms) + gcc_assert (j == parms->num); new_reversed = nreverse (new_args); if (args) { @@ -451,7 +459,8 @@ build_function_type_skip_decomp_args (tree orig_type, bitmap args_to_skip, if (t != orig_type) { t = build_function_type_skip_decomp_args (t, args_to_skip, - args_to_decompose, skip_return); + args_to_decompose, + parms, skip_return); TYPE_MAIN_VARIANT (new_type) = t; TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t); TYPE_NEXT_VARIANT (t) = new_type; @@ -474,7 +483,8 @@ build_function_type_skip_decomp_args (tree orig_type, bitmap args_to_skip, static tree build_function_decl_skip_decomp_args (tree orig_decl, bitmap args_to_skip, - bitmap args_to_decompose, bool skip_return) + bitmap args_to_decompose, + parms_added_p parms, bool skip_return) { tree new_decl = copy_node (orig_decl); tree new_type; @@ -483,8 +493,8 @@ build_function_decl_skip_decomp_args (tree orig_decl, bitmap args_to_skip, if (prototype_p (new_type) || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type)))) new_type - = build_function_type_skip_decomp_args (new_type, args_to_skip, - args_to_decompose, skip_return); + = build_function_type_skip_decomp_args (new_type, args_to_skip, args_to_decompose, + parms, skip_return); TREE_TYPE (new_decl) = new_type; /* For declarations setting DECL_VINDEX (i.e. methods) @@ -526,9 +536,26 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, tree new_decl; size_t len, i; struct ipa_replace_map *map; - char *name; + char *name; + parms_added_p parms; + bitmap_iterator bi; + unsigned int index; + unsigned int size = 0; + parms = ggc_alloc_parms_added (); + /* The size of parms_added vector is equal to number of fields to decompose. */ + if (args_to_decompose) + { + EXECUTE_IF_SET_IN_BITMAP (args_to_decompose, 0, index, bi) + size++; + parms->num = size; + } + else + parms->num = 0; + + gcc_assert (size <= MAX_PARMS_TO_DECOMPOSE); + if (!in_lto_p) gcc_checking_assert (tree_versionable_function_p (old_decl)); @@ -542,6 +569,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, new_decl = build_function_decl_skip_decomp_args (old_decl, args_to_skip, args_to_decompose, + parms, false); /* These pointers represent function body and will be populated only when clone @@ -602,6 +630,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, if (args_to_skip) { vec_safe_push (new_node->clone.combined_args_to_skip, args_to_skip); + vec_safe_push (new_node->clone.combined_parms_added, parms); if (!args_to_decompose) { bitmap tmp = BITMAP_GGC_ALLOC (); @@ -613,6 +642,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, if (args_to_decompose) { vec_safe_push (new_node->clone.combined_args_to_decompose, args_to_decompose); + vec_safe_push (new_node->clone.combined_parms_added, parms); if (!args_to_skip) { bitmap tmp = BITMAP_GGC_ALLOC (); @@ -658,6 +688,21 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, dump_bitmap (stderr, bm); } } + if (new_node->clone.combined_parms_added) + { + int j; + unsigned k; + parms_added_p parms; + + fprintf (stderr, " combined_parms_added: \n"); + FOR_EACH_VEC_SAFE_ELT (new_node->clone.combined_parms_added, j, parms) + { + fprintf (stderr, "num %d; ", parms->num); + for (k = 0; k < parms->num; k++) + fprintf (stderr, "%d ", parms->parms[k]); + fprintf (stderr, "\n"); + } + } new_node->externally_visible = 0; new_node->local.local = 1; @@ -1015,7 +1060,7 @@ cgraph_function_versioning (struct cgraph_node *old_version_node, else new_decl = build_function_decl_skip_decomp_args (old_decl, args_to_skip, - NULL, skip_return); + NULL, NULL, skip_return); /* Generate a new name for the new version. */ DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 9f144fa3442..19a44fb0af3 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -4793,31 +4793,89 @@ adjust_agg_replacement_values (struct cgraph_node *node, struct ipa_agg_replacement_value *aggval) { struct ipa_agg_replacement_value *v; - int i, c = 0, d = 0, *adj; + int *adj; + unsigned j, i, c=0; - if (!node->clone.combined_args_to_skip) + fprintf (stderr, "\nAt the beginning of adjust_agg.\n"); + if (!node->clone.combined_args_to_skip + && !node->clone.combined_args_to_decompose) return; for (v = aggval; v; v = v->next) { gcc_assert (v->index >= 0); - if (c < v->index) + if (c < (unsigned)v->index) c = v->index; } c++; + + gcc_assert (vec_safe_length (node->clone.combined_args_to_skip) + == vec_safe_length (node->clone.combined_args_to_decompose)); + gcc_assert (vec_safe_length (node->clone.combined_args_to_skip) + == vec_safe_length (node->clone.combined_parms_added)); adj = XALLOCAVEC (int, c); + + /* Initial mapping. */ for (i = 0; i < c; i++) - if (bitmap_bit_p (node->clone.combined_args_to_skip, i)) - { - adj[i] = -1; - d++; - } - else - adj[i] = i - d; + adj[i] = i; + + for (j = 0; j < vec_safe_length (node->clone.combined_args_to_skip); j++) + { + bitmap skip = (*node->clone.combined_args_to_skip)[j]; + bitmap decomp = (*node->clone.combined_args_to_decompose)[j]; + parms_added_p parms = (*node->clone.combined_parms_added)[j]; + int k = 0; + unsigned n_skip = bitmap_last_set_bit (skip); + unsigned n_decomp = bitmap_last_set_bit (decomp); + unsigned n = (n_skip > n_decomp) ? n_skip : n_decomp; + int * shift = XALLOCAVEC (int, n); + int * kill = XALLOCAVEC (int, n); + int d = 0; + + for (i = 0; i < n; i++) + { + shift[i] = 0; + kill[i] = 0; + } + + for (i = 0; i < n; i++) + { + if (bitmap_bit_p (decomp, i)) + { + d += parms->parms[k]; + k++; + } + shift[i] = d; + if (bitmap_bit_p (skip, i)) + { + d--; + kill[i] = 1; + } + } + shift[n-1] = d; + + /* Update adjustments. */ + for (i = 0; i < c; i++) + { + int a = adj[i]; + if (a != -1) /* i was not skipped */ + { + if ((unsigned)a >= n) + adj[i] += shift[n-1]; + else + { + if (kill[a]) + adj[i] = -1; + else + adj[i] += shift[a]; + } + } + } + } for (v = aggval; v; v = v->next) - v->index = adj[v->index]; + v->index = adj[v->index]; } diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 915450219f4..ab0b1af1049 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -1629,7 +1629,8 @@ output_cgraph_opt_summary_p (struct cgraph_node *node) || node->clone.args_to_skip || node->clone.combined_args_to_skip || node->clone.args_to_decompose - || node->clone.combined_args_to_decompose)); + || node->clone.combined_args_to_decompose + || node->clone.combined_parms_added)); } /* Output optimization summary for EDGE to OB. */ @@ -1694,6 +1695,21 @@ output_node_opt_summary (struct output_block *ob, } else streamer_write_uhwi (ob, 0); + if (node->clone.combined_parms_added) + { + parms_added_p parms; + unsigned j; + + streamer_write_uhwi (ob, vec_safe_length (node->clone.combined_parms_added)); + FOR_EACH_VEC_SAFE_ELT (node->clone.combined_parms_added, i, parms) + { + streamer_write_uhwi (ob, parms->num); + for (j=0; j < parms->num; j++) + streamer_write_uhwi (ob, parms->parms[j]); + } + } + else + streamer_write_uhwi (ob, 0); streamer_write_uhwi (ob, vec_safe_length (node->clone.tree_map)); FOR_EACH_VEC_SAFE_ELT (node->clone.tree_map, i, map) { @@ -1826,6 +1842,22 @@ input_node_opt_summary (struct cgraph_node *node, } } count = streamer_read_uhwi (ib_main); + node->clone.combined_parms_added = NULL; + if (count) + { + for (i = 0; i < count; i++) + { + parms_added_p parms = ggc_alloc_parms_added (); + unsigned len = streamer_read_uhwi (ib_main); + unsigned k; + parms->num = len; + + vec_safe_push (node->clone.combined_parms_added, parms); + for (k = 0; k < len; k++) + parms->parms[k] = streamer_read_uhwi (ib_main); + } + } + count = streamer_read_uhwi (ib_main); for (i = 0; i < count; i++) { struct ipa_replace_map *map = ggc_alloc_ipa_replace_map (); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index a945c62ad42..4459febf5cd 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -5095,11 +5095,11 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id, tree new_parm = NULL, ntype; int i; - i = 0; /* dst_fc is a new function declaration, that already defines new types of parameters. */ ntype = TYPE_ARG_TYPES (TREE_TYPE((*id).dst_fn)); + parg = &new_parm; for (arg = orig_parm; arg; arg = DECL_CHAIN (arg), i++) { @@ -5116,7 +5116,6 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id, arg_name = IDENTIFIER_POINTER (DECL_NAME (arg)); for (t = TYPE_FIELDS (stype); t; t = TREE_CHAIN (t)) { - //debug_tree (TREE_VALUE (ntype)); field_name = IDENTIFIER_POINTER (DECL_NAME (t)); sprintf (buf, "%s.%s", arg_name, field_name); parm_name = get_identifier (buf); @@ -5125,7 +5124,8 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id, lang_hooks.dup_lang_specific_decl (parm_decl); *parg = parm_decl; parg = &DECL_CHAIN (parm_decl); - ntype = TREE_CHAIN (ntype); + if (ntype && ntype != void_list_node) + ntype = TREE_CHAIN (ntype); } } if (!args_to_skip || !bitmap_bit_p (args_to_skip, i)) @@ -5138,7 +5138,8 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id, lang_hooks.dup_lang_specific_decl (new_tree); *parg = new_tree; parg = &DECL_CHAIN (new_tree); - ntype = TREE_CHAIN (ntype); + if (ntype && ntype != void_list_node) + ntype = TREE_CHAIN (ntype); } else if (!pointer_map_contains (id->decl_map, arg)) { -- cgit v1.2.1