Tuesday, March 1, 2011

I found the cause of the repeated "inv" sequences seen below:
movb @M+1, r2
inv r2
inv r2
szcb r2, @L

There was no commutative form for an expression like "A=A&(^B)", so GCC added extra "inv" instructions to fit the one form it had. By adding the commutative form "A=(^B)&A", GCC was able to recognize the redundant work and eliminate it. We now have much nicer output here:
szcb @M+1, r2
movb r2, @L

Unfortunately, this could be made smaller yet:
szcb @M+1, @L

This is the same reluctance to use memory-to-memory instructions I found earlier. I suppose I could make more peepholes for this, but that would explode the pattern count. I would need an optimization matching a pattern like "Rn=FUNC(); mem=Rn" for every instruction in the system. That's a lot of peepholes. At that point, it might be better to try to find a different way to encourace memory-to-memory operations.

Adding this same logic to word-sized not-and operations resulted in an error:

2k_chess.c:122: error: unable to find a register to spill in class ‘REAL_REGS’
this is the insn:
(insn 740 739 742 126 2k_chess.c:112 (set (reg/v:QI 69 [ x ])
(subreg:QI (reg:HI 6 r3 [322]) 1)) 70 {movqi} (expr_list:REG_DEAD (reg:HI 6 r3 [322])
(nil)))
2k_chess.c:122: confused by earlier errors, bailing out

OK... I didn't see that coming. Also, R3 should be available since it would otherwise be free at the end of the instruction. What's in the area of this instruction?

(insn 739 738 740 126 2k_chess.c:112 (set (reg:HI 322)
(and:HI (not:HI (reg:HI 362 [ prephitmp.228 ]))
(reg:HI 322))) 40 {*not_andhi} (nil))

(insn 740 739 742 126 2k_chess.c:112 (set (reg/v:QI 69 [ x ])
(subreg:QI (reg:HI 322) 1)) 70 {movqi} (expr_list:REG_DEAD (reg:HI 322)
(nil)))

Hmm, not good. That's the logic I just fixed.

Note to self: I modified reload1.c to use debug output, this will cause a crash later if not removed.

No comments:

Post a Comment