This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix up var-tracking notes emitted in between bbs (PR middle-end/43631)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Alexandre Oliva <aoliva at redhat dot com>, Steven Bosscher <stevenb dot gcc at gmail dot com>
- Date: Thu, 15 Nov 2012 00:02:29 +0100
- Subject: [PATCH] Fix up var-tracking notes emitted in between bbs (PR middle-end/43631)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Steven has been complaining for some years that var-tracking inserts
NOTE_INSN_VAR_LOCATION (and NOTE_INSN_CALL_ARG_LOCATION) notes sometimes
in between basic blocks, but with BLOCK_FOR_INSN set (or sometimes extends
a bb ending originally with a noreturn or throwing call by a note or more
after it). Fixed thusly, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk?
2012-11-14 Jakub Jelinek <jakub@redhat.com>
PR middle-end/43631
* var-tracking.c (emit_note_insn_var_location, emit_notes_in_bb):
Clear BLOCK_FOR_INSN on notes emitted in between basic blocks,
don't adjust BB_END when inserting note after BB_END of some bb.
--- gcc/var-tracking.c.jj 2012-11-13 10:54:06.000000000 +0100
+++ gcc/var-tracking.c 2012-11-13 11:35:31.668284140 +0100
@@ -8566,9 +8566,30 @@ emit_note_insn_var_location (void **varp
|| NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
else
- note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
+ {
+ note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
+ /* If insn is BB_HEAD of some bb, make sure the note
+ doesn't have BLOCK_FOR_INSN set. The notes don't
+ extend the extents of a basic block, and e.g. notes emitted
+ for differences in between basic blocks should live in between
+ the basic blocks. */
+ if (BLOCK_FOR_INSN (note)
+ && BB_HEAD (BLOCK_FOR_INSN (note)) == insn)
+ set_block_for_insn (note, NULL);
+ }
}
NOTE_VAR_LOCATION (note) = note_vl;
+ /* If insn is BB_END of some bb, make sure the note
+ doesn't have BLOCK_FOR_INSN set. The notes don't
+ extend the extents of a basic block, and e.g. a noreturn
+ call can still be followed by NOTE_INSN_CALL_ARG_LOCATION. */
+ if (BLOCK_FOR_INSN (note)
+ && BB_END (BLOCK_FOR_INSN (note)) == note
+ && PREV_INSN (note) == insn)
+ {
+ BB_END (BLOCK_FOR_INSN (note)) = insn;
+ set_block_for_insn (note, NULL);
+ }
set_dv_changed (var->dv, false);
gcc_assert (var->in_changed_variables);
@@ -8936,6 +8957,16 @@ emit_notes_in_bb (basic_block bb, datafl
}
note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
NOTE_VAR_LOCATION (note) = arguments;
+ /* If insn is BB_END of some bb, make sure the note
+ doesn't have BLOCK_FOR_INSN set. The notes don't
+ extend the extents of a basic block, and e.g. a noreturn
+ call can still be followed by NOTE_INSN_CALL_ARG_LOCATION. */
+ if (BLOCK_FOR_INSN (note)
+ && BB_END (BLOCK_FOR_INSN (note)) == note)
+ {
+ BB_END (BLOCK_FOR_INSN (note)) = insn;
+ set_block_for_insn (note, NULL);
+ }
}
break;
Jakub