From 3fa410c0827461ed141fcfcd93e019e0bba8ddc1 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 19 Jul 2017 20:08:07 +0200 Subject: [PATCH] re PR regression/81331 (missed Eh delivery in partitioned function) PR middle-end/81331 * except.c (maybe_add_nop_after_section_switch): New function. (execute): Use it. From-SVN: r250358 --- gcc/ChangeLog | 6 ++++++ gcc/except.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 426577b942b..44b3ba9a54b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-07-19 Jan Hubicka + + PR middle-end/81331 + * except.c (maybe_add_nop_after_section_switch): New function. + (execute): Use it. + 2017-07-19 Tom de Vries * gimple.h (gimple_phi_set_arg): Make assert more strict. diff --git a/gcc/except.c b/gcc/except.c index ffa5b75a465..c77d42cdfee 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2444,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 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 (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. */ @@ -2631,6 +2686,7 @@ public: virtual bool gate (function *); virtual unsigned int execute (function *) { + maybe_add_nop_after_section_switch (); return convert_to_eh_region_ranges (); } -- 2.30.2