This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: HARD_REGNO_CALL_PART_CLOBBERED and regs_invalidated_by_call


Matthew Fortune <Matthew.Fortune@imgtec.com> writes:
> Richard Sandiford <rdsandiford@googlemail.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
>> saved
>> >    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.

Ah, OK.

> 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.

Thanks,
Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]