summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlga Golovanevsky <root@ogolovanevsky-lnx.caveonetworks.com>2016-02-26 19:01:29 -0800
committerOlga Golovanevsky <root@ogolovanevsky-lnx.caveonetworks.com>2016-02-26 19:01:29 -0800
commite750838754c5243aa12a0afee22b9f8e831a2262 (patch)
tree3b03597f6bd113992e81c06c623104a44fc21962
parenta318fed90d8b0c48cc0335e389e1ae08055d1e8e (diff)
downloadgcc-apinski/struct-reorg-4.9.tar.gz
Decompose function parameters: patch 7apinski/struct-reorg-4.9
-rw-r--r--gcc/cgraph.h11
-rw-r--r--gcc/cgraphclones.c59
-rw-r--r--gcc/ipa-prop.c80
-rw-r--r--gcc/lto-cgraph.c34
-rw-r--r--gcc/tree-inline.c9
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<ipa_replace_map_p, va_gc> *tree_map;
@@ -263,6 +271,9 @@ struct GTY(()) cgraph_clone_info
vec<bitmap, va_gc> *combined_args_to_skip;
bitmap args_to_decompose;
vec<bitmap, va_gc> *combined_args_to_decompose;
+ /* Number parameters added before those who will be decomposed.
+ We need it for adjusting aggregate replacements in ipcp transform. */
+ vec<parms_added_p, va_gc> *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))
{