Commit 345683a9 by Martin Jambor Committed by Martin Jambor

[PR80803 2/2] Diligent queuing in SRA grp_write prop

2017-06-13  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/80803
	PR tree-optimization/81063
	* tree-sra.c (subtree_mark_written_and_enqueue): Move up in the file.
	(propagate_subaccesses_across_link): Enqueue subtree whneve necessary
	instead of relying on the caller.

testsuite/
	gcc.dg/tree-ssa/pr80803.c: New test.
	gcc.dg/tree-ssa/pr81063.c: Likewise.

From-SVN: r249154
parent 35a952ba
2017-06-13 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/80803
PR tree-optimization/81063
* tree-sra.c (subtree_mark_written_and_enqueue): Move up in the file.
(propagate_subaccesses_across_link): Enqueue subtree whneve necessary
instead of relying on the caller.
2017-06-13 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (add_access_to_work_queue): Only enqueue accesses
that have a first_link.
(sort_and_splice_var_accesses): Do not check first_link before
......
2017-06-13 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/80803
PR tree-optimization/81063
gcc.dg/tree-ssa/pr80803.c: New test.
gcc.dg/tree-ssa/pr81063.c: Likewise.
2017-06-12 Yury Gribov <tetra2005@gmail.com>
* c-c++-common/fold-masked-cmp-3.c: New test.
......
/* { dg-do run } */
/* { dg-options "-O" } */
struct S0
{
unsigned a : 15;
int b;
int c;
};
struct S1
{
struct S0 s0;
int e;
};
struct Z
{
char c;
int z;
} __attribute__((packed));
union U
{
struct S1 s1;
struct Z z;
};
int __attribute__((noinline, noclone))
return_zero (void)
{
return 0;
}
volatile union U gu;
struct S0 gs;
int __attribute__((noinline, noclone))
check_outcome ()
{
if (gs.a != 6
|| gs.b != 80000)
__builtin_abort ();
}
int
main (int argc, char *argv[])
{
union U u;
struct S1 m,n;
struct S0 l;
if (return_zero ())
u.z.z = 20000;
else
{
u.s1.s0.a = 6;
u.s1.s0.b = 80000;
u.s1.e = 2;
n = u.s1;
m = n;
m.s0.c = 0;
l = m.s0;
gs = l;
}
gu = u;
check_outcome ();
return 0;
}
/* { dg-do run } */
/* { dg-options "-O" } */
struct A
{
int b;
int c:2;
};
struct B
{
int e;
struct A f;
} g = {0, {0, 1}}, j;
struct A *h = &g.f;
int main ()
{
struct A k;
struct B l = j, i = l;
if (!i.f.b)
k = i.f;
*h = k;
if (g.f.c != 0)
__builtin_abort ();
return 0;
}
......@@ -2558,9 +2558,28 @@ create_artificial_child_access (struct access *parent, struct access *model,
}
/* Propagate all subaccesses of RACC across an assignment link to LACC. Return
true if any new subaccess was created. Additionally, if RACC is a scalar
access but LACC is not, change the type of the latter, if possible. */
/* Beginning with ACCESS, traverse its whole access subtree and mark all
sub-trees as written to. If any of them has not been marked so previously
and has assignment links leading from it, re-enqueue it. */
static void
subtree_mark_written_and_enqueue (struct access *access)
{
if (access->grp_write)
return;
access->grp_write = true;
add_access_to_work_queue (access);
struct access *child;
for (child = access->first_child; child; child = child->next_sibling)
subtree_mark_written_and_enqueue (child);
}
/* Propagate subaccesses and grp_write flags of RACC across an assignment link
to LACC. Enqueue sub-accesses as necessary so that the write flag is
propagated transitively. Return true if anything changed. Additionally, if
RACC is a scalar access but LACC is not, change the type of the latter, if
possible. */
static bool
propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
......@@ -2576,7 +2595,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
gcc_checking_assert (!comes_initialized_p (racc->base));
if (racc->grp_write)
{
lacc->grp_write = true;
subtree_mark_written_and_enqueue (lacc);
ret = true;
}
}
......@@ -2585,13 +2604,21 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
|| lacc->grp_unscalarizable_region
|| racc->grp_unscalarizable_region)
{
ret |= !lacc->grp_write;
lacc->grp_write = true;
if (!lacc->grp_write)
{
ret = true;
subtree_mark_written_and_enqueue (lacc);
}
return ret;
}
if (is_gimple_reg_type (racc->type))
{
if (!lacc->grp_write)
{
ret = true;
subtree_mark_written_and_enqueue (lacc);
}
if (!lacc->first_child && !racc->first_child)
{
tree t = lacc->base;
......@@ -2616,21 +2643,15 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
struct access *new_acc = NULL;
HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
if (rchild->grp_unscalarizable_region)
{
lacc->grp_write = true;
continue;
}
if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
&new_acc))
{
if (new_acc)
{
if (!new_acc->grp_write
&& (lacc->grp_write || rchild->grp_write))
if (!new_acc->grp_write && rchild->grp_write)
{
new_acc ->grp_write = true;
gcc_assert (!lacc->grp_write);
subtree_mark_written_and_enqueue (new_acc);
ret = true;
}
......@@ -2640,7 +2661,23 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
ret |= propagate_subaccesses_across_link (new_acc, rchild);
}
else
lacc->grp_write = true;
{
if (rchild->grp_write && !lacc->grp_write)
{
ret = true;
subtree_mark_written_and_enqueue (lacc);
}
}
continue;
}
if (rchild->grp_unscalarizable_region)
{
if (rchild->grp_write && !lacc->grp_write)
{
ret = true;
subtree_mark_written_and_enqueue (lacc);
}
continue;
}
......@@ -2648,36 +2685,17 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
lacc->grp_write
|| rchild->grp_write);
if (new_acc)
{
ret = true;
if (racc->first_child)
propagate_subaccesses_across_link (new_acc, rchild);
}
gcc_checking_assert (new_acc);
if (racc->first_child)
propagate_subaccesses_across_link (new_acc, rchild);
add_access_to_work_queue (lacc);
ret = true;
}
return ret;
}
/* Beginning with ACCESS, traverse its whole access subtree and mark all
sub-trees as written to. If any of them has not been marked so previously
and has assignment links leading from it, re-enqueue it. */
static void
subtree_mark_written_and_enqueue (struct access *access)
{
if (access->grp_write)
return;
access->grp_write = true;
add_access_to_work_queue (access);
struct access *child;
for (child = access->first_child; child; child = child->next_sibling)
subtree_mark_written_and_enqueue (child);
}
/* Propagate all subaccesses across assignment links. */
static void
......
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