summaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-02 17:52:18 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-02 17:52:18 +0000
commitc79d6ecf5563140990af3fd6597e57aecefa4f92 (patch)
tree98148830f4cfbf1657daafe9c739844729ce140b /gcc/tree-sra.c
parent2a50bfcf98249aff98c8ad8383d0d419f06fd9b2 (diff)
downloadgcc-c79d6ecf5563140990af3fd6597e57aecefa4f92.tar.gz
2009-09-02 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (struct access): New field grp_hint. (dump_access): Dump grp_hint. (sort_and_splice_var_accesses): Set grp_hint if a group is read multiple times. (analyze_access_subtree): Only scalarize accesses with grp_hint set or those which have been specifically read and somehow written to. (propagate_subacesses_accross_link): Set grp_hint of right child and also possibly of the left child. * testsuite/gcc.dg/tree-ssa/sra-8.c: New testcase. * testsuite/gcc.dg/memcpy-1.c: Add . to match pattern. * testsuite/gcc.dg/uninit-I.c: XFAIL warning test. * testsuite/g++.dg/warn/unit-1.C: XFAIL warning test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151345 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 33be0f6aaca..8d4dc90d179 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -165,6 +165,10 @@ struct access
/* Does this group contain a read access? This flag is propagated down the
access tree. */
unsigned grp_read : 1;
+ /* Other passes of the analysis use this bit to make function
+ analyze_access_subtree create scalar replacements for this group if
+ possible. */
+ unsigned grp_hint : 1;
/* Is the subtree rooted in this access fully covered by scalar
replacements? */
unsigned grp_covered : 1;
@@ -261,12 +265,14 @@ dump_access (FILE *f, struct access *access, bool grp)
fprintf (f, ", type = ");
print_generic_expr (f, access->type, 0);
if (grp)
- fprintf (f, ", grp_write = %d, grp_read = %d, grp_covered = %d, "
- "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
- "grp_partial_lhs = %d, grp_to_be_replaced = %d\n",
- access->grp_write, access->grp_read, access->grp_covered,
- access->grp_unscalarizable_region, access->grp_unscalarized_data,
- access->grp_partial_lhs, access->grp_to_be_replaced);
+ fprintf (f, ", grp_write = %d, grp_read = %d, grp_hint = %d, "
+ "grp_covered = %d, grp_unscalarizable_region = %d, "
+ "grp_unscalarized_data = %d, grp_partial_lhs = %d, "
+ "grp_to_be_replaced = %d\n",
+ access->grp_write, access->grp_read, access->grp_hint,
+ access->grp_covered, access->grp_unscalarizable_region,
+ access->grp_unscalarized_data, access->grp_partial_lhs,
+ access->grp_to_be_replaced);
else
fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
access->grp_partial_lhs);
@@ -1203,8 +1209,9 @@ sort_and_splice_var_accesses (tree var)
while (i < access_count)
{
struct access *access = VEC_index (access_p, access_vec, i);
- bool modification = access->write;
+ bool grp_write = access->write;
bool grp_read = !access->write;
+ bool multiple_reads = false;
bool grp_partial_lhs = access->grp_partial_lhs;
bool first_scalar = is_gimple_reg_type (access->type);
bool unscalarizable_region = access->grp_unscalarizable_region;
@@ -1227,8 +1234,15 @@ sort_and_splice_var_accesses (tree var)
struct access *ac2 = VEC_index (access_p, access_vec, j);
if (ac2->offset != access->offset || ac2->size != access->size)
break;
- modification |= ac2->write;
- grp_read |= !ac2->write;
+ if (ac2->write)
+ grp_write = true;
+ else
+ {
+ if (grp_read)
+ multiple_reads = true;
+ else
+ grp_read = true;
+ }
grp_partial_lhs |= ac2->grp_partial_lhs;
unscalarizable_region |= ac2->grp_unscalarizable_region;
relink_to_new_repr (access, ac2);
@@ -1244,8 +1258,9 @@ sort_and_splice_var_accesses (tree var)
i = j;
access->group_representative = access;
- access->grp_write = modification;
+ access->grp_write = grp_write;
access->grp_read = grp_read;
+ access->grp_hint = multiple_reads;
access->grp_partial_lhs = grp_partial_lhs;
access->grp_unscalarizable_region = unscalarizable_region;
if (access->first_link)
@@ -1377,6 +1392,7 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
HOST_WIDE_INT covered_to = root->offset;
bool scalar = is_gimple_reg_type (root->type);
bool hole = false, sth_created = false;
+ bool direct_read = root->grp_read;
if (mark_read)
root->grp_read = true;
@@ -1405,7 +1421,9 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
hole |= !child->grp_covered;
}
- if (allow_replacements && scalar && !root->first_child)
+ if (allow_replacements && scalar && !root->first_child
+ && (root->grp_hint
+ || (direct_read && root->grp_write)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -1543,7 +1561,6 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
{
struct access *rchild;
HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
-
bool ret = false;
if (is_gimple_reg_type (lacc->type)
@@ -1570,8 +1587,13 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
&new_acc))
{
- if (new_acc && rchild->first_child)
- ret |= propagate_subacesses_accross_link (new_acc, rchild);
+ if (new_acc)
+ {
+ rchild->grp_hint = 1;
+ new_acc->grp_hint |= new_acc->grp_read;
+ if (rchild->first_child)
+ ret |= propagate_subacesses_accross_link (new_acc, rchild);
+ }
continue;
}
@@ -1582,6 +1604,7 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
rchild->type, false))
continue;
+ rchild->grp_hint = 1;
new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
if (racc->first_child)
propagate_subacesses_accross_link (new_acc, rchild);