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] PR opt/10764: ICE using x86 logdf2


On 14 May 2003, Alexandre Oliva wrote:
> I think I learned a long time ago that a CLOBBER of an input operand
> in PARALLEL with an input operand was not quite the right way to do
> it.  I don't recall whether it was for efficiency or correctness
> (clobber in parallel with input might be considered confusing by some
> passes).  Wouldn't it be better to just mark the match_operand as
> in/out with + instead?

Hopefully, Richard will comment.  However I'll explain the results
of my experiments.  To be honest, the first thing that I tried was
changing the match_operands to "+u", but with no success.  I then
tried "&u" to make the input operand as early clobber, again with
no luck.  Either I got the same ICE in "subst_stack_regs_pat, at
reg-stack.c:1764", or another in "find_reloads, at reload.c:3472".


The problem is that the original code looks like:

(set (reg:XF 62) (my_const))

(set (reg:DF 61) (unspec:DF [(reg:DF 59) (reg:XF 62)] 66))

(set (reg:XF 64) (my_const))

(set (reg:DF 63) (unspec:DF [(reg:DF 60) (reg:XF 64)] 66))


which without explicit clobbers CSE turns into:

(set (reg:XF 62) (my_const))

(set (reg:DF 61) (unspec:DF [(reg:DF 59) (reg:XF 62)] 66))

(set (reg:DF 63) (unspec:DF [(reg:DF 60) (reg:XF 62)] 66))


Which I believe is impossible for reload to handle.  The constraint
on the second argument to UNSPEC is that it must be "u", i.e. in
st(1).  But as I mentioned st(1) is clobbered by this "unspec"!
My understanding is that reload doesn't perform live range splitting,
so that if (reg:DF 62) is "coloured" as "(reg:DF 8 st(1))" then all
occurances of it are register allocated to st(1).

In an ideal world, I'd hoped that using "+u" would convert the
second set of RTL insns into something like:

(set (reg:XF 62) (my_const))

(set (reg:XF 65) (reg:XF 62))

(set (reg:DF 61) (unspec:DF [(reg:DF 59) (reg:XF 62)] 66))

(set (reg:XF 66) (reg:XF 65))

(set (reg:DF 63) (unspec:DF [(reg:DF 60) (reg:XF 66)] 66))


Which would be a PRE-like transformation, making a copy before
the register is clobbered/corrupted in the first "unspec" and
then using this copy in the second unspec.  This could place
pseudo's 62 and 66 in the same hard register, i.e. st(1).

Perhaps, its supposed to work, but I tried various combinations
("u", "+u", "&u", "+f" and "&f") all without any luck.  Having
caused a serious regression, I was delighted that the explicit
clobbers solution worked.  If we can fix reload, I'll be happy
to remove the parallel clobbers and go with an admittedly much
cleaner solution.


Have I misunderstood reload?  This was my first significant patch
to a back-end's machine description, so I'm certain I know next
to nothing about the magic reload can perform.

Roger
--


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