This is about addressing modes.
A C expression that is nonzero if the machine supports pre-increment, pre-decrement, post-increment, or post-decrement addressing respectively.
A C expression that is nonzero if the machine supports pre- or post-address side-effect generation involving constants other than the size of the memory operand.
A C expression that is nonzero if the machine supports pre- or post-address side-effect generation involving a register displacement.
A C expression that is 1 if the RTX x is a constant which
is a valid address. On most machines the default definition of
(CONSTANT_P (x) && GET_CODE (x) != CONST_DOUBLE)
is acceptable, but a few machines are more restrictive as to which
constant addresses are supported.
CONSTANT_P, which is defined by target-independent code,
accepts integer-values expressions whose values are not explicitly
known, such as
const arithmetic expressions, in addition to
A number, the maximum number of registers that can appear in a valid
memory address. Note that it is up to you to specify a value equal to
the maximum number that
TARGET_LEGITIMATE_ADDRESS_P would ever
A function that returns whether x (an RTX) is a legitimate memory address on the target machine for a memory operand of mode mode.
Legitimate addresses are defined in two variants: a strict variant and a non-strict one. The strict parameter chooses which variant is desired by the caller.
The strict variant is used in the reload pass. It must be defined so
that any pseudo-register that has not been allocated a hard register is
considered a memory reference. This is because in contexts where some
kind of register is required, a pseudo-register with no hard register
must be rejected. For non-hard registers, the strict variant should look
reg_renumber array; it should then proceed using the hard
register number in the array, or treat the pseudo as a memory reference
if the array holds
The non-strict variant is used in other passes. It must be defined to accept all pseudo-registers in every context where some kind of register is required.
Normally, constant addresses which are the sum of a
and an integer are stored inside a
const RTX to mark them as
constant. Therefore, there is no need to recognize such sums
specifically as legitimate addresses. Normally you would simply
const as legitimate.
PRINT_OPERAND_ADDRESS is not prepared to handle constant
sums that are not marked with
const. It assumes that a naked
plus indicates indexing. If so, then you must reject such
naked constant sums as illegitimate addresses, so that none of them will
be given to
On some machines, whether a symbolic address is legitimate depends on
the section that the address refers to. On these machines, define the
TARGET_ENCODE_SECTION_INFO to store the information
symbol_ref, and then check for it here. When you see a
const, you will have to look inside it to find the
symbol_ref in order to determine the section. See Assembler Format.
Some ports are still using a deprecated legacy substitute for
this hook, the
GO_IF_LEGITIMATE_ADDRESS macro. This macro
has this syntax:
#define GO_IF_LEGITIMATE_ADDRESS (mode, x, label)
goto label if the address x is a valid
address on the target machine for a memory operand of mode mode.
Compiler source files that want to use the strict variant of this
macro define the macro
REG_OK_STRICT. You should use an
#ifdef REG_OK_STRICT conditional to define the strict variant in
that case and the non-strict variant otherwise.
Using the hook is usually simpler because it limits the number of files that are recompiled when changes are made.
A single character to be used instead of the default
character for general memory addresses. This defines the constraint
letter which matches the memory addresses accepted by
TARGET_LEGITIMATE_ADDRESS_P. Define this macro if you want to
support new address formats in your back end without changing the
semantics of the
'm' constraint. This is necessary in order to
preserve functionality of inline assembly constructs using the
A C expression to determine the base term of address x,
or to provide a simplified version of x from which alias.cc
can easily find the base term. This macro is used in only two places:
find_base_term in alias.cc.
It is always safe for this macro to not be defined. It exists so that alias analysis can understand machine-dependent addresses.
The typical use of this macro is to handle addresses containing a label_ref or symbol_ref within an UNSPEC.
This hook is given an invalid memory address x for an operand of mode mode and should try to return a valid memory address.
x will always be the result of a call to
and oldx will be the operand that was given to that function to produce
The code of the hook should not alter the substructure of x. If it transforms x into a more legitimate form, it should return the new x.
It is not necessary for this hook to come up with a legitimate address, with the exception of native TLS addresses (see Emulated TLS). The compiler has standard ways of doing so in all cases. In fact, if the target supports only emulated TLS, it is safe to omit this hook or make it return x if it cannot find a valid way to legitimize the address. But often a machine-dependent strategy can generate better code.
A C compound statement that attempts to replace x, which is an address that needs reloading, with a valid memory address for an operand of mode mode. win will be a C statement label elsewhere in the code. It is not necessary to define this macro, but it might be useful for performance reasons.
For example, on the i386, it is sometimes possible to use a single
reload register instead of two by reloading a sum of two pseudo
registers into a register. On the other hand, for number of RISC
processors offsets are limited so that often an intermediate address
needs to be generated in order to address a stack slot. By defining
LEGITIMIZE_RELOAD_ADDRESS appropriately, the intermediate addresses
generated for adjacent some stack slots can be made identical, and thus
Note: This macro should be used with caution. It is necessary to know something of how reload works in order to effectively use this, and it is quite easy to produce macros that build in too much knowledge of reload internals.
Note: This macro must be able to reload an address created by a previous invocation of this macro. If it fails to handle such addresses then the compiler may generate incorrect code or abort.
The macro definition should use
push_reload to indicate parts that
need reloading; opnum, type and ind_levels are usually
suitable to be passed unaltered to
The code generated by this macro must not alter the substructure of
x. If it transforms x into a more legitimate form, it
should assign x (which will always be a C variable) a new value.
This also applies to parts that you change indirectly by calling
The macro definition may use
strict_memory_address_p to test if
the address has become legitimate.
If you want to change only a part of x, one standard way of doing
this is to use
copy_rtx. Note, however, that it unshares only a
single level of rtl. Thus, if the part to be changed is not at the
top level, you’ll need to replace first the top level.
It is not necessary for this macro to come up with a legitimate
address; but often a machine-dependent strategy can generate better code.
This hook returns
true if memory address addr in address
space addrspace can have
different meanings depending on the machine mode of the memory
reference it is used for or if the address is valid for some modes
but not others.
Autoincrement and autodecrement addresses typically have mode-dependent effects because the amount of the increment or decrement is the size of the operand being addressed. Some machines have other mode-dependent addresses. Many RISC machines have no mode-dependent addresses.
You may assume that addr is a valid address for the machine.
The default version of this hook returns
This hook returns true if x is a legitimate constant for a
mode-mode immediate operand on the target machine. You can assume that
CONSTANT_P, so you need not check this.
The default definition returns true.
This hook returns true if x is a TLS operand on the target
machine that should be pre-computed when used as the argument in a call.
You can assume that x satisfies
CONSTANT_P, so you need not
The default definition returns false.
This hook is used to undo the possibly obfuscating effects of the
macros. Some backend implementations of these macros wrap symbol
references inside an
UNSPEC rtx to represent PIC or similar
addressing modes. This target hook allows GCC’s optimizers to understand
the semantics of these opaque
UNSPECs by converting them back
into their original form.
This hook should return true if x should not be emitted into debug sections.
This hook should return true if x is of a form that cannot (or should not) be spilled to the constant pool. mode is the mode of x.
The default version of this hook returns false.
The primary reason to define this hook is to prevent reload from deciding that a non-legitimate constant would be better reloaded from the constant pool instead of spilling and reloading a register holding the constant. This restriction is often true of addresses of TLS symbols for various targets.
This hook should return true if pool entries for constant x can
be placed in an
object_block structure. mode is the mode
The default version returns false for all constants.
This hook should return true if pool entries for decl should
be placed in an
The default version returns true for all decls.
This hook should return the DECL of a function that implements the
reciprocal of the machine-specific builtin function fndecl, or
NULL_TREE if such a function is not available.
This hook should return the DECL of a function f that given an address addr as an argument returns a mask m that can be used to extract from two vectors the relevant data that resides in addr in case addr is not properly aligned.
The autovectorizer, when vectorizing a load operation from an address
addr that may be unaligned, will generate two vector loads from
the two aligned addresses around addr. It then generates a
REALIGN_LOAD operation to extract the relevant data from the
two loaded vectors. The first two arguments to
v1 and v2, are the two vectors, each of size VS, and
the third argument, OFF, defines how the data will be extracted
from these two vectors: if OFF is 0, then the returned vector is
v2; otherwise, the returned vector is composed from the last
VS-OFF elements of v1 concatenated to the first
OFF elements of v2.
If this hook is defined, the autovectorizer will generate a call
to f (using the DECL tree that this hook returns) and will
use the return value of f as the argument OFF to
REALIGN_LOAD. Therefore, the mask m returned by f
should comply with the semantics expected by
If this hook is not defined, then addr will be used as
the argument OFF to
REALIGN_LOAD, in which case the low
log2(VS) - 1 bits of addr will be considered.
Returns cost of different scalar or vector statements for vectorization cost model. For vector memory operations the cost may depend on type (vectype) and misalignment value (misalign).
This hook returns the preferred alignment in bits for accesses to
vectors of type type in vectorized code. This might be less than
or greater than the ABI-defined value returned by
TARGET_VECTOR_ALIGNMENT. It can be equal to the alignment of
a single element, in which case the vectorizer will not try to optimize
The default hook returns
TYPE_ALIGN (type), which is
correct for most targets.
Return true if vector alignment is reachable (by peeling N iterations) for the given scalar type type. is_packed is false if the scalar access using type is known to be naturally aligned.
This hook is used to test whether the target can permute up to two
vectors of mode op_mode using the permutation vector
producing a vector of mode mode. The hook is also used to emit such
When the hook is being used to test whether the target supports a permutation, in0, in1, and out are all null. When the hook is being used to emit a permutation, in0 and in1 are the source vectors of mode op_mode and out is the destination vector of mode mode. in1 is the same as in0 if sel describes a permutation on one vector instead of two.
Return true if the operation is possible, emitting instructions for it if rtxes are provided.
If the hook returns false for a mode with multibyte elements, GCC will try the equivalent byte operation. If that also fails, it will try forcing the selector into a register and using the vec_permmode instruction pattern. There is no need for the hook to handle these two implementation approaches itself.
This hook is used to test whether the target has a special method of division of vectors of type vectype using the value constant, and producing a vector of type vectype. The division will then not be decomposed by the vectorizer and kept as a div.
When the hook is being used to test whether the target supports a special divide, in0, in1, and output are all null. When the hook is being used to emit a division, in0 and in1 are the source vectors of type vecttype and output is the destination vector of type vectype.
Return true if the operation is possible, emitting instructions for it if rtxes are provided and updating output.
This hook should return the decl of a function that implements the
vectorized variant of the function with the
NULL_TREE if such a function is not available.
The return type of the vectorized function shall be of vector type
vec_type_out and the argument types should be vec_type_in.
This hook should return the decl of a function that implements the
vectorized variant of target built-in function
return type of the vectorized function shall be of vector type
vec_type_out and the argument types should be vec_type_in.
This hook should return true if the target supports misaligned vector store/load of a specific factor denoted in the misalignment parameter. The vector store/load should be of machine mode mode and the elements in the vectors should be of type type. is_packed parameter is true if the memory access is defined in a packed struct.
This hook should return the preferred mode for vectorizing scalar
mode mode. The default is
word_mode, because the vectorizer can do some
transformations even in absence of specialized SIMD hardware.
This hook should return the preferred mode to split the final reduction step on mode to. The reduction is then carried out reducing upper against lower halves of vectors recursively until the specified mode is reached. The default is mode which means no splitting.
If using the mode returned by
is not the only approach worth considering, this hook should add one mode to
modes for each useful alternative approach. These modes are then
TARGET_VECTORIZE_RELATED_MODE to obtain the vector mode
for a given element mode.
The modes returned in modes should use the smallest element mode
possible for the vectorization approach that they represent, preferring
integer modes over floating-poing modes in the event of a tie. The first
mode should be the
TARGET_VECTORIZE_PREFERRED_SIMD_MODE for its
If all is true, add suitable vector modes even when they are generally not expected to be worthwhile.
The hook returns a bitmask of flags that control how the modes in modes are used. The flags are:
Tells the loop vectorizer to try all the provided modes and pick the one with the lowest cost. By default the vectorizer will choose the first mode that works.
The hook does not need to do anything if the vector returned by
TARGET_VECTORIZE_PREFERRED_SIMD_MODE is the only one relevant
for autovectorization. The default implementation adds no modes and
If a piece of code is using vector mode vector_mode and also wants
to operate on elements of mode element_mode, return the vector mode
it should use for those elements. If nunits is nonzero, ensure that
the mode has exactly nunits elements, otherwise pick whichever vector
size pairs the most naturally with vector_mode. Return an empty
opt_machine_mode if there is no supported vector mode with the
There is no prescribed way of handling the case in which nunits is zero. One common choice is to pick a vector mode with the same size as vector_mode; this is the natural choice if the target has a fixed vector size. Another option is to choose a vector mode with the same number of elements as vector_mode; this is the natural choice if the target has a fixed number of elements. Alternatively, the hook might choose a middle ground, such as trying to keep the number of elements as similar as possible while applying maximum and minimum vector sizes.
The default implementation uses
mode_for_vector to find the
requested mode, returning a mode with the same size as vector_mode
when nunits is zero. This is the correct behavior for most targets.
Return the mode to use for a vector mask that holds one boolean
result for each element of vector mode mode. The returned mask mode
can be a vector of integers (class
MODE_VECTOR_INT), a vector of
MODE_VECTOR_BOOL) or a scalar integer (class
MODE_INT). Return an empty
opt_machine_mode if no such
mask mode exists.
The default implementation returns a
MODE_VECTOR_INT with the
same size and number of elements as mode, if such a mode exists.
This hook returns true if masked internal function ifn (really of
internal_fn) should be considered expensive when the mask is
all zeros. GCC can then try to branch around the instruction instead.
This hook should initialize target-specific data structures in preparation for modeling the costs of vectorizing a loop or basic block. The default allocates three unsigned integers for accumulating costs for the prologue, body, and epilogue of the loop or basic block. If loop_info is non-NULL, it identifies the loop being vectorized; otherwise a single block is being vectorized. If costing_for_scalar is true, it indicates the current cost model is for the scalar version of a loop or block; otherwise it is for the vector version.
Target builtin that implements vector gather operation. mem_vectype
is the vector type of the load and index_type is scalar type of
the index, scaled by scale.
The default is
NULL_TREE which means to not vectorize gather
Target builtin that implements vector scatter operation. vectype
is the vector type of the store and index_type is scalar type of
the index, scaled by scale.
The default is
NULL_TREE which means to not vectorize scatter
This hook should set vecsize_mangle, vecsize_int, vecsize_float fields in simd_clone structure pointed by clone_info argument and also simdlen field if it was previously 0. vecsize_mangle is a marker for the backend only. vecsize_int and vecsize_float should be left zero on targets where the number of lanes is not determined by the bitsize (in which case simdlen is always used). The hook should return 0 if SIMD clones shouldn’t be emitted, or number of vecsize_mangle variants that should be emitted.
This hook should add implicit
to SIMD clone node if needed.
This hook should return -1 if SIMD clone node shouldn’t be used in vectorized loops in current function, or non-negative number if it is usable. In that case, the smaller the number is, the more desirable it is to use it.
Return number of threads in SIMT thread group on the target.
Return 1 if trait name is present in the OpenMP context’s device trait set, return 0 if not present in any OpenMP context in the whole translation unit, or -1 if not present in the current OpenMP context but might be present in another OpenMP context in the same TU.
This hook should check the launch dimensions provided for an OpenACC compute region, or routine. Defaulted values are represented as -1 and non-constant values as 0. The fn_level is negative for the function corresponding to the compute region. For a routine it is the outermost level at which partitioned execution may be spawned. The hook should verify non-default values. If DECL is NULL, global defaults are being validated and unspecified defaults should be filled in. Diagnostics should be issued as appropriate. Return true, if changes have been made. You must override this hook to provide dimensions larger than 1.
This hook should return the maximum size of a particular dimension, or zero if unbounded.
This hook can be used to convert IFN_GOACC_FORK and IFN_GOACC_JOIN function calls to target-specific gimple, or indicate whether they should be retained. It is executed during the oacc_device_lower pass. It should return true, if the call should be retained. It should return false, if it is to be deleted (either because target-specific gimple has been inserted before it, or there is no need for it). The default hook returns false, if there are no RTL expanders for them.
This hook is used by the oacc_transform pass to expand calls to the GOACC_REDUCTION internal function, into a sequence of gimple instructions. call is gimple statement containing the call to the function. This hook removes statement call after the expanded sequence has been inserted. This hook is also responsible for allocating any storage for reductions when necessary.
This hook returns the target’s preferred final argument for a call
to conditional internal function ifn (really of type
internal_fn). type specifies the return type of the
function and ops are the operands to the conditional operation,
of which there are nops.
For example, if ifn is
IFN_COND_ADD, the hook returns
a value of type type that should be used when ‘ops’
and ‘ops’ are conditionally added together.
This hook is only relevant if the target supports conditional patterns
cond_addm. The default implementation returns a zero
constant of type type.
This hook, if defined, is used by accelerator target back-ends to adjust
OpenACC variable declarations that should be made private to the given
parallelism level (i.e.
GOMP_DIM_VECTOR). A typical use for this hook is to force variable
declarations at the
gang level to reside in GPU shared memory.
loc may be used for diagnostic purposes.
You may also use the
TARGET_GOACC_EXPAND_VAR_DECL hook if the
adjusted variable declaration needs to be expanded to RTL in a non-standard
This hook, if defined, is used by accelerator target back-ends to expand
specially handled kinds of
VAR_DECL expressions. A particular use is
to place variables with specific attributes inside special accelarator
memories. A return value of
NULL indicates that the target does not
VAR_DECL, and normal RTL expanding is resumed.
Only define this hook if your accelerator target needs to expand certain
VAR_DECL nodes in a way that differs from the default. You can also adjust
private variables at OpenACC device-lowering time using the
TARGET_GOACC_ADJUST_PRIVATE_DECL target hook.
Create a record used to propagate local-variable state from an active worker to other workers. A possible implementation might adjust the type of REC to place the new variable in shared GPU memory.
Presence of this target hook indicates that middle end neutering/broadcasting be used.
Lay out a fixed shared-memory region on the target. The LO and HI arguments should be set to a range of addresses that can be used for worker broadcasting. The dimensions, reduction size and gang-private size arguments are for the current offload region.