diff options
author | Michel Zou | 2018-05-08 11:43:51 +0200 |
---|---|---|
committer | Michel Zou | 2018-05-08 11:43:51 +0200 |
commit | 6a20f3893557bcad3c9ba55c02ec8e08740856da (patch) | |
tree | 41e29f0dec422f5b992629a6fd0053e7ec319c5b /bz85638.patch | |
parent | c34776bae81b7accdb6ae939e830f72bba3a8319 (diff) | |
download | aur-6a20f3893557bcad3c9ba55c02ec8e08740856da.tar.gz |
8.1.0
Diffstat (limited to 'bz85638.patch')
-rw-r--r-- | bz85638.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/bz85638.patch b/bz85638.patch new file mode 100644 index 000000000000..9ed00e836d3c --- /dev/null +++ b/bz85638.patch @@ -0,0 +1,180 @@ +--- gcc/bb-reorder.c (revision 259642) ++++ gcc/bb-reorder.c (working copy) +@@ -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_ + 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); +@@ -1651,9 +1710,11 @@ find_rarely_executed_basic_blocks_and_cr + + /* 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; + +@@ -1685,13 +1746,18 @@ find_rarely_executed_basic_blocks_and_cr + 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) + { |