Commit e1ad2926 by Alexandre Oliva Committed by Alexandre Oliva

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
parent f00b411f
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
......
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
......
/* { 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) ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment