This is the mail archive of the gcc-patches@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]

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


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