aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-05-17 06:57:45 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-05-17 06:57:45 +0000
commit773d0331f7456614f9f7e619e642946d9bdc638a (patch)
tree548ff0f2efa59788903cd0e6dc22e20a8d9a7156
parent8ee520219f795fc363d90c1e92ebad642d0e9f69 (diff)
downloadgcc-773d0331f7456614f9f7e619e642946d9bdc638a.zip
gcc-773d0331f7456614f9f7e619e642946d9bdc638a.tar.gz
gcc-773d0331f7456614f9f7e619e642946d9bdc638a.tar.bz2
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c15
-rw-r--r--gcc/tree-ssa-dse.c36
4 files changed, 54 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 700ac4a..23d13ac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
* config/riscv/riscv.md (<optab>si3_mask, <optab>si3_mask_1): Prepend
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9eab3ad..f52a555 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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>
PR c++/85363
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c
new file mode 100644
index 0000000..3016dfe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 32a25b9..589cfef 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -577,6 +577,7 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
else
defvar = gimple_vdef (temp);
auto_vec<gimple *, 10> defs;
+ gimple *phi_def = NULL;
FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
{
/* Limit stmt walking. */
@@ -600,7 +601,10 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
processing. */
if (!bitmap_bit_p (visited,
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. */
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;
}
- /* Process defs and remove paths starting with a kill from further
- processing. */
+ /* Process defs and remove those we need not process further. */
for (unsigned i = 0; i < defs.length (); ++i)
- if (stmt_kills_ref_p (defs[i], ref))
- {
- if (by_clobber_p && !gimple_clobber_p (defs[i]))
- *by_clobber_p = false;
+ {
+ gimple *def = defs[i];
+ gimple *use_stmt;
+ 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);
- }
+ }
/* If all defs kill the ref we are done. */
if (defs.is_empty ())