This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Extension to compare-elim


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]