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
This commit is contained in:
parent
f00b411f54
commit
e1ad2926a0
@ -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
|
||||
|
@ -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
|
||||
|
38
gcc/testsuite/gcc.dg/guality/inline-params-2.c
Normal file
38
gcc/testsuite/gcc.dg/guality/inline-params-2.c
Normal file
@ -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);
|
||||
}
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user