diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-03-26 10:10:21 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-03-26 10:10:21 +0100 |
commit | 10ea09ee846eaa345161a3a3f519b3780d6101fa (patch) | |
tree | fa1093ef2fea98dbc89a5336b18885639f2addfe | |
parent | dab932d1519ba07fb4c49e6849ee7ceb02c0d603 (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/gimple.h | 14 | ||||
-rw-r--r-- | gcc/gimplify.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/debug/pr94281.C | 11 |
5 files changed, 70 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 180c92f..8005e1a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 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. + PR rtl-optimization/92264 * var-tracking.c (add_stores): Call cselib_set_value_sp_based even for sp based values in !frame_pointer_needed diff --git a/gcc/gimple.h b/gcc/gimple.h index 0420d6d..305d98f 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -4728,6 +4728,18 @@ is_gimple_debug (const gimple *gs) } +/* Return the first nondebug statement in GIMPLE sequence S. */ + +static inline gimple * +gimple_seq_first_nondebug_stmt (gimple_seq s) +{ + gimple_seq_node n = gimple_seq_first (s); + while (n && is_gimple_debug (n)) + n = n->next; + return n; +} + + /* Return the last nondebug statement in GIMPLE sequence S. */ static inline gimple * @@ -4737,7 +4749,7 @@ gimple_seq_last_nondebug_stmt (gimple_seq s) for (n = gimple_seq_last (s); n && is_gimple_debug (n); n = n->prev) - if (n->prev == s) + if (n == s) return NULL; return n; } 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6091bcc..ea31955 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2020-03-26 Jakub Jelinek <jakub@redhat.com> + PR debug/94281 + * g++.dg/debug/pr94281.C: New test. + PR c++/81349 * g++.dg/cpp1z/pr81349.C: New test. diff --git a/gcc/testsuite/g++.dg/debug/pr94281.C b/gcc/testsuite/g++.dg/debug/pr94281.C new file mode 100644 index 0000000..0638691 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/pr94281.C @@ -0,0 +1,11 @@ +// PR debug/94281 +// { dg-do compile } +// { dg-options "-O1 -fno-tree-dce -fipa-icf -fno-tree-forwprop -fcompare-debug" } + +void fn1() +{ +} +void fn2() +{ + ; +} |