re PR rtl-optimization/85638 (build failure for Ada runtime with SJLJ exceptions on x86)

PR rtl-optimization/85638
	* bb-reorder.c: Include common/common-target.h.
	(create_forwarder_block): New function extracted from...
	(fix_up_crossing_landing_pad): ...here.  Rename into...
	(dw2_fix_up_crossing_landing_pad): ...this.
	(sjlj_fix_up_crossing_landing_pad): New function.
	(find_rarely_executed_basic_blocks_and_crossing_edges): In SJLJ mode,
	call sjlj_fix_up_crossing_landing_pad if there are incoming EH edges
	from both partitions and exit the loop after one iteration.

From-SVN: r260070
This commit is contained in:
Eric Botcazou 2018-05-09 07:58:29 +00:00 committed by Eric Botcazou
parent 655b16da12
commit 40305631b5
2 changed files with 108 additions and 30 deletions

View File

@ -1,3 +1,15 @@
2018-05-09 Eric Botcazou <ebotcazou@adacore.com>
PR rtl-optimization/85638
* bb-reorder.c: Include common/common-target.h.
(create_forwarder_block): New function extracted from...
(fix_up_crossing_landing_pad): ...here. Rename into...
(dw2_fix_up_crossing_landing_pad): ...this.
(sjlj_fix_up_crossing_landing_pad): New function.
(find_rarely_executed_basic_blocks_and_crossing_edges): In SJLJ mode,
call sjlj_fix_up_crossing_landing_pad if there are incoming EH edges
from both partitions and exit the loop after one iteration.
2018-05-08 Kelvin Nilsen <kelvin@gcc.gnu.org>
Revert:

View File

@ -117,6 +117,7 @@
#include "fibonacci_heap.h"
#include "stringpool.h"
#include "attribs.h"
#include "common/common-target.h"
/* The number of rounds. In most cases there will only be 4 rounds, but
when partitioning hot and cold basic blocks into separate sections of
@ -1408,17 +1409,95 @@ get_uncond_jump_length (void)
return length;
}
/* Create a forwarder block to OLD_BB starting with NEW_LABEL and in the
other partition wrt OLD_BB. */
static basic_block
create_forwarder_block (rtx_code_label *new_label, basic_block old_bb)
{
/* Put the new label and a jump in the new basic block. */
rtx_insn *label = emit_label (new_label);
rtx_code_label *old_label = block_label (old_bb);
rtx_insn *jump = emit_jump_insn (targetm.gen_jump (old_label));
JUMP_LABEL (jump) = old_label;
/* Create the new basic block and put it in last position. */
basic_block last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
basic_block new_bb = create_basic_block (label, jump, last_bb);
new_bb->aux = last_bb->aux;
new_bb->count = old_bb->count;
last_bb->aux = new_bb;
emit_barrier_after_bb (new_bb);
make_single_succ_edge (new_bb, old_bb, 0);
/* Make sure the new basic block is in the other partition. */
unsigned new_partition = BB_PARTITION (old_bb);
new_partition ^= BB_HOT_PARTITION | BB_COLD_PARTITION;
BB_SET_PARTITION (new_bb, new_partition);
return new_bb;
}
/* The common landing pad in block OLD_BB has edges from both partitions.
Add a new landing pad that will just jump to the old one and split the
edges so that no EH edge crosses partitions. */
static void
sjlj_fix_up_crossing_landing_pad (basic_block old_bb)
{
const unsigned lp_len = cfun->eh->lp_array->length ();
edge_iterator ei;
edge e;
/* Generate the new common landing-pad label. */
rtx_code_label *new_label = gen_label_rtx ();
LABEL_PRESERVE_P (new_label) = 1;
/* Create the forwarder block. */
basic_block new_bb = create_forwarder_block (new_label, old_bb);
/* Create the map from old to new lp index and initialize it. */
unsigned *index_map = (unsigned *) alloca (lp_len * sizeof (unsigned));
memset (index_map, 0, lp_len * sizeof (unsigned));
/* Fix up the edges. */
for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; )
if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb))
{
rtx_insn *insn = BB_END (e->src);
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
gcc_assert (note != NULL);
const unsigned old_index = INTVAL (XEXP (note, 0));
/* Generate the new landing-pad structure. */
if (index_map[old_index] == 0)
{
eh_landing_pad old_lp = (*cfun->eh->lp_array)[old_index];
eh_landing_pad new_lp = gen_eh_landing_pad (old_lp->region);
new_lp->post_landing_pad = old_lp->post_landing_pad;
new_lp->landing_pad = new_label;
index_map[old_index] = new_lp->index;
}
XEXP (note, 0) = GEN_INT (index_map[old_index]);
/* Adjust the edge to the new destination. */
redirect_edge_succ (e, new_bb);
}
else
ei_next (&ei);
}
/* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions.
Add a new landing pad that will just jump to the old one and split the
edges so that no EH edge crosses partitions. */
static void
fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
dw2_fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
{
eh_landing_pad new_lp;
basic_block new_bb, last_bb;
rtx_insn *jump;
unsigned new_partition;
edge_iterator ei;
edge e;
@ -1428,32 +1507,12 @@ fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
new_lp->landing_pad = gen_label_rtx ();
LABEL_PRESERVE_P (new_lp->landing_pad) = 1;
/* Put appropriate instructions in new bb. */
rtx_code_label *new_label = emit_label (new_lp->landing_pad);
rtx_code_label *old_label = block_label (old_bb);
jump = emit_jump_insn (targetm.gen_jump (old_label));
JUMP_LABEL (jump) = old_label;
/* Create new basic block to be dest for lp. */
last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
new_bb = create_basic_block (new_label, jump, last_bb);
new_bb->aux = last_bb->aux;
new_bb->count = old_bb->count;
last_bb->aux = new_bb;
emit_barrier_after_bb (new_bb);
make_single_succ_edge (new_bb, old_bb, 0);
/* Make sure new bb is in the other partition. */
new_partition = BB_PARTITION (old_bb);
new_partition ^= BB_HOT_PARTITION | BB_COLD_PARTITION;
BB_SET_PARTITION (new_bb, new_partition);
/* Create the forwarder block. */
basic_block new_bb = create_forwarder_block (new_lp->landing_pad, old_bb);
/* Fix up the edges. */
for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; )
if (e->src != new_bb && BB_PARTITION (e->src) == new_partition)
if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb))
{
rtx_insn *insn = BB_END (e->src);
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
@ -1652,9 +1711,11 @@ find_rarely_executed_basic_blocks_and_crossing_edges (void)
/* The format of .gcc_except_table does not allow landing pads to
be in a different partition as the throw. Fix this by either
moving or duplicating the landing pads. */
moving the landing pads or inserting forwarder landing pads. */
if (cfun->eh->lp_array)
{
const bool sjlj
= (targetm_common.except_unwind_info (&global_options) == UI_SJLJ);
unsigned i;
eh_landing_pad lp;
@ -1686,13 +1747,18 @@ find_rarely_executed_basic_blocks_and_crossing_edges (void)
which ^= BB_HOT_PARTITION | BB_COLD_PARTITION;
BB_SET_PARTITION (bb, which);
}
else if (sjlj)
sjlj_fix_up_crossing_landing_pad (bb);
else
fix_up_crossing_landing_pad (lp, bb);
dw2_fix_up_crossing_landing_pad (lp, bb);
/* There is a single, common landing pad in SJLJ mode. */
if (sjlj)
break;
}
}
/* Mark every edge that crosses between sections. */
FOR_EACH_BB_FN (bb, cfun)
FOR_EACH_EDGE (e, ei, bb->succs)
{