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]

Use-and-clobber insns and some ancient combine.c code


Hello Richard and Richard,

when evaluating the use of ADD LOGICAL WITH CARRY instructions on s390
(see also the patch I checked in today), I've noticed two places in
combine that prevent those instructions to be exploited fully.

Both of these are due to code you added to combine a long time ago;
I was wondering if you still recall why these changes were necessary
-- I don't really understand it in the context of the current code.

In both cases, the issues arise from instructions that both use and
clobber a hard register within a single PARALLEL.  This happens 
naturally with an 'add with carry' type instruction: it uses the 
condition code (which is a hard reg on s390), and at the same time
clobbers it.  There doesn't appear to be anything wrong with such 
types of insns as far as I can see; however, those two places prevent 
combine from generating such insns in several cases.

The first place is in can_combine_p.  This check:

  /* Don't substitute for a register intended as a clobberable operand.
     Similarly, don't substitute an expression containing a register that
     will be clobbered in I3.  */
  if (GET_CODE (PATTERN (i3)) == PARALLEL)
    for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
      if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
          && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0),
                                       src)
              || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest)))
        return 0;

simply refuses to combine any expression containing the CC hard reg
into a insn that clobbers CC.  I would like this to happen to allow
combining a sCOND-type instruction with a regular add into an add-
with-carry instruction.

I guess I can see why we wouldn't want to substitute into the operand
of a CLOBBER itself.  But why prevent substitution of an expression
containing a register that will be clobbered?  This second clause was
added under this ChangeLog entry:

Wed Oct 28 05:34:11 1992  Richard Kenner  (kenner at vlsi1.ultra.nyu.edu)

        * reload1.c (gen_input_reload): In PLUS, if OP0 and OP1 are the
        same, use RELOADREG when generating the addition.

        * reload.c (find_reloads_address): When copying memref after we've
        made recursive calls on it, copy any replacements we made.

        * combine.c (can_combine_p): Don't substitute an expression
        containing a register that will be clobbered in I3.

        * objc/core.c, objc/hash.c: Include tconfig.h, not config.h.
        Include gstdarg.h.
        * objc/object.m: Include tconfig.h, not config.h.
        Include gstdarg.h before stdio.h.
        * objc/objc.h: Don't include gstdarg.h here.
        * objc/objc-proto.h (CLASS_LOCATION_SHIFT): Use HOST_BITS_PER_LONG,
        not BITS_PER_WORD.
        (setClassNumber, getClassNumber): `info' field is long, not int.


The second place is reg_dead_at_p.  This is used when adding hard-reg
clobbers in recog_for_combine to ensure no clobber is added for a reg
that is actually live at this point.  However, this routine always
considers all registers showing up as input in NEWPAT as live:

   Hard regs marked as being live in NEWPAT_USED_REGS
   must be assumed to be always live.

Now, I'd like to see a SImode sCOND type insn followed by an extension 
to DImode be combined into a single DImode sCOND.  However, as the 
extend insn doesn't clobber CC, that clobber would need to be added -- 
but since the new pattern uses CC as input, reg_dead_at_p refuses to 
make this substitution.   (As my sCOND insns are in fact implemented
as add-with-carry, they implicitly clobber CC.)

Again, I do not understand why this is being prevented (shouldn't
it be enough to mark all *output* registers from newpat as live?).
The code was added under this ChangeLog entry:

Sat Mar 19 17:13:47 1994  Richard Earnshaw (rwe11@cl.cam.ac.uk)

        * combine.c (newpat_used_regs): New variable.
        (mark_used_regs_combine): New function.
        (try_combine): Use them.
        (reg_dead_at_p): Registers marked in newpat_used_regs must always be
        considered to be live.


I've simply reverted those two changes in my current tree, and this
bootstrapped and tested without regressions on s390-ibm-linux and
s390x-ibm-linux; the resulting compiler does perform the optimizations
I'm expecting.  However, I'm not sure about simply removing code the
purpose of which I don't understand.  I'm aware that this code is 
over a decade old, but if you still remember anything about its
history, I'd be glad for any hints ...

Bye,
Ulrich

-- 
  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]