This is the mail archive of the 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: What to do with new-ra for GCC 4.0

Bernd Schmidt wrote:

> [secondary reload lifetimes]
> > This is wrong (at least, it is different from what the old code did
> > and what s390 expects).
> > 
> > For secondary input reloads, you decrement 'birth' of the primary
> > reload.  This prevents the same reload reg to be chosen for primary
> > and secondary reload.  However, the old code *did* do that (and
> > existing backends expect it) *if* primary and secondary reload
> > share the same class.
> Hmm.  Examples?  There's an abort in push_secondary_reload for this 
> case, but it seems like it has been slightly relaxed in the last 5 
> years...  What could this behaviour possibly be useful for?  Are these 
> just cases where you need a special insn but not an extra register?

In my case, I always need the special insn, and I might need an
extra register (only if the target has the wrong register class).

The problem on s390 is that there is no insn that performs a 32-bit
addition without clobbering the condition code.  However reload
needs to reload effective addresses (PLUS rtxs) that may come up
during register elimination; such a reload must not clobber the
condition code.  s390 does have a LOAD ADDRESS instruction which
can perform that reload, but this instruction only does a 31-bit
operation (because addresses are 31 bits wide on s390).  Therefore
this insn *must not* be represented as a simple (set ... (plus ...))
in the .md file, otherwise it would be erroneously recognized by
combine etc. to perform full SImode addition.

So, I have the LOAD ADDRESS in the .md file with a pattern that
won't be recognized otherwise, and have a secondary reload insn
that generates this pattern.

So far, so good.  As always with reload, there are complications.
The first is, that the address to be reloaded may itself be 
invalid because of an out-of-range displacement.  In this case
I need a scratch register of class ADDR_REGS to first load the
displacement into, and then do the LOAD ADDRESS.  This scratch
register may in general be equal to the target of the LOAD
ADDRESS (i.e. the primary reload register) -- however, if that
target happens *not* to be in class ADDR_REGS, I do need a 
different scratch register.  And, of course, the scratch register
must in all cases be different from any register feeding into
the address to be reloaded.

B.t.w. note that back-ends that definitely *need* a scratch
register different from the target currently employ special
provisions to guarantee that.  E.g. in

(define_expand "reload_inqi"
  [(parallel [(match_operand:QI 0 "register_operand" "=r")
              (match_operand:QI 1 "any_memory_operand" "m")
              (match_operand:TI 2 "register_operand" "=&r")])]
      /* It is possible that one of the registers we got for operands[2]
         might coincide with that of operands[0] (which is why we made
         it TImode).  Pick the other one to use as our scratch.  */
      if (REGNO (operands[0]) == REGNO (operands[2]))
        scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
        scratch = gen_rtx_REG (DImode, REGNO (operands[2]));

> I think we might need both, but possibly we have to make 
> "rl->reginfo.birth--" conditional on "secondary_icode == -1".

I'm not sure why this would be required -- if we have no special
insn, an simple move will be generated.  If the register picked
as primary reload happens to also have the appropriate class
required for the secondary reload, it should be valid to just
omit the secondary reload.

> > And indeed there are paths in find_reload that set inc to nonzero values
> > even in the absence of preincrement (s390 doesn't even *have* that!).
> Then maybe we should fix those paths.

The one that bit me is this in reload.c:

        /* Handle an operand with a nonoffsettable address
           appearing where an offsettable address will do
           by reloading the address into a base register.

           ??? We can also do this when the operand is a register and
           reg_equiv_mem is not offsettable, but this is a bit tricky,
           so we don't bother with it.  It may not be worth doing.  */
        else if (goal_alternative_matched[i] == -1
                 && goal_alternative_offmemok[i]
                 && MEM_P (recog_data.operand[i]))
              = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
                             &XEXP (recog_data.operand[i], 0), (rtx*) 0,
                             MODE_BASE_REG_CLASS (VOIDmode),
                             GET_MODE (XEXP (recog_data.operand[i], 0)),
                             VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
              = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));

Note the unconditional set.  I must admit I've never thought about
the whole inc/dec situation in reload as we don't have such insns,
so I'm not sure why 'inc' is set here unconditionally, and what the
proper condition should be ...


  Dr. Ulrich Weigand
  Linux on zSeries Development

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