summaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c78
1 files changed, 65 insertions, 13 deletions
diff --git a/gcc/except.c b/gcc/except.c
index 0bf2c2eac0e..4068b68f31f 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -974,7 +974,6 @@ dw2_build_landing_pads (void)
{
basic_block bb;
rtx_insn *seq;
- edge e;
if (lp == NULL || lp->post_landing_pad == NULL)
continue;
@@ -991,9 +990,9 @@ dw2_build_landing_pads (void)
end_sequence ();
bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad));
- e = make_edge (bb, bb->next_bb, e_flags);
- e->count = bb->count;
- e->probability = REG_BR_PROB_BASE;
+ bb->count = bb->next_bb->count;
+ bb->frequency = bb->next_bb->frequency;
+ make_single_succ_edge (bb, bb->next_bb, e_flags);
if (current_loops)
{
struct loop *loop = bb->next_bb->loop_father;
@@ -1183,7 +1182,8 @@ sjlj_emit_function_enter (rtx_code_label *dispatch_label)
emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
TYPE_MODE (integer_type_node), 0,
- dispatch_label, REG_BR_PROB_BASE / 100);
+ dispatch_label,
+ profile_probability::unlikely ());
#else
expand_builtin_setjmp_setup (addr, dispatch_label);
#endif
@@ -1258,7 +1258,6 @@ sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
rtx_insn *seq;
basic_block bb;
eh_region r;
- edge e;
int i, disp_index;
vec<tree> dispatch_labels = vNULL;
@@ -1346,9 +1345,7 @@ sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
rtx_insn *before = label_rtx (lp->post_landing_pad);
bb = emit_to_new_bb_before (seq2, before);
- e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
- e->count = bb->count;
- e->probability = REG_BR_PROB_BASE;
+ make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU);
if (current_loops)
{
struct loop *loop = bb->next_bb->loop_father;
@@ -1386,9 +1383,7 @@ sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
bb = emit_to_new_bb_before (seq, first_reachable_label);
if (num_dispatch == 1)
{
- e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
- e->count = bb->count;
- e->probability = REG_BR_PROB_BASE;
+ make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU);
if (current_loops)
{
struct loop *loop = bb->next_bb->loop_father;
@@ -2449,6 +2444,61 @@ emit_note_eh_region_end (rtx_insn *insn)
return emit_note_after (NOTE_INSN_EH_REGION_END, insn);
}
+/* Add NOP after NOTE_INSN_SWITCH_TEXT_SECTIONS when the cold section starts
+ with landing pad.
+ With landing pad being at offset 0 from the start label of the section
+ we would miss EH delivery because 0 is special and means no landing pad. */
+
+static bool
+maybe_add_nop_after_section_switch (void)
+{
+ if (!crtl->uses_eh_lsda
+ || !crtl->eh.call_site_record_v[1])
+ return false;
+ int n = vec_safe_length (crtl->eh.call_site_record_v[1]);
+ hash_set<rtx_insn *> visited;
+
+ for (int i = 0; i < n; ++i)
+ {
+ struct call_site_record_d *cs
+ = (*crtl->eh.call_site_record_v[1])[i];
+ if (cs->landing_pad)
+ {
+ rtx_insn *insn = as_a <rtx_insn *> (cs->landing_pad);
+ while (true)
+ {
+ /* Landing pads have LABEL_PRESERVE_P flag set. This check make
+ sure that we do not walk past landing pad visited earlier
+ which would result in possible quadratic behaviour. */
+ if (LABEL_P (insn) && LABEL_PRESERVE_P (insn)
+ && visited.add (insn))
+ break;
+
+ /* Conservatively assume that ASM insn may be empty. We have
+ now way to tell what they contain. */
+ if (active_insn_p (insn)
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && GET_CODE (PATTERN (insn)) != ASM_OPERANDS)
+ break;
+
+ /* If we reached the start of hot section, then NOP will be
+ needed. */
+ if (GET_CODE (insn) == NOTE
+ && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
+ {
+ emit_insn_after (gen_nop (), insn);
+ break;
+ }
+
+ /* We visit only labels from cold section. We should never hit
+ begining of the insn stream here. */
+ insn = PREV_INSN (insn);
+ }
+ }
+ }
+ return false;
+}
+
/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
The new note numbers will not refer to region numbers, but
instead to call site entries. */
@@ -2636,7 +2686,9 @@ public:
virtual bool gate (function *);
virtual unsigned int execute (function *)
{
- return convert_to_eh_region_ranges ();
+ int ret = convert_to_eh_region_ranges ();
+ maybe_add_nop_after_section_switch ();
+ return ret;
}
}; // class pass_convert_to_eh_region_ranges