fix mips out-of-range branches

Alexandre Oliva aoliva@redhat.com
Tue Dec 10 22:03:00 GMT 2002


Our mips port has long had a problem that caused it to emit jumps that
the GNU assembler translated to branches that turned out to be out of
range.  The assembler only did this when emitting PIC, because jump to
label is non-PIC, but still, this affected testcases such as
gcc.c-torture/compile/20001226-1.c on IRIX 6, that failed due to
time-outs OR because of assembler's complaints.

I noticed the case of out-of-range branches was covered, but we still
had problems with jumps, so I fixed it, arranging for them to be
emitted as branches when emitting non-embedded PIC, if they're in
range, otherwise by a sequence that loads the branch-target address
into $at and then jumps to it.

However, I noticed that even conditional branches were broken in the
out-of-range case.  We'd emit a jump that would probably be
out-of-range (even though I've never managed to exercise this), and
we'd emit the delay slot after the jump, and branch around it, so the
delay slot would never be executed if the branch was not taken.  This
is correct for branch-likely, but not otherwise.  In case the branch
is not marked as likely, we might just emit the label before the delay
slot, but it's more efficient to place the delay slot next to the
inverted branch, and fill the delay slot of the jump with a nop, since
then we skip entirely the nop in case the (compound) branch is not
taken.

I haven't gone as far as retaining the branch-likely properties by
generating a longer sequence, like I did in the assembler branch
relaxation patch, because (i) I'm not sure it's worth it and (ii) I
wasn't sure whether I could use the information of whether the branch
was marked as likely to compute its length.  So I just use the
likelihood of the original branch to decide whether to place the delay
slot.  I've arranged for out-of-range jumps to be emitted in a
PIC-safe way too.  Also, in case the delay slot is not filled, we no
longer enclose the entire sequence in nomacro/noreorder and thus we no
longer emit nops in this case.  If the delay slot is filled, then the
entire sequence will be enclosed in nomacro/noreorder, and either the
branch or the jump will have its delay slot filled with a nop (a
branch likely split while emitting PIC could have its delay slot
filled with the first instruction of the PIC expansion of la, but then
we'd have to do the expansion at the compiler level, depending on the
ABI, and I didn't feel like going that far; perhaps some day... :-)


I've tested this patch with a bootstrap on mips-sgi-irix6.5.  Since I
was using a gcc that didn't have this patch as the compiler for
stage1, I had to build a few stage1 files with optimization enabled,
otherwise they'd trip on the out-of-range jump-turned-into-branch bug.

For additional coverage, I installed the resulting bootstrapped
compiler, tweaked the limits used to decide whether the branch was
in-range in thelength attribute of jump and branches, from 128Kb to
512 bytes, and bootstrapped again.  Stage1 built correctly without
optimization this time, and bootstrap succeeded.  Yay!

20001226-1.c also passed at -O0 (it used to fail before, when using
gas), but it failed due to compiler time-outs at some higher
optimization levels, which is no news.  Left alone, compilation
eventually succeeds, and the testcase passes.

Oh, I almost forgot to mention: I took out the nonsensical handling of
REGs in the jump pattern: (label_ref (reg)) is never to be generated.
Just to be sure, in my first bootstrap, I replaced the body of the
test for REG with an abort(), and it never hit, so I took it out the
second time.

Ok to install?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcc-mips-jump-out-of-range.patch
Type: text/x-patch
Size: 5761 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20021210/37777320/attachment.bin>
-------------- next part --------------

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                 aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer


More information about the Gcc-patches mailing list