Thread View: gnu.gcc.bug
1 messages
1 total messages
Started by Rob McMahon
Sat, 24 Sep 1988 23:38
GCC 1.28 can abort in reload_as_needed
Author: Rob McMahon
Date: Sat, 24 Sep 1988 23:38
Date: Sat, 24 Sep 1988 23:38
103 lines
4074 bytes
4074 bytes
GCC 1.28, Gould PN6030
I hope I can explain this coherently, I'm sorry I can't give a test program.
During the first scan in reload, find_reloads can find a required value via
find_equiv_reg which is no longer available during the second scan in
reload_as_needed, due to reloads having taken place (optional in the case that
I hit). If this means a block which didn't appear to need reloads first time
round now needs a reload, this can mean there is no spill reg available for
it, and the compiler aborts at the new test in reload_as_needed marked by the
comment:
/* If this block has not had spilling done,
...
If we have any non-optionals that need a spill reg, abort. */
The change I've made to get me going is to make find_equiv_reg ignore
instructions with reloads pending, around line 2499 in reload.c:
p = PREV_INSN (p);
if (p == 0 || GET_CODE (p) == CODE_LABEL)
return 0;
=> if (GET_CODE (p) == INSN
/* If we don't want spill regs (true for all calls in this file) */
&& (! (reload_reg_p != 0 && reload_reg_p != (short *)1)
by changing the marked line to be
if (GET_CODE (p) == INSN && GET_MODE (p) == VOIDmode
but I think this may be over conservative.
Here are some commented excerpts from the .lreg file to show what I mean.
FIRST_PSEUDO_REGISTER is 19.
| Register 21 used 7 times across 50 insns; dies in 4 places; crosses calls;
| pointer.
| Register 23 used 11 times across 118 insns; dies in 4 places; crosses calls;
| pref INDEX_REGS; pointer.
| Register 30 used 2 times across 2 insns in block 1; GP_REGS or none.
|
| Basic block 0: first insn 3, last 24.
| Registers live at start: 10 16
|
| Basic block 1: first insn 25, last 29.
| Registers live at start: 10 16 19 20 21 23 24 25
|
| ;; Register 30 in 0.
reload then assigns:
reg_renumber[21] = 7
reg_renumber[23] = -1
reg_renumber[30] = 0
| (insn 5 4 6 (set (reg/v:SI 23)
| (mem:SI (plus:SI (reg:SI 18) (const_int 8)))) 40 (nil)
| (expr_list (mem:SI (plus:SI (reg:SI 18) (const_int 8))) (nil)))
insn 5 gets output reload for reg 23
| (insn 8 7 9 (set (reg/v:SI 21)
| (reg/v:SI 23)) 40 (insn_list 5 (nil))
| (nil))
insn 8 gets optional input reload for reg 23
basic block 0 needs reloads.
| (insn 27 25 28 (set (reg:SI 30)
| (zero_extend:SI (mem/s:QI (plus:SI (reg/v:SI 23)
| (const_int 12))))) 55 (insn_list 25 (nil))
| (expr_list:TI (zero_extend:SI (reg:QI 29)) (nil)))
insn 27 gets reload of reg 23 but finds reg 7 (was pseudo-reg 21) is
equivalent due to insn 8, so basic block 1 needs no reloads.
in reload_as_needed
insn 5 gets reg 3 for its output reload, and becomes
| (insn:QI 5 4 341 (set (reg:SI 3)
| (mem:SI (plus:SI (reg:SI 18) (const_int 8)))) 40 (nil)
| (expr_list (mem:SI (plus:SI (reg:SI 18) (const_int 8))) (nil)))
|
| (insn 341 5 6 (set (reg/v:SI 23)
| (reg:SI 3)) -1 (nil)
| (expr_list:QI (reg:SI 3) (nil)))
insn 8 takes up on its optional reload, finding reg 23 still around in reg 3,
and becomes
| (insn:QI 8 7 9 (set (reg/v:SI 7)
| (reg:SI 3)) 40 (insn_list 5 (nil))
| (nil))
insn 27 now can't find an equivalent. insn 8 is not what it was, insn 341 is
unusable because it is a reload insn. So the instruction suddenly needs a
reload, but basic_block_needs is 0 for this block, so reload_as_needed aborts.
Hope this isn't too incomprehensible.
Rob
--
UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037
JANET: cudcv@uk.ac.warwick ARPA: cudcv@warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads