re PR tree-optimization/85757 (tree optimizers fail to fully clean up fixed-size memcpy)
2018-05-17 Richard Biener <rguenther@suse.de> PR tree-optimization/85757 * tree-ssa-dse.c (dse_classify_store): Record a PHI def and remove defs that only feed that PHI from further processing. * gcc.dg/tree-ssa/ssa-dse-34.c: New testcase. From-SVN: r260306
This commit is contained in:
parent
8ee520219f
commit
773d0331f7
@ -1,3 +1,9 @@
|
|||||||
|
2018-05-17 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR tree-optimization/85757
|
||||||
|
* tree-ssa-dse.c (dse_classify_store): Record a PHI def and
|
||||||
|
remove defs that only feed that PHI from further processing.
|
||||||
|
|
||||||
2018-05-16 Jim Wilson <jimw@sifive.com>
|
2018-05-16 Jim Wilson <jimw@sifive.com>
|
||||||
|
|
||||||
* config/riscv/riscv.md (<optab>si3_mask, <optab>si3_mask_1): Prepend
|
* config/riscv/riscv.md (<optab>si3_mask, <optab>si3_mask_1): Prepend
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2018-05-17 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR tree-optimization/85757
|
||||||
|
* gcc.dg/tree-ssa/ssa-dse-34.c: New testcase.
|
||||||
|
|
||||||
2018-05-16 Marek Polacek <polacek@redhat.com>
|
2018-05-16 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
PR c++/85363
|
PR c++/85363
|
||||||
|
15
gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c
Normal file
15
gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O -fdump-tree-dse1-details" } */
|
||||||
|
|
||||||
|
void f(int n, char *p0, char *p1, char *p2, char *o)
|
||||||
|
{
|
||||||
|
int t0, t1;
|
||||||
|
__builtin_memcpy(&t0, p0, 1);
|
||||||
|
__builtin_memcpy(&t1, p1, 1);
|
||||||
|
if (n==3)
|
||||||
|
__builtin_memcpy(o+2, p2, 1);
|
||||||
|
__builtin_memcpy(o+0, &t0, 1);
|
||||||
|
__builtin_memcpy(o+1, &t1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" } } */
|
@ -577,6 +577,7 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
|
|||||||
else
|
else
|
||||||
defvar = gimple_vdef (temp);
|
defvar = gimple_vdef (temp);
|
||||||
auto_vec<gimple *, 10> defs;
|
auto_vec<gimple *, 10> defs;
|
||||||
|
gimple *phi_def = NULL;
|
||||||
FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
|
FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
|
||||||
{
|
{
|
||||||
/* Limit stmt walking. */
|
/* Limit stmt walking. */
|
||||||
@ -600,7 +601,10 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
|
|||||||
processing. */
|
processing. */
|
||||||
if (!bitmap_bit_p (visited,
|
if (!bitmap_bit_p (visited,
|
||||||
SSA_NAME_VERSION (PHI_RESULT (use_stmt))))
|
SSA_NAME_VERSION (PHI_RESULT (use_stmt))))
|
||||||
defs.safe_push (use_stmt);
|
{
|
||||||
|
defs.safe_push (use_stmt);
|
||||||
|
phi_def = use_stmt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If the statement is a use the store is not dead. */
|
/* If the statement is a use the store is not dead. */
|
||||||
else if (ref_maybe_used_by_stmt_p (use_stmt, ref))
|
else if (ref_maybe_used_by_stmt_p (use_stmt, ref))
|
||||||
@ -657,15 +661,31 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
|
|||||||
return DSE_STORE_DEAD;
|
return DSE_STORE_DEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process defs and remove paths starting with a kill from further
|
/* Process defs and remove those we need not process further. */
|
||||||
processing. */
|
|
||||||
for (unsigned i = 0; i < defs.length (); ++i)
|
for (unsigned i = 0; i < defs.length (); ++i)
|
||||||
if (stmt_kills_ref_p (defs[i], ref))
|
{
|
||||||
{
|
gimple *def = defs[i];
|
||||||
if (by_clobber_p && !gimple_clobber_p (defs[i]))
|
gimple *use_stmt;
|
||||||
*by_clobber_p = false;
|
use_operand_p use_p;
|
||||||
|
/* If the path to check starts with a kill we do not need to
|
||||||
|
process it further.
|
||||||
|
??? With byte tracking we need only kill the bytes currently
|
||||||
|
live. */
|
||||||
|
if (stmt_kills_ref_p (def, ref))
|
||||||
|
{
|
||||||
|
if (by_clobber_p && !gimple_clobber_p (def))
|
||||||
|
*by_clobber_p = false;
|
||||||
|
defs.unordered_remove (i);
|
||||||
|
}
|
||||||
|
/* In addition to kills we can remove defs whose only use
|
||||||
|
is another def in defs. That can only ever be PHIs of which
|
||||||
|
we track a single for simplicity reasons (we fail for multiple
|
||||||
|
PHIs anyways). */
|
||||||
|
else if (gimple_code (def) != GIMPLE_PHI
|
||||||
|
&& single_imm_use (gimple_vdef (def), &use_p, &use_stmt)
|
||||||
|
&& use_stmt == phi_def)
|
||||||
defs.unordered_remove (i);
|
defs.unordered_remove (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If all defs kill the ref we are done. */
|
/* If all defs kill the ref we are done. */
|
||||||
if (defs.is_empty ())
|
if (defs.is_empty ())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user