+2019-09-21 Richard Sandiford <richard.sandiford@arm.com>
+
+ * ira-conflicts.c (can_use_same_reg_p): New function.
+ (process_reg_shuffles): Take an insn parameter. Ignore cases
+ in which input operand op_num could seemingly never be allocated
+ to the same register as the destination.
+ (add_insn_allocno_copies): Update call to process_reg_shuffles.
+
2019-09-21 Richard Sandiford <richard.sandiford@arm.com>
* simplify-rtx.c (neg_const_int): Replace with...
return true;
}
-/* Process all of the output registers of the current insn which are
- not bound (BOUND_P) and the input register REG (its operand number
+/* Return true if output operand OUTPUT and input operand INPUT of
+ INSN can use the same register class for at least one alternative.
+ INSN is already described in recog_data and recog_op_alt. */
+static bool
+can_use_same_reg_p (rtx_insn *insn, int output, int input)
+{
+ alternative_mask preferred = get_preferred_alternatives (insn);
+ for (int nalt = 0; nalt < recog_data.n_alternatives; nalt++)
+ {
+ if (!TEST_BIT (preferred, nalt))
+ continue;
+
+ const operand_alternative *op_alt
+ = &recog_op_alt[nalt * recog_data.n_operands];
+ if (op_alt[input].matches == output)
+ return true;
+
+ if (ira_reg_class_intersect[op_alt[input].cl][op_alt[output].cl]
+ != NO_REGS)
+ return true;
+ }
+ return false;
+}
+
+/* Process all of the output registers of the current insn (INSN) which
+ are not bound (BOUND_P) and the input register REG (its operand number
OP_NUM) which dies in the insn as if there were a move insn between
them with frequency FREQ. */
static void
-process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p)
+process_reg_shuffles (rtx_insn *insn, rtx reg, int op_num, int freq,
+ bool *bound_p)
{
int i;
rtx another_reg;
if (!REG_SUBREG_P (another_reg) || op_num == i
|| recog_data.operand_type[i] != OP_OUT
- || bound_p[i])
+ || bound_p[i]
+ || (!can_use_same_reg_p (insn, i, op_num)
+ && (recog_data.constraints[op_num][0] != '%'
+ || !can_use_same_reg_p (insn, i, op_num + 1))
+ && (op_num == 0
+ || recog_data.constraints[op_num - 1][0] != '%'
+ || !can_use_same_reg_p (insn, i, op_num - 1))))
continue;
process_regs_for_copy (reg, another_reg, false, NULL, freq);
the corresponding allocno copies. The cost will not
correspond to a real move insn cost, so make the frequency
smaller. */
- process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p);
+ process_reg_shuffles (insn, operand, i, freq < 8 ? 1 : freq / 8,
+ bound_p);
}
}
/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
/* { dg-final { scan-assembler-not {\tmov\tz} } } */
-/* At the moment we don't manage to avoid using MOVPRFX for the
- floating-point functions. */
-/* { dg-final { scan-assembler-not {\tmovprfx\t} { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times {\tmovprfx\t} 6 } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
/* { dg-final { scan-assembler-not {\tsel\t} } } */