aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2017-05-10 10:16:54 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2017-05-10 10:16:54 +0000
commite1ad2926a08a65efae413d84673e11ba695f2bd4 (patch)
tree97c8067510e1da022eb7b05fa24ef82a66880abf /gcc
parentf00b411f5437114d7ee7107be1d150b7d893dfc7 (diff)
downloadgcc-e1ad2926a08a65efae413d84673e11ba695f2bd4.zip
gcc-e1ad2926a08a65efae413d84673e11ba695f2bd4.tar.gz
gcc-e1ad2926a08a65efae413d84673e11ba695f2bd4.tar.bz2
avoid remove&reinsert of call when splitting block for inlining
We used to split the inlined-into block at (= after) the call, and then remove the call from the first block to insert it in the second. The removal may cause unnecessary and unrecoverable resetting of debug insns: we do not generate debug temps for calls. Avoid the remove-and-reinsert dance by splitting the block before the call. for gcc/ChangeLog * tree-inline.c (expand_call_inline): Split block at stmt before the call. for gcc/testsuite/ChangeLog * gcc.dg/guality/inline-params-2.c: New. From-SVN: r247830
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/guality/inline-params-2.c38
-rw-r--r--gcc/tree-inline.c25
4 files changed, 53 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1f08f99..454203c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * tree-inline.c (expand_call_inline): Split block at stmt
+ before the call.
+
2017-05-09 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/68163
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8ec71d7..0fc75a3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.dg/guality/inline-params-2.c: New.
+
2017-05-10 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/80145
diff --git a/gcc/testsuite/gcc.dg/guality/inline-params-2.c b/gcc/testsuite/gcc.dg/guality/inline-params-2.c
new file mode 100644
index 0000000..e00188c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/inline-params-2.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* tree inline used to split the block for inlining after the call,
+ then move the call to the after-the-call block. This move
+ temporarily deletes the assignment to the result, which in turn
+ resets any debug bind stmts referencing the result. Make sure we
+ don't do that, verifying that the result is visible after the call,
+ and when passed to another inline function. */
+/* { dg-options "-g" } */
+/* { dg-xfail-run-if "" { "*-*-*" } { "-fno-fat-lto-objects" } } */
+
+#define GUALITY_DONT_FORCE_LIVE_AFTER -1
+
+#ifndef STATIC_INLINE
+#define STATIC_INLINE /*static*/
+#endif
+
+
+#include "guality.h"
+
+__attribute__ ((always_inline)) static inline int
+t1 (int i)
+{
+ GUALCHKVAL (i);
+ return i;
+}
+__attribute__ ((always_inline)) static inline int
+t2 (int i)
+{
+ GUALCHKVAL (i);
+ return i - 42;
+}
+int
+main (int argc, char *argv[])
+{
+ int i = t1(42);
+ GUALCHKVAL (i);
+ return t2(i);
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index bfaaede..db3e08f 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4542,33 +4542,20 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
= DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl);
- /* Split the block holding the GIMPLE_CALL. */
- e = split_block (bb, stmt);
+ /* Split the block before the GIMPLE_CALL. */
+ stmt_gsi = gsi_for_stmt (stmt);
+ gsi_prev (&stmt_gsi);
+ e = split_block (bb, gsi_end_p (stmt_gsi) ? NULL : gsi_stmt (stmt_gsi));
bb = e->src;
return_block = e->dest;
remove_edge (e);
- /* split_block splits after the statement; work around this by
- moving the call into the second block manually. Not pretty,
- but seems easier than doing the CFG manipulation by hand
- when the GIMPLE_CALL is in the last statement of BB. */
- stmt_gsi = gsi_last_bb (bb);
- gsi_remove (&stmt_gsi, false);
-
/* If the GIMPLE_CALL was in the last statement of BB, it may have
been the source of abnormal edges. In this case, schedule
the removal of dead abnormal edges. */
gsi = gsi_start_bb (return_block);
- if (gsi_end_p (gsi))
- {
- gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- purge_dead_abnormal_edges = true;
- }
- else
- {
- gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
- purge_dead_abnormal_edges = false;
- }
+ gsi_next (&gsi);
+ purge_dead_abnormal_edges = gsi_end_p (gsi);
stmt_gsi = gsi_start_bb (return_block);