SMALL_REGISTER_CLASSES fixes for combine.c

Jeffrey A Law law@cygnus.com
Sun Dec 6 03:38:00 GMT 1998


  In message <Pine.GSO.4.02A.9812042217200.9618-100000@jennifer.informatik.rwth
-aachen.de>you write:
  > > If the hard reg is actually live *during* the instruction, it is right to
  > > set it in bad_spill_regs.  We could approximate this with
  > > (REGNO_REG_SET_P (chain->live_before, i)
  > >  && REGNO_REG_SET_P (chain->live_after, i)) .
  > > Now, if the hard reg is only life after the instruction, we may use it
  > > for RELOAD_FOR_INPUT (*), RELOAD_FOR_INPUT_ADDRESS,
  > > RELOAD_FOR_INPADDR_ADDRESS, RELOAD_FOR_OTHER_ADDRESS,
  > > RELOAD_FOR_OPERAND_ADDRESS (*), and RELOAD_FOR_OPADDR_ADDRESS reloads.
  > > If it is only life after the instruction,
  > > we may use it for RELOAD_FOR_OUTPUT, RELOAD_FOR_OUTPUT_ADDRESS, and
  > > RELOAD_FOR_OUTADDR_ADDRESS.
  > > (*) not if the register is earlyclobbered.
  > 
  > That would even be an optimization for other cases as well.
Yes.  Though reload would have to be careful not to combine reloads which could
make this improvement unsafe.

  > But does it fix all these problems?
Probably not.  I don't think Joern was claiming it would fix all the problems,
just that the old code could actually handle some of these situations. 
Basicaly this idea gives the reloader a couple more options in some cases,
which is a good thing.


  > > Register allocation can't allocate anything to a fixed register.
  > > Consider these two SH instructions:
  > > 
  > >  (insn 21 18 23 (set (reg/v:SI 45)
  > >          (reg:SI 18 t)) 83 {movsi_i} (insn_list 18 (nil))
  > >      (expr_list:REG_DEAD (reg:SI 18 t)
  > >          (nil)))
  > >  
  > >  (insn 23 21 24 (set (reg:SI 18 t)
  > >          (eq:SI (reg/v:SI 45)
  > >              (const_int 1))) -1 (insn_list 21 (nil))
  > >      (expr_list:REG_DEAD (reg/v:SI 45)
  > >          (nil)))
  > > 
  > > Currently, they get combined into a no-op move, which disappears later.
  > > With your patch, they couldn't be combined any longer.
  > 
  > What generates these uses of fixed regs?
Some ports use fixed registers in their define_insns or define_expands.


  > Here's one (probably not too well thought out) idea: Could we allow these
  > combinations for fixed regs, and reject them for all others?  If neither
  > register allocation nor reload is going to use fixed regs, no conflicts can
  > be created that way.
I don't think that signficiantly helps.  Some targets use hard regs explicitly,
but those registers are not always fixed.  This has always been considered safe
as long as the hard registers were not in a class by themselves and other
registers in the same class were available to the allocator.


Let's take a step back and look at the problem another way.

The basic problem is we have a hard register which appears in rtl (%eax) that
is also in a class by itself (AREG) and the md files has instructions which
must use eax, though they operate on pseudos (div pattern for example)

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=a")
        (udiv:DI (match_operand:DI 1 "register_operand" "a")
                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
   (set (match_operand:SI 3 "register_operand" "=d")
        (umod:SI (match_dup 1) (match_dup 2)))]
  ""
  "div%L0 %2,%0"
  [(set_attr "type" "idiv")])

This situation has always been taboo.  Other ports would have complained
loudly in reload if they set up a similar situation.  The x86 has gotten away
with this for a long time because of SMALL_REGISTER_CLASSES.

If SMALL_REGISTER_CLASSES is going to go away, or if we're going to allow
optimizations on hard regs in the presense of SMALL_REGISTER_CLASSES, then we
need some reload work to handle this situation.

One could envision a class a registers which are "bad", but possibly not
"fatal" if we need them for a reload.  We may have to save/restore them around
the insn in question (either to another reg or a stack slot).

We may still want to inhibit some optimizations on these values though since
this reloading has a cost...  But instead of having it be driven on the 
S_R_C define, we make it a little less restrictive -- like avoid lengthening
the lifetime of a non-fixed hard register that is in a class by itself and
is used for argument passing & return values.

jeff

This is primarily a problem with arguments & return values.  



braindamage in reload.

jeff



More information about the Gcc-patches mailing list