aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-03-26 10:10:21 +0100
committerJakub Jelinek <jakub@redhat.com>2020-03-26 10:10:21 +0100
commit10ea09ee846eaa345161a3a3f519b3780d6101fa (patch)
treefa1093ef2fea98dbc89a5336b18885639f2addfe /gcc/gimplify.c
parentdab932d1519ba07fb4c49e6849ee7ceb02c0d603 (diff)
downloadgcc-10ea09ee846eaa345161a3a3f519b3780d6101fa.zip
gcc-10ea09ee846eaa345161a3a3f519b3780d6101fa.tar.gz
gcc-10ea09ee846eaa345161a3a3f519b3780d6101fa.tar.bz2
gimplify: Fix -fcompare-debug differences caused by gimplify_body [PR94281]
The following testcase FAILs, because gimplify_body adds a GIMPLE_NOP only when there are no statements in the function and with -g there is a DEBUG_BEGIN_STMT, so it doesn't add it and due to -fno-tree-dce that never gets removed afterwards. Similarly, if the body seq after gimplification contains some DEBUG_BEGIN_STMTs plus a single gbind, then we could behave differently between -g0 and -g, by using that gbind as the body in the -g0 case and not in the -g case. This patch fixes that by ignoring DEBUG_BEGIN_STMTs (other debug stmts can't appear at this point yet thankfully) during decisions and if we pick the single gbind and there are DEBUG_BEGIN_STMTs next to it, it moves them into the gbind. While debugging this, I found also a bug in the gimple_seq_last_nondebug_stmt function, for a seq that has a single non-DEBUG_BEGIN_STMT statement followed by one or more DEBUG_BEGIN_STMTs it would return NULL rather than the first statement. 2020-03-26 Jakub Jelinek <jakub@redhat.com> PR debug/94281 * gimple.h (gimple_seq_first_nondebug_stmt): New function. (gimple_seq_last_nondebug_stmt): Don't return NULL if seq contains a single non-debug stmt followed by one or more debug stmts. * gimplify.c (gimplify_body): Use gimple_seq_first_nondebug_stmt instead of gimple_seq_first_stmt, use gimple_seq_first_nondebug_stmt and gimple_seq_last_nondebug_stmt instead of gimple_seq_first and gimple_seq_last to check if outer_stmt gbind could be reused and if yes and it is surrounded by any debug stmts, move them into the gbind body. * g++.dg/debug/pr94281.C: New test.
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index ef531f3..787435c 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -14849,7 +14849,7 @@ gimplify_body (tree fndecl, bool do_parms)
/* Gimplify the function's body. */
seq = NULL;
gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
- outer_stmt = gimple_seq_first_stmt (seq);
+ outer_stmt = gimple_seq_first_nondebug_stmt (seq);
if (!outer_stmt)
{
outer_stmt = gimple_build_nop ();
@@ -14859,8 +14859,37 @@ gimplify_body (tree fndecl, bool do_parms)
/* The body must contain exactly one statement, a GIMPLE_BIND. If this is
not the case, wrap everything in a GIMPLE_BIND to make it so. */
if (gimple_code (outer_stmt) == GIMPLE_BIND
- && gimple_seq_first (seq) == gimple_seq_last (seq))
- outer_bind = as_a <gbind *> (outer_stmt);
+ && (gimple_seq_first_nondebug_stmt (seq)
+ == gimple_seq_last_nondebug_stmt (seq)))
+ {
+ outer_bind = as_a <gbind *> (outer_stmt);
+ if (gimple_seq_first_stmt (seq) != outer_stmt
+ || gimple_seq_last_stmt (seq) != outer_stmt)
+ {
+ /* If there are debug stmts before or after outer_stmt, move them
+ inside of outer_bind body. */
+ gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
+ gimple_seq second_seq = NULL;
+ if (gimple_seq_first_stmt (seq) != outer_stmt
+ && gimple_seq_last_stmt (seq) != outer_stmt)
+ {
+ second_seq = gsi_split_seq_after (gsi);
+ gsi_remove (&gsi, false);
+ }
+ else if (gimple_seq_first_stmt (seq) != outer_stmt)
+ gsi_remove (&gsi, false);
+ else
+ {
+ gsi_remove (&gsi, false);
+ second_seq = seq;
+ seq = NULL;
+ }
+ gimple_seq_add_seq_without_update (&seq,
+ gimple_bind_body (outer_bind));
+ gimple_seq_add_seq_without_update (&seq, second_seq);
+ gimple_bind_set_body (outer_bind, seq);
+ }
+ }
else
outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);