Controlling instruction alternative selection

Paul Shortis pshortis@dataworx.com.au
Fri Jul 31 04:55:00 GMT 2015


I'm working with a CPU having a restricted set of registers that can do 
three address maths wheres ALL registers can do two address maths.

If I define

(define_insn "addsi3"
   [     (set (match_operand:SI 0 "register_operand" "=r,r")
                     (plus:SI (match_operand:SI 1 "register_operand" 
"0,0")
                                        (match_operand:SI 2 "rhs_operand" 
"r,i")))

So that all adds are done using 2 address instructions then all is fine. 
If however I change addsi3 to

(where the constraint 'R' is the smaller set of three address registers)

(define_insn "addsi3"
   [     (set (match_operand:SI 0 "register_operand" "=R,r,r")
                     (plus:SI (match_operand:SI 1 "register_operand" 
"R,0,0")
                                        (match_operand:SI 2 "rhs_operand" 
"R,r,i")))


to take advantage of the three address instructions then the three 
address instructions are used successfully on many occassions.

However when register pressure on the 'R' class is high the allocater 
never falls back to using the entire register set by employing the two 
address instructions.

Resulting in ...

error: unable to find a register to spill in class ‘GP_REGS’

enabling lra and inspecting the rtl dump indicates that both 
alternatives (R and r) seem to be equally appealing to the allocater so 
it chooses 'R' and fails.

GCC internals document indicates that the '0' alternates should be 
placed at the end of the alternatives list, so I'm guessing 'R' will 
always be chosen.

Using constraint disparaging (?R) eradicates the errors, but of course 
that causes the 'R' three address alternative to never be used.

Suggestions ?



More information about the Gcc mailing list