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>
|
2017-05-09 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||||
|
|
||||||
PR target/68163
|
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>
|
2017-05-10 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR c++/80145
|
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->caller->decl)
|
||||||
= DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl);
|
= DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl);
|
||||||
|
|
||||||
/* Split the block holding the GIMPLE_CALL. */
|
/* Split the block before the GIMPLE_CALL. */
|
||||||
e = split_block (bb, stmt);
|
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;
|
bb = e->src;
|
||||||
return_block = e->dest;
|
return_block = e->dest;
|
||||||
remove_edge (e);
|
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
|
/* If the GIMPLE_CALL was in the last statement of BB, it may have
|
||||||
been the source of abnormal edges. In this case, schedule
|
been the source of abnormal edges. In this case, schedule
|
||||||
the removal of dead abnormal edges. */
|
the removal of dead abnormal edges. */
|
||||||
gsi = gsi_start_bb (return_block);
|
gsi = gsi_start_bb (return_block);
|
||||||
if (gsi_end_p (gsi))
|
gsi_next (&gsi);
|
||||||
{
|
purge_dead_abnormal_edges = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt_gsi = gsi_start_bb (return_block);
|
stmt_gsi = gsi_start_bb (return_block);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user