aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-03-14 09:42:45 +0100
committerRichard Biener <rguenther@suse.de>2023-03-14 13:46:30 +0100
commitbd6e566e9dc543cf4f6df69dcefb40bb8b4100f1 (patch)
treecf763b71e176fddae80cf7af4d80c2f8704e20f2 /gcc
parent67839c562779081936cb79ebca156ef43d70f65f (diff)
downloadgcc-bd6e566e9dc543cf4f6df69dcefb40bb8b4100f1.zip
gcc-bd6e566e9dc543cf4f6df69dcefb40bb8b4100f1.tar.gz
gcc-bd6e566e9dc543cf4f6df69dcefb40bb8b4100f1.tar.bz2
Remove variables only used with .DEFERRED_INIT
In PR109087 it was noticed that we rely on DSE to remove .DEFERRED_INIT when it is the only remaining use of a variable. Since DSE is imperfect and even if it were not would be limited by the amount of statements to walk the following enhances the unused var removal pass to handle .DEFERRED_INIT like CLOBBERs, thus we do not keep local variables just because they are deferred initialized. * tree-ssa-live.cc (remove_unused_locals): Do not treat the .DEFERRED_INIT of a variable as use, instead remove that if it is the only use. * gcc.dg/auto-init-unused-1.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/auto-init-unused-1.c16
-rw-r--r--gcc/tree-ssa-live.cc21
2 files changed, 36 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/auto-init-unused-1.c b/gcc/testsuite/gcc.dg/auto-init-unused-1.c
new file mode 100644
index 0000000..b7d44e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-unused-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftrivial-auto-var-init=zero -fdump-tree-ssa" } */
+
+int a;
+int foo (void);
+int bar (void);
+
+void
+baz (void)
+{
+ int *b[6];
+ if (foo ())
+ a |= bar ();
+}
+
+/* { dg-final { scan-tree-dump-not "DEFERRED_INIT" "ssa" } } */
diff --git a/gcc/tree-ssa-live.cc b/gcc/tree-ssa-live.cc
index c179444..9118e82 100644
--- a/gcc/tree-ssa-live.cc
+++ b/gcc/tree-ssa-live.cc
@@ -813,6 +813,12 @@ remove_unused_locals (void)
continue;
}
+ if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+ {
+ have_local_clobbers = true;
+ continue;
+ }
+
if (b)
TREE_USED (b) = true;
@@ -856,7 +862,7 @@ remove_unused_locals (void)
to remove them if they are the only references to a local variable,
but we want to retain them when there's any other. So the first pass
ignores them, and the second pass (if there were any) tries to remove
- them. */
+ them. We do the same for .DEFERRED_INIT. */
if (have_local_clobbers)
FOR_EACH_BB_FN (bb, cfun)
{
@@ -888,6 +894,19 @@ remove_unused_locals (void)
if (b)
TREE_USED (b) = true;
}
+ else if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+ {
+ tree lhs = gimple_call_lhs (stmt);
+ if (DECL_P (lhs) && !is_used_p (lhs))
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ continue;
+ }
+ if (b)
+ TREE_USED (b) = true;
+ }
else if (gimple_debug_bind_p (stmt))
{
tree var = gimple_debug_bind_get_var (stmt);