End scopes before location-less insns From: Alexandre Oliva --- gcc/final.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/gcc/final.c b/gcc/final.c index 1fa93d9..6fab871 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1634,13 +1634,19 @@ choose_inner_scope (tree s1, tree s2) /* Emit lexical block notes needed to change scope from S1 to S2. */ static void -change_scope (rtx_insn *orig_insn, tree s1, tree s2) +change_scope (rtx_insn *prev_insn, rtx_insn *orig_insn, tree s1, tree s2) { rtx_insn *insn = orig_insn; + rtx_insn *einsn; tree com = NULL_TREE; tree ts1 = s1, ts2 = s2; tree s; + if (!prev_insn) + einsn = insn; + else + einsn = NEXT_INSN (prev_insn); + while (ts1 != ts2) { gcc_assert (ts1 && ts2); @@ -1660,7 +1666,7 @@ change_scope (rtx_insn *orig_insn, tree s1, tree s2) s = s1; while (s != com) { - rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn); + rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, einsn); NOTE_BLOCK (note) = s; s = BLOCK_SUPERCONTEXT (s); } @@ -1684,6 +1690,7 @@ reemit_insn_block_notes (void) tree cur_block = DECL_INITIAL (cfun->decl); rtx_insn *insn; rtx_note *note; + rtx_insn *prev_insn = NULL; insn = get_insns (); for (; insn; insn = NEXT_INSN (insn)) @@ -1693,10 +1700,16 @@ reemit_insn_block_notes (void) /* Prevent lexical blocks from straddling section boundaries. */ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS) { + rtx_insn *einsn; + if (prev_insn) + einsn = NEXT_INSN (prev_insn); + else + einsn = insn; + prev_insn = NULL; for (tree s = cur_block; s != DECL_INITIAL (cfun->decl); s = BLOCK_SUPERCONTEXT (s)) { - rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn); + rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, einsn); NOTE_BLOCK (note) = s; note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn); NOTE_BLOCK (note) = s; @@ -1732,14 +1745,16 @@ reemit_insn_block_notes (void) if (this_block != cur_block) { - change_scope (insn, cur_block, this_block); + change_scope (prev_insn, insn, cur_block, this_block); cur_block = this_block; } + + prev_insn = insn; } /* change_scope emits before the insn, not after. */ note = emit_note (NOTE_INSN_DELETED); - change_scope (note, cur_block, DECL_INITIAL (cfun->decl)); + change_scope (NULL, note, cur_block, DECL_INITIAL (cfun->decl)); delete_insn (note); reorder_blocks ();