Extension to compare-elim

Paulo J. Matos paulo@matos-sorge.com
Tue May 15 13:00:00 GMT 2012


Hi,

I am looking at a missed optimization and I think this is something that 
could be added to compare-elim, if it's not already done somewhere else. 
I have a double word comparison to zero, so in C it's:
int le(long a) { return a <= 0; }

My expand uses the following transformation (in my current discussion y0 
and y1 are 0):
    if x0:x1 <= y0:y1 goto L
==>
    if x0 < y0 goto L
    if x0 > y0 goto K
    if x1 <= y1 goto L
K:


This generates the assembler:
$le:
         tst     @$XAP_AH
         bmi ?L7
         cmp     AH,#H'0000
         bgt ?L3
         tst     @$XAP_AL
         bne ?L3
?L7:
         ld      AL,#H'0001
         bra     0,X
?L3:
         ld      AL,#H'0000
         bra     0,X

My argument is that the tst @$XAP_AH above could be transformed into cmp 
AH, #H'0000 and the following compare could be removed getting this:
$le:
         cmp     AH,#H'0000
         bmi ?L7
         bgt ?L3
         tst     @$XAP_AL
         bne ?L3
?L7:
         ld      AL,#H'0001
         bra     0,X
?L3:
         ld      AL,#H'0000
         bra     0,X

The RTL for the first two comparisons at compare-elim is:
(insn 51 3 52 2 (set (reg:CC_NZ 13 CC)
         (compare:CC_NZ (reg:QI 0 AH [orig:27 a ] [27])
             (const_int 0 [0]))) b651.c:1 63 {*tstqi}
      (nil))

(jump_insn 52 51 34 2 (set (pc)
         (if_then_else (ge (reg:CC_NZ 13 CC)
                 (const_int 0 [0]))
             (label_ref 41)
             (pc))) b651.c:1 68 {*conditional_branch}
      (expr_list:REG_BR_PROB (const_int 7900 [0x1edc])
         (nil))
  -> 41)

(code_label 41 43 25 4 6 "" [1 uses])

(note 25 41 49 4 [bb 4] NOTE_INSN_BASIC_BLOCK)

(insn 49 25 50 4 (set (reg:CC 13 CC)
         (compare:CC (reg:QI 0 AH [orig:27 a ] [27])
             (const_int 0 [0]))) b651.c:1 64 {*cmpqi}
      (nil))

(jump_insn 50 49 26 4 (set (pc)
         (if_then_else (gt (reg:CC 13 CC)
                 (const_int 0 [0]))
             (label_ref 13)
             (pc))) b651.c:1 68 {*conditional_branch}
      (expr_list:REG_BR_PROB (const_int 7900 [0x1edc])
         (nil))
  -> 13)

The transformation would involve deleting insn 49 and transforming insn 
51 into mode CC. I guess this could be easily done by checking at each 
comparison if we can eliminate the current comparison by generalizing 
the previous one using a function like rx_cc_modes_compatible (from rx.c).

What do you think?

Cheers,

-- 
PMatos



More information about the Gcc mailing list