of the operand the constraint refers to, as well as ref_regno and ref_mode
of the operand @var{opno} the filter depends on additionally.
+Note that either of the regnos can be INVALID_REGNUM to indicate that the
+register allocator hasn't yet allocated a hard reg. For certain kinds
+of filters it is still possible to reject regnos, even if the ref_regno is
+unknown.
+
As such dependent filters are dynamic and cannot be precomputed, it is
advisable to use them very sparingly. Register allocation is a very
compile-time sensitive part of GCC, and too many, or too complicated
dynamic filters may increase the compile time significantly.
-As an example, the riscv port must ensure that for widening vector
-instructions, the destination register group either does not overlap
-or only overlaps specific parts of the source. A dynamic register
-constraint would then be:
+An example for dependent filter usage is the riscv port. It must ensure
+that for widening vector instructions, the destination register group either
+does not overlap the source or only overlaps specific parts it. A dynamic
+register constraint would then be:
@smallexample
(define_register_constraint "Wtt" "V_REGS" "..." "riscv_widen_overlap_ok (regno, mode, ref_regno, ref_mode)" "0")
gcc_assert (ref_opno >= 0 && ref_opno < curr_static_id->n_operands);
rtx ref_op = *curr_id->operand_loc[ref_opno];
+ if (SUBREG_P (ref_op))
+ ref_op = SUBREG_REG (ref_op);
if (!REG_P (ref_op))
return nullptr;
unsigned int ref_regno = REGNO (ref_op);
if (ref_regno >= FIRST_PSEUDO_REGISTER)
{
int ref_hard_regno = reg_renumber[ref_regno];
+ /* Even with a pseudo reference op, the filter can still reject
+ based on the partner. We call it with INVALID_REGNUM
+ to give it a chance to do so. Otherwise we'd introduce
+ an "all choices legal" filter that might later
+ "change its mind" once there is a fixed reference. */
if (ref_hard_regno < 0)
- return nullptr;
+ return lra_get_dependent_filter (id, mode, INVALID_REGNUM,
+ GET_MODE (ref_op), false);
ref_regno = (unsigned int) ref_hard_regno;
}