This is the mail archive of the
mailing list for the GCC project.
Re: HARD_REGNO_CALL_PART_CLOBBERED and regs_invalidated_by_call
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Matthew Fortune <Matthew dot Fortune at imgtec dot com>
- Cc: "gcc\ at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Sun, 06 Apr 2014 20:14:35 +0100
- Subject: Re: HARD_REGNO_CALL_PART_CLOBBERED and regs_invalidated_by_call
- Authentication-results: sourceware.org; auth=none
- References: <6D39441BF12EF246A7ABCE6654B023534D7B3E at LEMAIL01 dot le dot imgtec dot org> <8761moxjhl dot fsf at talisman dot default> <6D39441BF12EF246A7ABCE6654B023534DB619 at LEMAIL01 dot le dot imgtec dot org>
Matthew Fortune <Matthew.Fortune@imgtec.com> writes:
> Richard Sandiford <email@example.com> writes:
>> Matthew Fortune <Matthew.Fortune@imgtec.com> writes:
>> > Hi Richard,
>> > As part of implementing the new O32 FPXX ABI I am making use of the
>> > HARD_REGNO_CALL_PART_CLOBBERED macro to allow odd-numbered
>> > floating-point registers to be considered as 'normally' callee-saved
>> > but call clobbered if they are being used to hold SImode or SFmode
>> > data. The macro is implemented as:
>> > /* Odd numbered single precision registers are not considered call
>> > for O32 FPXX as they will be clobbered when run on an FR=1 FPU.
>> > #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)
>> > (TARGET_FLOATXX && ((MODE) == SFmode || (MODE) == SImode)
>> > && FP_REG_P (REGNO) && (REGNO & 1))
>> Under these conditions the entire value is call-clobbered though.
>> It might be better to say that the odd-numbered registers are always
>> call-clobbered (which I think is more accurate) but force them to be
>> saved by functions that use them. This is in some ways similar to the
>> way that interrupt handlers save call-clobbered registers.
> The problem here is that these registers form the second part of 64-bit
> call saved registers and therefore have to be marked as call-saved for
> 64-bit values regardless of their behaviour for 32-bit values. I have
> tried to simply mark them as call-clobbered and the effect was that
> 64-bit values ended up being seen as call-clobbered.
> Approaching this problem from both sides leads to complications as O32
> FPXX has a register which behaves differently based on mode. From
> experimentation I believe this approach to be the neatest and use
> existing features of GCC.
>> Maybe some RA heuristics will need tweaking to reflect the extra cost
>> of these registers, but I imagine that's true either way.
> Perhaps. I am currently thinking/hoping that simply having them marked
> as call clobbered will be enough.
FWIW, I have some patches queued for stage 1 that tell the
target-independent code which registers are saved by the current
function. This makes things like interrupt functions less magical.
Maybe it would help with exposing the "call-clobbered and call-saved"
thing to RA.
> In terms of the HARD_REGNO_CALL_PART_CLOBBERED macro. I would say that
> it is poorly named as it gives no indication to GCC internals as to
> which part of the register is clobbered and which is not.
I don't think it was really supposed to matter. (Not that I'm defending
the name. :-))
> When this macro
> returns true GCC simply takes that to mean the whole register is
> clobbered. I'd say that then makes my usage legitimate. If I had time
> and will power I'd remove the 'PART' from this macro and switch over to
> having it as the primary source of call-clobbered information in GCC
> doing away with call_used_regs etc. Having the mode information is quite
> valuable as we are seeing with SIMD ISA extensions that use this macro.
> Supporting two sources of call-clobbered data is probably what lead us to
> the current situation of broken optimisation passes.
Definitely agree with the last part. But I think it'd be better to fix
it the other way: get rid of the existing HARD_REGNO_CALL_PART_CLOBBERED
uses in the generic code and replace things like call_used_regs with
mode-indexed HARD_REG_SETs of the call-clobbered registers. You could
then add a cleaner target interface that says whether a given register
is call-clobbered in a given mode. The default could use the existing
HARD_REGNO_CALL_PART_CLOBBERED, CALL_USED_REGISTERS and
CALL_REALLY_USED_REGISTERS (another horrible part of the interface).
Doing it that way wouldn't involve any changes to port-specific code
other than MIPS. Other ports could use the default implementation
and switch to the new interface later.
I realise that might be more work than you were planning on,
but if you're having to change existing passes anyway then we
might as well fix it in a way that reduces the number of places
that need to check two things instead of one.
All IMO of course. I don't maintain this part of GCC.