The following macros control mode switching optimizations:
Define this macro if the port needs extra instructions inserted for mode switching.
For an example, the SH4 can perform both single and double precision
floating point operations, but to perform a single precision operation,
the FPSCR PR bit has to be cleared, while for a double precision
operation, this bit has to be set. Changing the PR bit requires a general
purpose register as a scratch register, hence these FPSCR sets have to
be inserted before reload, i.e. you cannot put this into instruction emitting
or TARGET_MACHINE_DEPENDENT_REORG
.
You can have multiple entities that are mode-switched, some of which might
only be needed conditionally. The entities are identified by their index
into the NUM_MODES_FOR_MODE_SWITCHING
initializer, with the length
of the initializer determining the number of entities.
OPTIMIZE_MODE_SWITCHING
should return nonzero for any entity
that needs mode-switching.
If you define this macro, you also have to define
NUM_MODES_FOR_MODE_SWITCHING
, TARGET_MODE_NEEDED
,
TARGET_MODE_PRIORITY
and TARGET_MODE_EMIT
.
The other macros in this section are optional.
If you define OPTIMIZE_MODE_SWITCHING
, you have to define this as
initializer for an array of integers. Each initializer element
N refers to an entity that needs mode switching, and specifies the number
of different modes that are defined for that entity.
The position of the element in the initializer—starting counting at
zero—determines the integer that is used to refer to the mode-switched
entity in question.
Modes are represented as numbers 0 … N − 1.
In mode arguments and return values, N either represents an unknown
mode or “no mode”, depending on context.
void
TARGET_MODE_EMIT (int entity, int mode, int prev_mode, HARD_REG_SET regs_live)
¶Generate one or more insns to set entity to mode. hard_reg_live is the set of hard registers live at the point where the insn(s) are to be inserted. prev_moxde indicates the mode to switch from, or is the number of modes if the previous mode is not known. Sets of a lower numbered entity will be emitted before sets of a higher numbered entity to a mode of the same or lower priority.
int
TARGET_MODE_NEEDED (int entity, rtx_insn *insn, HARD_REG_SET regs_live)
¶entity is an integer specifying a mode-switched entity.
If OPTIMIZE_MODE_SWITCHING
is defined, you must define this hook
to return the mode that entity must be switched into prior to the
execution of insn, or the number of modes if insn has no
such requirement. regs_live contains the set of hard registers
that are live before insn.
int
TARGET_MODE_AFTER (int entity, int mode, rtx_insn *insn, HARD_REG_SET regs_live)
¶entity is an integer specifying a mode-switched entity. If this hook is defined, it is evaluated for every insn during mode switching. It returns the mode that entity is in after insn has been executed. mode is the mode that entity was in before insn was executed, taking account of TARGET_MODE_NEEDED. regs_live is the set of hard registers that are live after insn has been executed.
mode is equal to the number of modes defined for entity if the mode before insn is unknown. The hook should likewise return the number of modes if it does not know what mode entity has after insn.
Not defining the hook is equivalent to returning mode.
int
TARGET_MODE_CONFLUENCE (int entity, int mode1, int mode2)
¶By default, the mode-switching pass assumes that a given entity’s modes
are mutually exclusive. This means that the pass can only tell
TARGET_MODE_EMIT
about an entity’s previous mode if all
incoming paths of execution leave the entity in the same state.
However, some entities might have overlapping, non-exclusive modes, so that it is sometimes possible to represent “mode mode1 or mode mode2” with something more specific than “mode not known”. If this is true for at least one entity, you should define this hook and make it return a mode that includes mode1 and mode2 as possibilities. (The mode can include other possibilities too.) The hook should return the number of modes if no suitable mode exists for the given arguments.
int
TARGET_MODE_BACKPROP (int entity, int mode1, int mode2)
¶If defined, the mode-switching pass uses this hook to back-propagate mode requirements through blocks that have no mode requirements of their own. Specifically, mode1 is the mode that entity has on exit from a block B1 (say) and mode2 is the mode that the next block requires entity to have. B1 does not have any mode requirements of its own.
The hook should return the mode that it prefers or requires entity
to have in B1, or the number of modes if there is no such requirement.
If the hook returns a required mode for more than one of B1’s outgoing
edges, those modes are combined as for TARGET_MODE_CONFLUENCE
.
For example, suppose there is a “one-shot” entity that, for a given execution of a function, either stays off or makes exactly one transition from off to on. It is safe to make the transition at any time, but it is better not to do so unnecessarily. This hook allows the function to manage such an entity without having to track its state at runtime. Specifically. the entity would have two modes, 0 for off and 1 for on, with 2 representing “don’t know”. The system is forbidden from transitioning from 2 to 1, since 2 represents the possibility that the entity is already on (and the aim is to avoid having to emit code to check for that case). This hook would therefore return 1 when mode1 is 2 and mode2 is 1, which would force the entity to be on in the source block. Applying this inductively would remove all transitions in which the previous state is unknown.
int
TARGET_MODE_ENTRY (int entity)
¶If this hook is defined, it is evaluated for every entity that
needs mode switching. It should return the mode that entity is
guaranteed to be in on entry to the function, or the number of modes
if there is no such guarantee.
If TARGET_MODE_ENTRY
is defined then TARGET_MODE_EXIT
must be defined.
int
TARGET_MODE_EXIT (int entity)
¶If this hook is defined, it is evaluated for every entity that
needs mode switching. It should return the mode that entity must
be in on return from the function, or the number of modes if there is no
such requirement.
If TARGET_MODE_EXIT
is defined then TARGET_MODE_ENTRY
must be defined.
int
TARGET_MODE_EH_HANDLER (int entity)
¶If this hook is defined, it should return the mode that entity is guaranteed to be in on entry to an exception handler, or the number of modes if there is no such guarantee.
int
TARGET_MODE_PRIORITY (int entity, int n)
¶This hook specifies the order in which modes for entity
are processed. 0 is the highest priority,
NUM_MODES_FOR_MODE_SWITCHING[entity] - 1
the lowest.
The hook returns an integer designating a mode
for entity. For any fixed entity, mode_priority
(entity, n) shall be a bijection in 0 …
num_modes_for_mode_switching[entity] - 1
.