This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] h8300: Fix target/11805
Alexandre Oliva <aoliva@redhat.com> writes:
> On Aug 21, 2003, Roger Sayle <roger@eyesopen.com> wrote:
>
>> Sorry to ask, but are there any plans to upgrade the h8300 backend from
>> a cc0 target to a new style MODE_CC target?
>
> I don't think this would be a good idea. The h8300 is one of those
> machines in which most instructions modify the condition codes, and
> you can take advantage of the set values by omitting additional
> compare instructions.
That's all fine from the point of view of a single target maintainer.
Roger's taking the global view, where having more than one way to do
something is bad. The cc0 mechanism has bitrotted to the point that
all cc0 targets were broken for several months last year and no one
noticed, which says to me that it's outlived its usefulness.
> Forcing a port in which most instructions set condition codes would
> pretty much force every instruction that modifies them to be
> implemented as a parallel that, besides its intended action, sets the
> condition code register according to the side effects of the
> operation, which significantly hinder GCC's ability to optimize the
> code, or at least clobbers it (the x86 approach), which doesn't have
> as much impact in optimization, but doesn't enable redundant compares
> to be eliminated without significant effort.
This is a real problem. I have been idly thinking about a model in
which the initial RTL claims that there is no condition code; instead
there are compare-and-branch insns that (if they were output) would
produce a pair of machine instructions. So you'd have RTL like this:
(set (reg:SI 0) (minus:SI (reg:SI 0) (reg:SI 1)))
(set (pc)
(if_then_else (eq:SI (reg:SI 0) (const_int 0))
(label_ref ".L1")
(pc)))
=> subl r0, r1
testl r0
beq .L1
This persists until after register allocation. At that point a whole
bunch of "operation and branch" anonymous patterns get enabled, and we
run the code through a second combine pass, which will produce
(parallel[
(set (reg:SI 0 (minus:SI (reg:SI 0) (reg:SI 1))))
(set (pc)
(if_then_else (eq:SI (reg:SI 0) (reg:SI 1))
(label_ref ".L1")
(pc)))])
=> subl r0, r1
beq .L1
The only thing I'm not sure how to handle is optimizing out the extra
compare in a three-way branch:
cmpl r0, r1
bgt .L1
cmp1 r0, r1
blt .L2
; r0==r1 here
but only because I can't think of a good way to represent this in RTL.
zw