Since stack slot sharing now only works when RTL expansion
sees the point of birth of variables explicitely marked
we have to insert those markers during optimization.

One case is when CCP simplifies a VLA allocation done
with __builtin_stack_{save,restore} to a decl with constant size.
There we already place the proper end-of-life CLOBBERs and the
patch changes us to also emit birth CLOBBERs.  gcc.dg/pr51491.c
is where the effect is visible.

A similar case happens when inlining produces declarations for
arguments and result variables.  This is visible in
g++.dg/opt/pr81715.C for example.

2022-02-02  Richard Biener  <rguent...@suse.de>

        * tree-inline.cc (expand_call_inline): Also insert birth
        CLOBBERs for parameter and return declarations.
        * tree-ssa-ccp.c (insert_clobbers_for_var): Also insert
        birth CLOBBERs.

        * gcc.dg/pr51491-2.c: Adjust.
---
 gcc/testsuite/gcc.dg/pr51491-2.c |  3 ++-
 gcc/tree-inline.cc               | 27 ++++++++++++++++++++++++++-
 gcc/tree-ssa-ccp.cc              |  5 +++++
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr51491-2.c b/gcc/testsuite/gcc.dg/pr51491-2.c
index 429ee4e5914..910be3ddeec 100644
--- a/gcc/testsuite/gcc.dg/pr51491-2.c
+++ b/gcc/testsuite/gcc.dg/pr51491-2.c
@@ -31,4 +31,5 @@ f (int n)
   return tt;
 }
 
-/* { dg-final { scan-tree-dump-times "CLOBBER" 2 "ccp1"} } */
+/* There is one redundant birth before the a[4] due to a DECL_EXPR + BIND.  */
+/* { dg-final { scan-tree-dump-times "CLOBBER" 5 "ccp1"} } */
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index ca66a8266b1..cb825077bde 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -4767,7 +4767,7 @@ expand_call_inline (basic_block bb, gimple *stmt, 
copy_body_data *id,
   cgraph_inline_failed_t reason;
   basic_block return_block;
   edge e;
-  gimple_stmt_iterator gsi, stmt_gsi;
+  gimple_stmt_iterator gsi, stmt_gsi, birth_gsi;
   bool successfully_inlined = false;
   bool purge_dead_abnormal_edges;
   gcall *call_stmt;
@@ -4924,6 +4924,7 @@ expand_call_inline (basic_block bb, gimple *stmt, 
copy_body_data *id,
   /* Split the block before the GIMPLE_CALL.  */
   stmt_gsi = gsi_for_stmt (stmt);
   gsi_prev (&stmt_gsi);
+  birth_gsi = stmt_gsi;
   e = split_block (bb, gsi_end_p (stmt_gsi) ? NULL : gsi_stmt (stmt_gsi));
   bb = e->src;
   return_block = e->dest;
@@ -5143,6 +5144,18 @@ expand_call_inline (basic_block bb, gimple *stmt, 
copy_body_data *id,
              clobber_stmt = gimple_build_assign (*varp, clobber);
              gimple_set_location (clobber_stmt, gimple_location (stmt));
              gsi_insert_before (&stmt_gsi, clobber_stmt, GSI_SAME_STMT);
+
+             clobber = build_clobber (TREE_TYPE (*varp), CLOBBER_BIRTH);
+             clobber_stmt = gimple_build_assign (*varp, clobber);
+             gimple_set_location (clobber_stmt, gimple_location (stmt));
+             if (gsi_end_p (birth_gsi))
+               {
+                 birth_gsi = gsi_start_bb (gsi_bb (birth_gsi));
+                 gsi_insert_before (&birth_gsi, clobber_stmt, GSI_NEW_STMT);
+               }
+             else
+               gsi_insert_after (&birth_gsi, clobber_stmt,
+                                 GSI_CONTINUE_LINKING);
            }
        }
 
@@ -5212,6 +5225,18 @@ expand_call_inline (basic_block bb, gimple *stmt, 
copy_body_data *id,
          clobber_stmt = gimple_build_assign (id->retvar, clobber);
          gimple_set_location (clobber_stmt, gimple_location (old_stmt));
          gsi_insert_after (&stmt_gsi, clobber_stmt, GSI_SAME_STMT);
+
+         clobber = build_clobber (TREE_TYPE (id->retvar), CLOBBER_BIRTH);
+         clobber_stmt = gimple_build_assign (id->retvar, clobber);
+         gimple_set_location (clobber_stmt, gimple_location (call_stmt));
+         if (gsi_end_p (birth_gsi))
+           {
+             birth_gsi = gsi_start_bb (gsi_bb (birth_gsi));
+             gsi_insert_before (&birth_gsi, clobber_stmt, GSI_NEW_STMT);
+           }
+         else
+           gsi_insert_after (&birth_gsi, clobber_stmt,
+                             GSI_CONTINUE_LINKING);
        }
     }
   else
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 9164efe3037..77910715755 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -2573,6 +2573,11 @@ insert_clobbers_for_var (gimple_stmt_iterator i, tree 
var)
       if (saved_val == NULL_TREE)
        continue;
 
+      /* Place a birth after the stack-save.  */
+      tree clobber = build_clobber (TREE_TYPE (var), CLOBBER_BIRTH);
+      gimple *clobber_stmt = gimple_build_assign (var, clobber);
+      gsi_insert_after (&i, clobber_stmt, GSI_SAME_STMT);
+
       insert_clobber_before_stack_restore (saved_val, var, &visited);
       break;
     }
-- 
2.34.1

Reply via email to