[PR 80898] Propagate grp_write from disqualified SRA candidates

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

	PR tree-optimization/80898
	* tree-sra.c (process_subtree_disqualification): Removed.
	(disqualify_candidate): Do not acll
	process_subtree_disqualification.
	(subtree_mark_written_and_enqueue): New function.
	(propagate_all_subaccesses): Set grp_write of LHS subtree if the
	RHS has been disqualified and re-queue LHS if necessary.  Apart
	from that, ignore disqualified RHS.

testsuite/
	* gcc.dg/tree-ssa/pr80898.c: New test.
	* gcc.dg/tree-ssa/pr80898-2.c: Likewise.

From-SVN: r248790
This commit is contained in:
Martin Jambor 2017-06-01 14:14:29 +02:00 committed by Martin Jambor
parent 4ba66aee9e
commit c8638450ab
5 changed files with 143 additions and 21 deletions

View file

@ -1,3 +1,14 @@
2017-06-01 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/80898
* tree-sra.c (process_subtree_disqualification): Removed.
(disqualify_candidate): Do not acll
process_subtree_disqualification.
(subtree_mark_written_and_enqueue): New function.
(propagate_all_subaccesses): Set grp_write of LHS subtree if the
RHS has been disqualified and re-queue LHS if necessary. Apart
from that, ignore disqualified RHS.
2017-06-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390.c (s390_emit_epilogue): Disable early return

View file

@ -1,3 +1,9 @@
2017-06-01 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/80898
* gcc.dg/tree-ssa/pr80898.c: New test.
* gcc.dg/tree-ssa/pr80898-2.c: Likewise.
2017-06-01 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/80896

View file

@ -0,0 +1,71 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
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;
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;
m = u.s1;
m.s0.c = 0;
l = m.s0;
gs = l;
}
gu = u;
check_outcome ();
return 0;
}

View file

@ -0,0 +1,20 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
struct S0 {
int f0 : 24;
int f1;
int f74;
} a, *c = &a;
struct S0 fn1() {
struct S0 b = {4, 3};
return b;
}
int main() {
*c = fn1();
if (a.f1 != 3)
__builtin_abort ();
return 0;
}

View file

@ -694,21 +694,9 @@ static bool constant_decl_p (tree 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
there is one. */
static void
disqualify_candidate (tree decl, const char *reason)
{
@ -723,13 +711,6 @@ disqualify_candidate (tree decl, const char *reason)
print_generic_expr (dump_file, decl);
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
@ -2679,6 +2660,26 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
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;
if (access->first_link)
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
@ -2698,7 +2699,20 @@ propagate_all_subaccesses (void)
if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
continue;
lacc = lacc->group_representative;
if (propagate_subaccesses_across_link (lacc, racc))
bool reque_parents = false;
if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
{
if (!lacc->grp_write)
{
subtree_mark_written_and_enqueue (lacc);
reque_parents = true;
}
}
else if (propagate_subaccesses_across_link (lacc, racc))
reque_parents = true;
if (reque_parents)
do
{
if (lacc->first_link)