- }
-
- dest = SET_DEST (set);
- src = SET_SRC (set);
-
- /* If this sets a MEM to the contents of a REG that is only used
- in a single basic block, see if the register is always equivalent
- to that memory location and if moving the store from INSN to the
- insn that set REG is safe. If so, put a REG_EQUIV note on the
- initializing insn.
-
- Don't add a REG_EQUIV note if the insn already has one. The existing
- REG_EQUIV is likely more useful than the one we are adding.
-
- If one of the regs in the address is marked as reg_equiv_replace,
- then we can't add this REG_EQUIV note. The reg_equiv_replace
- optimization may move the set of this register immediately before
- insn, which puts it after reg_equiv_init_insns[regno], and hence
- the mention in the REG_EQUIV note would be to an uninitialized
- pseudo. */
- /* ????? This test isn't good enough; we might see a MEM with a use of
- a pseudo register before we see its setting insn that will cause
- reg_equiv_replace for that pseudo to be set.
- Equivalences to MEMs should be made in another pass, after the
- reg_equiv_replace information has been gathered. */
-
- 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_init_insns[regno] != 0
- && reg_equiv_init_insns[regno] != const0_rtx
- && ! find_reg_note (insn, REG_EQUIV, NULL_RTX)
- && ! contains_replace_regs (XEXP (dest, 0), reg_equiv_replace))
- {
- rtx init_insn = XEXP (reg_equiv_init_insns[regno], 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));
- }
-
- /* We only handle the case of a pseudo register being set
- once, or always to the same value. */
- /* ??? The mn10200 port breaks if we add equivalences for
- values that need an ADDRESS_REGS register and set them equivalent
- to a MEM of a pseudo. The actual problem is in the over-conservative
- handling of INPADDR_ADDRESS / INPUT_ADDRESS / INPUT triples in
- calculate_needs, but we traditionally work around this problem
- here by rejecting equivalences when the destination is in a register
- that's likely spilled. This is fragile, of course, since the
- preferred class of a pseudo depends on all instructions that set
- or use it. */
-
- if (GET_CODE (dest) != REG
- || (regno = REGNO (dest)) < FIRST_PSEUDO_REGISTER
- || reg_equiv_init_insns[regno] == const0_rtx
- || (CLASS_LIKELY_SPILLED_P (reg_preferred_class (regno))
- && GET_CODE (src) == MEM))
- {
- /* This might be seting a SUBREG of a pseudo, a pseudo that is
- also set somewhere else to a constant. */
- note_stores (set, no_equiv);
- continue;
- }
- /* Don't handle the equivalence if the source is in a register
- class that's likely to be spilled. */
- if (GET_CODE (src) == REG
- && REGNO (src) >= FIRST_PSEUDO_REGISTER
- && CLASS_LIKELY_SPILLED_P (reg_preferred_class (REGNO (src))))
- {
- no_equiv (dest, set);
- continue;
- }
-
- note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
-
- if (REG_N_SETS (regno) != 1
- && (! note
- || ! function_invariant_p (XEXP (note, 0))
- || (reg_equiv_replacement[regno]
- && ! rtx_equal_p (XEXP (note, 0),
- reg_equiv_replacement[regno]))))
- {
- no_equiv (dest, set);
- continue;
- }
- /* Record this insn as initializing this register. */
- reg_equiv_init_insns[regno]
- = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init_insns[regno]);
-
- /* If this register is known to be equal to a constant, record that
- it is always equivalent to the constant. */
- if (note && function_invariant_p (XEXP (note, 0)))
- PUT_MODE (note, (enum machine_mode) REG_EQUIV);
-
- /* If this insn introduces a "constant" register, decrease the priority
- of that register. Record this insn if the register is only used once
- more and the equivalence value is the same as our source.
-
- The latter condition is checked for two reasons: First, it is an
- indication that it may be more efficient to actually emit the insn
- as written (if no registers are available, reload will substitute
- the equivalence). Secondly, it avoids problems with any registers
- dying in this insn whose death notes would be missed.
-
- If we don't have a REG_EQUIV note, see if this insn is loading
- a register used only in one basic block from a MEM. If so, and the
- MEM remains unchanged for the life of the register, add a REG_EQUIV
- note. */
-
- note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
-
- 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));
-
- if (note)
- {
- int regno = REGNO (dest);
-
- /* Record whether or not we created a REG_EQUIV note for a LABEL_REF.
- We might end up substituting the LABEL_REF for uses of the
- pseudo here or later. That kind of transformation may turn an
- indirect jump into a direct jump, in which case we must rerun the
- jump optimizer to ensure that the JUMP_LABEL fields are valid. */
- if (GET_CODE (XEXP (note, 0)) == LABEL_REF
- || (GET_CODE (XEXP (note, 0)) == CONST
- && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
- && (GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0))
- == LABEL_REF)))
- recorded_label_ref = 1;
-
-
- reg_equiv_replacement[regno] = XEXP (note, 0);
-
- /* Don't mess with things live during setjmp. */
- if (REG_LIVE_LENGTH (regno) >= 0)