Fix PR rtl-optimization/45593
Eric Botcazou
ebotcazou@adacore.com
Wed Sep 15 23:59:00 GMT 2010
This is a segfault compiling the kernel at -Os for the SPARC, a regression
present on the mainline and 4.5 branch. The crash occurs during delay slot
scheduling, aka reorg.
We start with an insn that is put into a delay slot by fill_simple_delay_slots
during the first reorg pass; it is only copied and not deleted. Then it is
put into a second delay slot by fill_eager_delay_slots, re-copied and still
not deleted. Then fill_eager_delay_slots, upon attempting to put it into a
third delay slot, notices that the insn is now redundant with the copy of
itself(!) put into the second delay slot and finally deletes it from its
original place. Then relax_delay_slots kicks in and remarks that the cond
jump owning the second delay slot jumps to the next instruction; therefore it
re-emits the insn that was in the second delay slot as a stand-alone insn and
deletes the jump. In the end, the insn has been copied into a delay slot and
hoisted in the stream; in particular, its basic block changed.
These transformations are interleaved with queries to mark_target_live_regs
which needs to know for each insn the basic block it can use to start
computing liveness info from. The results are cached in a hash table indexed
by the INSN_UID of the insns. Although insns are copied as a whole when they
are put into delay slots, INSN_UID included, this works because m_t_l_r
doesn't look within SEQUENCEs to compute the basic block; only the enclosing
insn is looked at and these insns don't move.
Things go awry when relax_delay_slots re-emits insns that were in delay slots
as stand-alone insns, because they are re-emitted as-is and thus we end up
with several top-level insns with the same INSN_UID in the stream, which of
course mightily confuses the caching done for mark_target_live_regs. That's
what happens here and causes the crash during the second reorg pass.
A radical fix could be to hash the insns themselves instead of their INSN_UID
but that's probably overkill. So the patch just makes sure the INSN_UID of
the insns is changed where they are re-emitted in relax_delay_slots.
Bootstrapped/regtesed on sparc-sun-solaris2.8 and sparc64-sun-solaris2.9,
applied on the mainline and 4.5 branch.
2010-09-15 Eric Botcazou <ebotcazou@adacore.com>
PR rtl-optimization/45593
* reorg.c (relax_delay_slots): Use emit_copy_of_insn_after to re-emit
insns that were in delay slots as stand-alone insns.
2010-09-15 Eric Botcazou <ebotcazou@adacore.com>
* gcc.c-torture/compile/20100915-1.c: New test.
--
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr45593.diff
Type: text/x-diff
Size: 2886 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20100915/2e1862d0/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 20100915-1.c
Type: text/x-csrc
Size: 1986 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20100915/2e1862d0/attachment-0001.bin>
More information about the Gcc-patches
mailing list