Sparc condition codes

Jakub Jelinek jj@sunsite.ms.mff.cuni.cz
Wed Jun 2 07:00:00 GMT 1999


Hi!

I'd like to ask folks for opinions on what's the best solution for the
SPARC condition codes optimizations:
SPARC does not define HAVE_cc0 and uses a separate hard register for
condition codes. Most of the integer arithmetic instructions have two forms:
one that sets the condition codes and one that does not.
Currently egcs (nor gcc) does not use them much, so e.g. one gets:

        unsigned long g = a + b;
        if (g)
                d = e + f;

into
        add %o0,%o1,%o0
        cmp %o0,0
        be .LL4
	...
while
	addcc %o0,%o1,%o0
	be .LL4
	...
would be sufficient (and of course there can be many other examples).
sparc.md even has some define_insn but they are not used in real-world
compilations (e.g.
(define_insn "*cmp_cc_plus"
  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
                                  (match_operand:SI 1 "arith_operand" "rI"))
                         (const_int 0)))]
  "! TARGET_LIVE_G0"
  "addcc\\t%0, %1, %%g0"
  [(set_attr "type" "compare")
   (set_attr "length" "1")])
).
The issue is that one usually uses the value of the arithmetic instruction
and so combiner will not combine it. Either it is used between the plus and
compare, which means there won't be LOG_LINKS set up from the compare to the
plus, or it is used afterwards (thus the result of plus does not die in the
compare and combiner again does not do anything).

Unfortunately this cannot be solved by peepholes either, because normally
the arithmetic instructions are not immediately before the compare insns.

I think this could be solved by some variant of global peephole for specific
registers where machine.h would specify which registers should be tried (and
it would try to combine two instructions into one parallel which is
mentioned in .md. The requirements would be that the second instruction sets
the register chosen by machine.h, it uses the result of the first
instruction, the result of the first instruction is not set anywhere in
between and the dest register of the second is neither set nor used in
between the two instructions and everything is within one basic block.

Now, before I start writing a prototype, is there some chance some change
like that might get into generic code? And also, would other platforms
benefit from it as well? IMHO from the sparc point of view the best place
for such optimization would be somewhere after the first scheduler pass, so
that scheduler is more free to schedule instructions and there is still
second sched pass which would fix it up.

Or is there some other way how to do this?

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz
Administrator of SunSITE Czech Republic, MFF, Charles University
___________________________________________________________________
UltraLinux  |  http://ultra.linux.cz/  |  http://ultra.penguin.cz/
Linux version 2.3.4 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________


More information about the Gcc mailing list