https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125266

--- Comment #18 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
(In reply to H.J. Lu from comment #17)
> This scheme won't work for x86 since ix86_conditional_register_usage is
> called on every function.  Each of them may enable/disable a different
> sets of registers.
But AArch64 also allows registers to be enabled and disabled per-function.  For
example, FP registers can be disabled per-function, and SVE registers can be
disabled per-function.  Many targets have something similar.  It's not really
an x86 peculiarity.

> The register set matrix can be quite big.  On x86,
> default_function_abi depends on the set of available registers.  It can
> be different for each function.
In GCC terms, the set of available registers is part of the current "target",
in the sense of target-globals.h.

Logically, the target (set of available registers) and the ABI are different
axes.  They can vary independently.

The system ABI, by convention and definition, has ABI identifier 0.  This is
the "default" ABI.

The documentation of each ABI defines its behaviour for *all* architected
registers.  Thus the GCC ABI identifier (such as ARM_PCS_AAPCS64) has a meaning
that is independent of the current set of available registers.

The final set of call-used registers is defined by a combination of:

- what does the ABI documentation say for register X? (the ABI axis)
- is register X available? (the target axis)

This is what the information in a function_abi represents.

The way this is supposed to work is that you first establish the target.  This
is done using target-globals.h (not by calling reinit_regs).  Usually
target-globals.h is invoked by the set_current_function hook.

Each target then has its own set of function_abi structures.  So we have a
2-dimensional system, indexed by target first and ABI second.

The conditional_register_usage hook should describe the default (system) ABI
for the current target.  This should not depend on cfun.  Other
(target-independent) global state should fully describe the current target,
otherwise target-globals.h won't work correctly.

Non-default ABIs are initialised on demand.  This is not done by
call_used_regs.  It is done by passing the set of call-used/call-clobbered
registers to initialize ().

Thus call_used_regs is only ever used (temporarily) to describe the
system/default ABI for the current target (set of available registers).  It is
never used for other ABIs.

Reply via email to