Commit 2bba7541 by Martin Jambor Committed by Martin Jambor

[PR 78687] Set SRA grp_write lazily

2017-05-02  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/78687
	* tree-sra.c (access): New field parent.
	(process_subtree_disqualification): New function.
	(disqualify_candidate): Call it.
	(build_accesses_from_assign): Reset write flag if creating an
	assighnment link.
	(build_access_subtree): Fill in parent field and also prpagate
	down grp_write flag.
	(create_artificial_child_access): New parameter set_grp_write, set
	grp_write to its value.
	(propagate_subaccesses_across_link): Also propagate grp_write flag
	values.
	(propagate_all_subaccesses): Push the closest parent back to work
	queue if add_access_to_work_queue returned true.

testsuite/
	* g++.dg/tree-ssa/pr78687.C: New test.

From-SVN: r247497
parent 2bf54d93
2017-05-02 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/78687
* tree-sra.c (access): New field parent.
(process_subtree_disqualification): New function.
(disqualify_candidate): Call it.
(build_accesses_from_assign): Reset write flag if creating an
assighnment link.
(build_access_subtree): Fill in parent field and also prpagate
down grp_write flag.
(create_artificial_child_access): New parameter set_grp_write, set
grp_write to its value.
(propagate_subaccesses_across_link): Also propagate grp_write flag
values.
(propagate_all_subaccesses): Push the closest parent back to work
queue if add_access_to_work_queue returned true.
2017-05-02 Richard Biener <rguenther@suse.de> 2017-05-02 Richard Biener <rguenther@suse.de>
* common.opt (fstrict-overflow): Alias negative to fwrapv. * common.opt (fstrict-overflow): Alias negative to fwrapv.
......
2017-05-02 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/78687
* g++.dg/tree-ssa/pr78687.C: New test.
2017-05-02 Richard Biener <rguenther@suse.de> 2017-05-02 Richard Biener <rguenther@suse.de>
* c-c++-common/Wlogical-op-1.c: Add -fwrapv to restore previous * c-c++-common/Wlogical-op-1.c: Add -fwrapv to restore previous
......
...@@ -158,6 +158,10 @@ struct access ...@@ -158,6 +158,10 @@ struct access
the representative. */ the representative. */
struct access *group_representative; struct access *group_representative;
/* After access tree has been constructed, this points to the parent of the
current access, if there is one. NULL for roots. */
struct access *parent;
/* If this access has any children (in terms of the definition above), this /* If this access has any children (in terms of the definition above), this
points to the first one. */ points to the first one. */
struct access *first_child; struct access *first_child;
...@@ -690,6 +694,19 @@ static bool constant_decl_p (tree decl) ...@@ -690,6 +694,19 @@ static bool constant_decl_p (tree decl)
return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl); return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl);
} }
/* Mark LHS of assign links out of ACCESS and its children as written to. */
static void
process_subtree_disqualification (struct access *access)
{
struct access *child;
for (struct assign_link *link = access->first_link; link; link = link->next)
link->lacc->grp_write = true;
for (child = access->first_child; child; child = child->next_sibling)
process_subtree_disqualification (child);
}
/* Remove DECL from candidates for SRA and write REASON to the dump file if /* Remove DECL from candidates for SRA and write REASON to the dump file if
there is one. */ there is one. */
static void static void
...@@ -706,6 +723,13 @@ disqualify_candidate (tree decl, const char *reason) ...@@ -706,6 +723,13 @@ disqualify_candidate (tree decl, const char *reason)
print_generic_expr (dump_file, decl, 0); print_generic_expr (dump_file, decl, 0);
fprintf (dump_file, " - %s\n", reason); fprintf (dump_file, " - %s\n", reason);
} }
struct access *access = get_first_repr_for_decl (decl);
while (access)
{
process_subtree_disqualification (access);
access = access->next_grp;
}
} }
/* Return true iff the type contains a field or an element which does not allow /* Return true iff the type contains a field or an element which does not allow
...@@ -1338,8 +1362,10 @@ build_accesses_from_assign (gimple *stmt) ...@@ -1338,8 +1362,10 @@ build_accesses_from_assign (gimple *stmt)
link->lacc = lacc; link->lacc = lacc;
link->racc = racc; link->racc = racc;
add_link_to_rhs (racc, link); add_link_to_rhs (racc, link);
/* Let's delay marking the areas as written until propagation of accesses
across link. */
lacc->write = false;
} }
return lacc || racc; return lacc || racc;
...@@ -2252,6 +2278,8 @@ build_access_subtree (struct access **access) ...@@ -2252,6 +2278,8 @@ build_access_subtree (struct access **access)
else else
last_child->next_sibling = *access; last_child->next_sibling = *access;
last_child = *access; last_child = *access;
(*access)->parent = root;
(*access)->grp_write |= root->grp_write;
if (!build_access_subtree (access)) if (!build_access_subtree (access))
return false; return false;
...@@ -2495,13 +2523,15 @@ child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset, ...@@ -2495,13 +2523,15 @@ child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
/* Create a new child access of PARENT, with all properties just like MODEL /* Create a new child access of PARENT, with all properties just like MODEL
except for its offset and with its grp_write false and grp_read true. except for its offset and with its grp_write false and grp_read true.
Return the new access or NULL if it cannot be created. Note that this access Return the new access or NULL if it cannot be created. Note that this
is created long after all splicing and sorting, it's not located in any access is created long after all splicing and sorting, it's not located in
access vector and is automatically a representative of its group. */ any access vector and is automatically a representative of its group. Set
the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
static struct access * static struct access *
create_artificial_child_access (struct access *parent, struct access *model, create_artificial_child_access (struct access *parent, struct access *model,
HOST_WIDE_INT new_offset) HOST_WIDE_INT new_offset,
bool set_grp_write)
{ {
struct access **child; struct access **child;
tree expr = parent->base; tree expr = parent->base;
...@@ -2523,7 +2553,7 @@ create_artificial_child_access (struct access *parent, struct access *model, ...@@ -2523,7 +2553,7 @@ create_artificial_child_access (struct access *parent, struct access *model,
access->offset = new_offset; access->offset = new_offset;
access->size = model->size; access->size = model->size;
access->type = model->type; access->type = model->type;
access->grp_write = true; access->grp_write = set_grp_write;
access->grp_read = false; access->grp_read = false;
access->reverse = model->reverse; access->reverse = model->reverse;
...@@ -2549,10 +2579,23 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc) ...@@ -2549,10 +2579,23 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
HOST_WIDE_INT norm_delta = lacc->offset - racc->offset; HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
bool ret = false; bool ret = false;
/* IF the LHS is still not marked as being written to, we only need to do so
if the RHS at this level actually was. */
if (!lacc->grp_write &&
(racc->grp_write || TREE_CODE (racc->base) == PARM_DECL))
{
lacc->grp_write = true;
ret = true;
}
if (is_gimple_reg_type (lacc->type) if (is_gimple_reg_type (lacc->type)
|| lacc->grp_unscalarizable_region || lacc->grp_unscalarizable_region
|| racc->grp_unscalarizable_region) || racc->grp_unscalarizable_region)
return false; {
ret |= !lacc->grp_write;
lacc->grp_write = true;
return ret;
}
if (is_gimple_reg_type (racc->type)) if (is_gimple_reg_type (racc->type))
{ {
...@@ -2572,7 +2615,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc) ...@@ -2572,7 +2615,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
lacc->grp_no_warning = true; lacc->grp_no_warning = true;
} }
} }
return false; return ret;
} }
for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling) for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
...@@ -2581,23 +2624,37 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc) ...@@ -2581,23 +2624,37 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
HOST_WIDE_INT norm_offset = rchild->offset + norm_delta; HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
if (rchild->grp_unscalarizable_region) if (rchild->grp_unscalarizable_region)
continue; {
lacc->grp_write = true;
continue;
}
if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size, if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
&new_acc)) &new_acc))
{ {
if (new_acc) if (new_acc)
{ {
if (!new_acc->grp_write
&& (lacc->grp_write || rchild->grp_write))
{
new_acc ->grp_write = true;
ret = true;
}
rchild->grp_hint = 1; rchild->grp_hint = 1;
new_acc->grp_hint |= new_acc->grp_read; new_acc->grp_hint |= new_acc->grp_read;
if (rchild->first_child) if (rchild->first_child)
ret |= propagate_subaccesses_across_link (new_acc, rchild); ret |= propagate_subaccesses_across_link (new_acc, rchild);
} }
else
lacc->grp_write = true;
continue; continue;
} }
rchild->grp_hint = 1; rchild->grp_hint = 1;
new_acc = create_artificial_child_access (lacc, rchild, norm_offset); new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
lacc->grp_write
|| rchild->grp_write);
if (new_acc) if (new_acc)
{ {
ret = true; ret = true;
...@@ -2628,9 +2685,17 @@ propagate_all_subaccesses (void) ...@@ -2628,9 +2685,17 @@ propagate_all_subaccesses (void)
if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base))) if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
continue; continue;
lacc = lacc->group_representative; lacc = lacc->group_representative;
if (propagate_subaccesses_across_link (lacc, racc) if (propagate_subaccesses_across_link (lacc, racc))
&& lacc->first_link) do
add_access_to_work_queue (lacc); {
if (lacc->first_link)
{
add_access_to_work_queue (lacc);
break;
}
lacc = lacc->parent;
}
while (lacc);
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment