On Tue, May 9, 2017 at 10:12 PM, Alexandre Oliva <aol...@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