On 2014-06-05, 4:12 PM, Richard Sandiford wrote:
It looks like there's a missing break after the 'G' and 'H' handling.
Tested on x86_64-linux-gnu. I also did an assembly comparison for
a range of targets and Alpha and MIPS seemed to be the only ones
affected. OK to install?
Sorry for the long write-up...
It is long but make me to know new things about Alpha and MIPS insn cases.
By the way, there are a lot of controversy about the changing cost for
particular hard reg. Sometimes it creates a lot of mess in allocation,
when one pseudo involves several hard regs.
Also a lot of alternatives can gives different hard reg preferencing or
wrong ones as we don't know what alternative will be used. Therefore I
think about earlier alternative selections and reg class cost
calculations based on the selected alternatives. But it will be a long
project probably involving code selection too. I don't know how will it
work until it is implemented which will not happen soon.
As I remember I added the code as I see small improvements on x86/x86-64
on benchmarks.
As for the patch, it is ok for me.
Thanks, Richard.
gcc/
* ira-lives.c (single_reg_class): Add missing break. Return NO_REGS
for extra address and memory constraints, not just 'p' and
TARGET_MEM_CONSTRAINT. Likewise if the operand is a constant or
equivalent to a constant and if it matches an extra constraint.
Ignore other non-register operands.
Index: gcc/ira-lives.c
===================================================================
--- gcc/ira-lives.c 2014-06-04 22:15:23.527995920 +0100
+++ gcc/ira-lives.c 2014-06-04 22:15:50.765243138 +0100
@@ -839,7 +839,8 @@ single_reg_class (const char *constraint
&& CONST_DOUBLE_OK_FOR_CONSTRAINT_P (equiv_const,
c, constraints)))
return NO_REGS;
- /* ??? what about memory */
+ break;
+
case 'r':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'j': case 'k': case 'l':
@@ -848,9 +849,22 @@ single_reg_class (const char *constraint
case 'A': case 'B': case 'C': case 'D':
case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'W': case 'Y': case 'Z':
+#ifdef EXTRA_CONSTRAINT_STR
+ /* ??? Is rejecting memory the best thing to do? */
+ if (EXTRA_MEMORY_CONSTRAINT (c, constraints)
+ || EXTRA_ADDRESS_CONSTRAINT (c, constraints))
+ return NO_REGS;
+ if (EXTRA_CONSTRAINT_STR (op, c, constraints)
+ || (equiv_const != NULL_RTX
+ && CONSTANT_P (equiv_const)
+ && EXTRA_CONSTRAINT_STR (equiv_const, c, constraints)))
+ return NO_REGS;
+#endif
next_cl = (c == 'r'
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, constraints));
+ if (next_cl == NO_REGS)
+ break;
if (cl == NO_REGS
? ira_class_singleton[next_cl][GET_MODE (op)] < 0
: (ira_class_singleton[cl][GET_MODE (op)]