This is the mail archive of the gcc@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: Use-and-clobber insns and REG_DEAD notes (fwd)


Hello Richard,

I'm still trying to figure out whether or not we are supposed
to have REG_DEAD notes for use-and-clobber insns; see below
for why this causes problems.

While digging in the CVS history, I noticed that the current
REG_DEAD handling in flow.c results mostly from a patch of yours:
http://gcc.gnu.org/ml/gcc-patches/2000-04/msg01124.html

As part of this patch you have removed a comment:
!      [snip] Which begs the whole
!      question of whether we should in fact have death notes for registers
!      used and clobbered (but not set) in the same insn.  [snip]

This is exactly the question I have here ;-)  Does the fact that
you removed the comment imply that you had answered the question?

Assuming the the current flow.c behaviour is in fact the intended
one, do you have suggestions on how to fix combine.c to behave
the same way, preferably without duplicating the whole logic?
Is there a way for combine to call back into flow to ask whether
a dead note is required?

Bye,
Ulrich


Forwarded message:
> From weigand Mon Jul  7 19:13:22 2003
> From: Ulrich Weigand <weigand>
> Message-Id: <200307071709.TAA12105@faui11.informatik.uni-erlangen.de>
> Subject: Re: Use-and-clobber insns and REG_DEAD notes
> To: matz@suse.de (Michael Matz)
> Date: Mon, 7 Jul 2003 19:09:06 +0200 (MET DST)
> Cc: weigand@i1.informatik.uni-erlangen.de (Ulrich Weigand), gcc@gcc.gnu.org
> In-Reply-To: <Pine.LNX.4.44.0307070807270.27789-100000@wotan.suse.de> from "Michael Matz" at Jul 07, 2003 08:18:12 AM
> X-Mailer: ELM [version 2.5 PL2]
> MIME-Version: 1.0
> Content-Type: text/plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
> Content-Length: 5908
> 
> Michael Matz wrote:
> 
> > Just to be sure, you have a (read) reference to CC, plus an extra clobber
> > for CC in the insn, yes?  Like
> > 
> > parallel[
> >   (set (bla) (plus (reg blubb) (reg CC))
> >   (clobber (reg CC))]
> > 
> > And no explicit set of CC, right?
> 
> Exactly.
> 
> > > However, when some other insn is combined into it, combine.c thinks it
> > > does not need to distribute the REG_DEAD note into the insn (because
> > > dead_or_set_p returns true),
> > 
> > Hmm, I'm not sure I understand.  Insn X is combined _into_ such a
> > cc-use-clobber insn Y?  To where should the REG_DEAD note (from insn Y) be
> > distributed.  insn X will be deleted if the combining is successful.
> 
> Sorry for being unclear.  The situation is like this:  I'm compiling
> this code (which is a standard way of building up a 64-bit addition
> from 32-bit additions):
> 
>   unsigned int x, y;
>   x = al + bl;
>   y = ah + bh + (x < al);
> 
> Before combine, this results in the following insn list (after ifcvt
> has recognized and converted the conditional):
> 
> (insn 18 12 20 0 (parallel [
>             (set (reg/v:SI 49 [ x ])
>                 (plus:SI (reg/v:SI 44 [ al ])
>                     (reg/v:SI 48 [ bl ])))
>             (clobber (reg:CC 33 %cc))
>         ]) 138 {addsi3} (insn_list 11 (insn_list 8 (nil)))
>     (expr_list:REG_DEAD (reg/v:SI 48 [ bl ])
>         (expr_list:REG_UNUSED (reg:CC 33 %cc)
>             (nil))))
> 
> (insn 20 18 38 0 (parallel [
>             (set (reg:SI 51)
>                 (plus:SI (reg/v:SI 42 [ ah ])
>                     (reg/v:SI 46 [ bh ])))
>             (clobber (reg:CC 33 %cc))
>         ]) 138 {addsi3} (insn_list 6 (insn_list 10 (nil)))
>     (expr_list:REG_DEAD (reg/v:SI 42 [ ah ])
>         (expr_list:REG_DEAD (reg/v:SI 46 [ bh ])
>             (expr_list:REG_UNUSED (reg:CC 33 %cc)
>                 (nil)))))
> 
> (insn 38 20 39 0 (set (reg:CCL1 33 %cc)
>         (compare:CCL1 (reg/v:SI 49 [ x ])
>             (reg/v:SI 44 [ al ]))) 33 {*cmpsi_ccur} (insn_list 18 (nil))
>     (expr_list:REG_DEAD (reg/v:SI 44 [ al ])
>         (nil)))
> 
> (insn 39 38 27 0 (parallel [
>             (set (reg/v:SI 50 [ y ])
>                 (plus:SI (plus:SI (reg:SI 51)
>                         (const_int 0 [0x0]))
>                     (ltu:SI (reg:CCL1 33 %cc)
>                         (const_int 0 [0x0]))))
>             (clobber (reg:CC 33 %cc))
>         ]) 144 {addsi3_alc} (insn_list 20 (insn_list 38 (nil)))
>     (expr_list:REG_DEAD (reg:SI 51)
>         (expr_list:REG_DEAD (reg:CCL1 33 %cc)
>             (expr_list:REG_UNUSED (reg:CC 33 %cc)
>                 (nil)))))
> 
> Note both REG_DEAD and REG_UNUSED on the %cc register.
> 
> Combine is now supposed to collapse 18 into 38 and 20 into 39,
> resulting in:
> 
> (insn 38 20 39 0 (parallel [
>             (set (reg:CCL1 33 %cc)
>                 (compare:CCL1 (plus:SI (reg:SI 5 %r5 [ al+4 ])
>                         (mem/f:SI (plus:DI (reg/f:DI 32 %ap)
>                                 (const_int 4 [0x4])) [4 bl+0 S4 A32]))
>                     (reg:SI 5 %r5 [ al+4 ])))
>             (set (reg/v:SI 49 [ x ])
>                 (plus:SI (reg:SI 5 %r5 [ al+4 ])
>                     (mem/f:SI (plus:DI (reg/f:DI 32 %ap)
>                             (const_int 4 [0x4])) [4 bl+0 S4 A32])))
>         ]) 129 {*addsi3_carry1_cc} (nil)
>     (expr_list:REG_DEAD (reg:DI 5 %r5 [ al ])
>         (nil)))
> 
> (insn 39 38 27 0 (parallel [
>             (set (reg/v:SI 50 [ y ])
>                 (plus:SI (plus:SI (reg:SI 4 %r4 [ ah+4 ])
>                         (reg:SI 6 %r6 [ bh+4 ]))
>                     (ltu:SI (reg:CCL1 33 %cc)
>                         (const_int 0 [0x0]))))
>             (clobber (reg:CC 33 %cc))
>         ]) 144 {addsi3_alc} (nil)
>     (expr_list:REG_DEAD (reg:DI 4 %r4 [ ah ])
>         (expr_list:REG_DEAD (reg:DI 6 %r6 [ bh ])
>             (expr_list:REG_UNUSED (reg:CC 33 %cc)
>                 (nil)))))
> 
> (it has in fact replaced some of the registers as well, but this
> shouldn't make any difference).
> 
> The interesting case is now the combination of 20 into 39, and in 
> particular what is supposed to happen with the notes that these
> instructions were carrying
> 
>     (expr_list:REG_DEAD (reg/v:SI 42 [ ah ])
>         (expr_list:REG_DEAD (reg/v:SI 46 [ bh ])
>             (expr_list:REG_UNUSED (reg:CC 33 %cc)
> 
>     (expr_list:REG_DEAD (reg:SI 51)
>         (expr_list:REG_DEAD (reg:CCL1 33 %cc)
>             (expr_list:REG_UNUSED (reg:CC 33 %cc)
> 
> What combine does is to take all of these notes and try to figure
> out which of them are still needed.  The REG_DEAD of 42 and 46 are
> kept (renamed to reg 4 and reg 6).  The two REG_UNUSED of %cc are
> merged into one.  The interesting case is what is supposed to happen
> with the REG_DEAD of %cc.
> 
> Here, the distribute_notes routine of combine.c contains logic that
> says, if dead_or_set_p returns true of %cc at the new insn (which it
> does due to the clobber), then the REG_DEAD note is superfluous and
> can be omitted.
> 
> However, this results in a different set of notes than what flow.c
> would have arrived at had it processed the result of combine.c.
> And in fact, during scheduling, data flow analysis *is* redone,
> and does result in the additional dead note, which causes an
> assertion in sched to fail (number of dead notes before != number
> of dead notes after).
> 
> > And even if flow would behave as described above (not emitting the
> > REG_UNUSED note), CC would _still_ be dead_or_set_p().  After all it _is_
> > set (clobbered, and thereby implicitely even dead).
> 
> Yes, the logic in combine.c would still work the same.  The problem
> is that this logic (if dead_or_set_p then we don't need REG_DEAD notes)
> is *not* the same as the logic applied by flow.c (there we have: if the
> register is *set* in the insn, we don't need a REG_DEAD note, but if
> it is clobbered, we still want one).
> 
> Either the one or the other needs to be fixed, the question is which
> one.  So, should insn 39 above carry a REG_DEAD note for %cc or not?
> 
> Bye,
> Ulrich
> 
> -- 
>   Dr. Ulrich Weigand
>   weigand@informatik.uni-erlangen.de
> 


-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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