mirror of git://gcc.gnu.org/git/gcc.git
[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:
parent
4ba66aee9e
commit
c8638450ab
|
|
@ -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>
|
2017-06-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* config/s390/s390.c (s390_emit_epilogue): Disable early return
|
* config/s390/s390.c (s390_emit_epilogue): Disable early return
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2017-06-01 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR c++/80896
|
PR c++/80896
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -694,21 +694,9 @@ 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
|
||||||
disqualify_candidate (tree decl, const char *reason)
|
disqualify_candidate (tree decl, const char *reason)
|
||||||
{
|
{
|
||||||
|
|
@ -723,13 +711,6 @@ disqualify_candidate (tree decl, const char *reason)
|
||||||
print_generic_expr (dump_file, decl);
|
print_generic_expr (dump_file, decl);
|
||||||
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
|
||||||
|
|
@ -2679,6 +2660,26 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
|
||||||
return ret;
|
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. */
|
/* Propagate all subaccesses across assignment links. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -2698,7 +2699,20 @@ 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))
|
|
||||||
|
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
|
do
|
||||||
{
|
{
|
||||||
if (lacc->first_link)
|
if (lacc->first_link)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue