This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: ssa bootstrap problem on x86 (cmpstrsi_1 pattern)
> Cc: gcc@gcc.gnu.org
> X-URL: http://www.codesourcery.com
> Organization: CodeSourcery, LLC
> From: Mark Mitchell <mark@codesourcery.com>
> Date: Sun, 23 Jul 2000 00:50:01 -0700
> X-Dispatcher: imput version 990425(IM115)
>
>
> Hi Mark,
>
> I've looked at the SSA bootstrap problem. It's caused by an insn
> in the x86 backend which looks like:
>
> Thanks for tracking this down.
>
> (define_insn "cmpstrsi_1"
> [(set (reg:CC 17)
> (if_then_else:CC (ne (match_operand:SI 2 "register_operand" "c")
> (const_int 0))
> (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
> (mem:BLK (match_operand:SI 1 "address_operand" "D")))
> (const_int 0)))
> (use (match_operand:SI 3 "immediate_operand" "i"))
> (use (reg:CC 17))
> (use (reg:SI 19))
> (clobber (match_dup 0))
> (clobber (match_dup 1))
> (clobber (match_dup 2))]
> ...)
>
> The problem here is the match_dups. IMHO, it would be much better if
> these were written as match_scratch with '0', '1', and '2'
> constraints.
>
> So we have something like:
>
> [(SET (reg:CC 17)
> (if_then_else:CC (ne (reg:SI 35) (const int 0)) ...)
> (USE (reg:CC 17))
> ...
> (CLOBBER (reg:SI 35)))
> ...]
>
> right? This just doesn't have a sensible SSA representation. I don't
> see how match_scratch helps. The bottom line is that moving any use
> of register 35 past this point is bogus. SSA doesn't really have a
> way of representing instructions that kill their input operands.
...
It does. I'm assuming that reg 35 is a pseudo (since SSA
doesn't apply to hard registers). It looks like:
(sequence [
(set (reg:SI 10035) (reg:SI 35))
(parallel [
(SET (reg:CC 17)
(if_then_else:CC (ne (reg:SI 10035) (const int 0)) ...)
(USE (reg:CC 17))
...
(CLOBBER (reg:SI 10035)))
...])
])
You can see that, taken as a whole, this insn has an input that is
not changed, and an outputs which is new to this insn. It's just
that it now also has an extra SET, which hopefully will become
no-ops but GCC isn't really good at ensuring such things.
(I might add that the hard register use is going to hurt; it might be
helpful to deal with that like the way we deal with SUBREGs by copying
in and out of psuedos in a SEQUENCE. No doubt this would make reload
much happier too.)
The reason match_scratch helps is that we could just write the same
pattern as
(define_insn "cmpstrsi_1"
[(set (reg:CC 17)
(if_then_else:CC (ne (match_operand:SI 2 "register_operand" "c")
(const_int 0))
(compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
(mem:BLK (match_operand:SI 1 "address_operand" "D")))
(const_int 0)))
(use (match_operand:SI 3 "immediate_operand" "i"))
(use (reg:CC 17))
(use (reg:SI 19))
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))]
...)
(parallel [
(SET (reg:CC 10017)
(if_then_else:CC (ne (reg:SI 35) (const int 0)) ...)
(USE (reg:CC 17))
...
(CLOBBER (reg:SI 10035)))
...])
and because of the constraints on the USE and the CLOBBER's
match_scratch, reload would ensure that registers 17 and 10017, and 35
and 10035, were put in the same hard register. I believe it can do
this, although I'll have to try a bootstrap to make sure.
--
- Geoffrey Keating <geoffk@cygnus.com>