AM30/AM33 SP handling

Alexandre Oliva aoliva@cygnus.com
Sun Apr 23 07:42:00 GMT 2000


On Apr 22, 2000, Jeffrey A Law <law@cygnus.com> wrote:

>   In message < oraein9nmk.fsf@zecarneiro.lsd.ic.unicamp.br >you write:
>> On Apr 21, 2000, Jeffrey A Law <law@cygnus.com> wrote:
>> 
>> >   In message < orpurj9run.fsf@zecarneiro.lsd.ic.unicamp.br >you write:
>> >> * config/mn10300/mn10300.md (movsi): Move SP handling to
>> >> separate patterns.
>> 
>> > I fail to see the benefit of the movsi change.
>> 
>> Unfortunately, it's necessary to avoid a reload failure.

>> It might work to simply remove the `x' from this entry

It doesn't.

>> but breaking the SP handling allows us to use data registers to
>> copy from/to SP on AM33.

> I would like to see a more detailed analysis of this problem -- testcases,
> rtl dumps and analysis.

Ok, here's a minimal testcase, derived from newlib/libm/math/kf_tan.c:

extern float T[];
float __kernel_tanf() {
	float w;
	return (T[0]+w*(T[2]+w*(T[3]+w*(T[4]+w*(T[1]+w*T[0])))));
}

% cc1 kf_tan.i -O2 -quiet
kf_tan.i: In function `__kernel_tanf':
kf_tan.i:6: Unable to find a register to spill in class `SP_REGS'.
kf_tan.i:6: This is the insn:
(insn 12 148 145 (set (reg:SI 26)
        (plus:SI (reg:SI 26)
            (const_int 8 [0x8]))) 23 {subsi3-1} (insn_list 10 (nil))
    (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("T"))
                (const_int 8 [0x8])))
        (nil)))
kf_tan.i:6: Internal compiler error in `spill_failure', at reload1.c:1825

Registers 23 (w), 26 (T+2) and 31 (T[0]), the ones with the most
conflicts, are not allocated in lreg.  23 and 31 aren't because all
DATA registers are already taken, and 26 isn't because the only
ADDRESS register still available, `a1', isn't preserved across
function calls.

Registers 23 and 31 shouldn't get in trouble because they can only be
allocated to DATA_OR_ADDRESS_REGS; register 26 is the one that
requires SP_OR_ADDRESS_REGS, else DATA_OR_ADDRESS_REGS.

In the lreg dump, I find:

(insn 148 10 12 (set (reg:SI 26)
        (reg:SI 25)) 8 {movsi+1} (nil)
    (nil))

(insn 12 148 145 (set (reg:SI 26)
        (plus:SI (reg:SI 26)
            (const_int 8 [0x8]))) 23 {subsi3-1} (insn_list 10 (nil))
    (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("T"))
                (const_int 8 [0x8])))
        (nil)))

reg 25 is (symbol_ref:SI ("T")), allocated to a0.  The greg dump ends
with:

Spilling for insn 148.
Spilling for insn 12.

but find_reloads() had decided SP_REGS was the best register class for
reg 26, and, since SP cannot be spilled, it loses.


Fortunately, I have a less disruptive solution, whose only drawback is
to not enable moving data regs from/to SP on AM33, which could be
easily done by creating a new AM33-only movsi pattern.  I'll
investigate if there are any gains from that.  Meanwhile, here's the
patch.  Ok to install?



More information about the Gcc-patches mailing list