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]

Re: RFC -- update_equiv_regs and friends




  In message <200103060119.UAA13255@jwlab.FEITH.COM>you write:
  > >   > In addition update_equiv_regs probably
  > >   > needs to verify that memory addresses don't vary before creating
  > >   > REG_EQUIV notes containing them.
  > > Note that rtx_varies_p does check that the address is non-varying too:
  > 
  > Yes, however update_equiv_regs has:
  > 
  >       if (note == 0 && REG_BASIC_BLOCK (regno) >= 0
  >           && GET_CODE (SET_SRC (set)) == MEM
  >           && validate_equiv_mem (insn, dest, SET_SRC (set)))
  >         REG_NOTES (insn) = note = gen_rtx_EXPR_LIST (REG_EQUIV, SET_SRC (se
  > t),
  >                                                      REG_NOTES (insn));
  > 
  > which generates a REG_EQUIV note without using rtx_varies_p.
Right.  But validate_equiv_mem verifies that the memory and its address
do not change over the inteval bounded by INSN and the death of DEST.
So we don't need to worry about the rtx_varies_p issues.

validate_equiv_mem also verifies that registers mentioned in the memory
address do not die in the interval bounded by INSN and the death of DEST.

So, assuming validate_equiv_mem does what its comments (and a scan of its
code) imply, we merely need to prove to ourselves that we could never use
the equivalence outside the bounds specified by the calls to
validate_equiv_mem.

All calls to validate_equiv_mem come from update_equiv_regs.

The first looks like this:

      if (GET_CODE (dest) == MEM && GET_CODE (src) == REG
          && (regno = REGNO (src)) >= FIRST_PSEUDO_REGISTER
          && REG_BASIC_BLOCK (regno) >= 0
          && REG_N_SETS (regno) == 1
          && reg_equiv[regno].init_insns != 0
          && reg_equiv[regno].init_insns != const0_rtx
          && ! find_reg_note (XEXP (reg_equiv[regno].init_insns, 0),
                              REG_EQUIV, NULL_RTX)
          && ! contains_replace_regs (XEXP (dest, 0)))
        {
          rtx init_insn = XEXP (reg_equiv[regno].init_insns, 0);
          if (validate_equiv_mem (init_insn, src, dest)
              && ! memref_used_between_p (dest, init_insn, insn))
            REG_NOTES (init_insn)
              = gen_rtx_EXPR_LIST (REG_EQUIV, dest, REG_NOTES (init_insn));
        }

INIT_INSN is the insn that sets up the equivalence.  SRC is the register,
DEST is the memory reference.  We know that SRC must die once within this
basic block which makes the useful life of the equivalence from INIT_INSN
to the death of SRC inclusive.  Which are precisely the bounds we pass to
validate_equiv_mem.   So we're safe with this call.

The second call to validate_equiv_mem looks like this:

      if (note == 0 && REG_BASIC_BLOCK (regno) >= 0
          && GET_CODE (SET_SRC (set)) == MEM
          && validate_equiv_mem (insn, dest, SET_SRC (set)))
        REG_NOTES (insn) = note = gen_rtx_EXPR_LIST (REG_EQUIV, SET_SRC (set),
                                                     REG_NOTES (insn));


Analysis is basically the same as the first one.  However, it's not obvious
that DEST is only set once unless you look up a dozen or so lines to this
code:

      if (REG_N_SETS (regno) != 1
          && (! note
              || rtx_varies_p (XEXP (note, 0), 0)
              || (reg_equiv[regno].replacement
                  && ! rtx_equal_p (XEXP (note, 0),
                                    reg_equiv[regno].replacement))))
        {
          no_equiv (dest, set, NULL);
          continue;
        }

Which prevents us from getting to the code which calls validate_equiv_mem
if DEST is set more than once.

jeff


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