* avoid remove&reinsert of call when splitting block for inlining
@ 2017-05-09 20:33 Alexandre Oliva
2017-05-10 8:14 ` Richard Biener
0 siblings, 1 reply; 2+ messages in thread
From: Alexandre Oliva @ 2017-05-09 20:33 UTC (permalink / raw)
To: gcc-patches
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.
Regstrapped on x86_64-linux-gnu and i686-linux-gnu. Ok to install?
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.
---
gcc/testsuite/gcc.dg/guality/inline-params-2.c | 38 ++++++++++++++++++++++++
gcc/tree-inline.c | 25 ++++------------
2 files changed, 44 insertions(+), 19 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/guality/inline-params-2.c
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..e00188ca
--- /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);
--
Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/ FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: avoid remove&reinsert of call when splitting block for inlining
2017-05-09 20:33 avoid remove&reinsert of call when splitting block for inlining Alexandre Oliva
@ 2017-05-10 8:14 ` Richard Biener
0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2017-05-10 8:14 UTC (permalink / raw)
To: Alexandre Oliva; +Cc: GCC Patches
On Tue, May 9, 2017 at 10:12 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
> 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.
>
> Regstrapped on x86_64-linux-gnu and i686-linux-gnu. Ok to install?
Ok if you included Ada in bootstrap / testing.
Thanks,
Richard.
> 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.
> ---
> gcc/testsuite/gcc.dg/guality/inline-params-2.c | 38 ++++++++++++++++++++++++
> gcc/tree-inline.c | 25 ++++------------
> 2 files changed, 44 insertions(+), 19 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/guality/inline-params-2.c
>
> 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..e00188ca
> --- /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);
>
>
> --
> Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
> You must be the change you wish to see in the world. -- Gandhi
> Be Free! -- http://FSFLA.org/ FSF Latin America board member
> Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-05-10 8:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-09 20:33 avoid remove&reinsert of call when splitting block for inlining Alexandre Oliva
2017-05-10 8:14 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).