|| (sregno < FIRST_PSEUDO_REGISTER
&& asm_noperands (PATTERN (p)) >= 0
&& reg_overlap_mentioned_p (src, PATTERN (p)))
+ /* Don't change hard registers used by a call. */
+ || (CALL_P (p) && sregno < FIRST_PSEUDO_REGISTER
+ && find_reg_fusage (p, USE, src))
/* Don't change a USE of a register. */
|| (GET_CODE (PATTERN (p)) == USE
&& reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0))))
/* If the insn in which SRC dies is a CALL_INSN, don't count it
as a call that has been crossed. Otherwise, count it. */
- if (q != p && GET_CODE (q) == CALL_INSN)
+ if (q != p && CALL_P (q))
{
/* Similarly, total calls for SREGNO, total calls beyond
the death note for DREGNO. */
PATTERN (q) = replace_rtx (PATTERN (q), dest, src);
- if (GET_CODE (q) == CALL_INSN)
+ if (CALL_P (q))
{
REG_N_CALLS_CROSSED (dregno)--;
REG_N_CALLS_CROSSED (sregno)++;
if (reg_set_p (src, p)
|| find_reg_note (p, REG_DEAD, dest)
- || (GET_CODE (p) == CALL_INSN && REG_N_CALLS_CROSSED (sregno) == 0))
+ || (CALL_P (p) && REG_N_CALLS_CROSSED (sregno) == 0))
break;
}
}
rtx src_reg = XEXP (src, 0);
int src_no = REGNO (src_reg);
int dst_no = REGNO (dest);
- rtx p, set, subreg;
+ rtx p, set;
enum machine_mode old_mode;
if (src_no < FIRST_PSEUDO_REGISTER
/* Now walk forward making additional replacements. We want to be able
to undo all the changes if a later substitution fails. */
- subreg = gen_lowpart_SUBREG (old_mode, src_reg);
while (p = NEXT_INSN (p), p != insn)
{
if (! INSN_P (p))
continue;
/* Make a tentative change. */
- validate_replace_rtx_group (src_reg, subreg, p);
+ validate_replace_rtx_group (src_reg,
+ gen_lowpart_SUBREG (old_mode, src_reg),
+ p);
}
validate_replace_rtx_group (src, src_reg, insn);
if (REG_P (src)
&& REG_LIVE_LENGTH (REGNO (src)) > 0
&& REG_P (dest)
- && !RTX_UNCHANGING_P (dest)
&& REG_LIVE_LENGTH (REGNO (dest)) > 0
&& (set = single_set (insn)) != NULL_RTX
&& !reg_mentioned_p (dest, SET_SRC (set))
if (REGNO_LAST_UID (src_regno) == insn_uid)
REGNO_LAST_UID (src_regno) = move_uid;
-
- if (REGNO_LAST_NOTE_UID (src_regno) == insn_uid)
- REGNO_LAST_NOTE_UID (src_regno) = move_uid;
}
}
#ifdef AUTO_INC_DEC
for (p = PREV_INSN (insn); p; p = PREV_INSN (p))
{
- if (GET_CODE (p) == CODE_LABEL
- || GET_CODE (p) == JUMP_INSN)
+ if (LABEL_P (p)
+ || JUMP_P (p))
break;
if (! INSN_P (p))
continue;
}
for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
{
- if (GET_CODE (p) == CODE_LABEL
- || GET_CODE (p) == JUMP_INSN)
+ if (LABEL_P (p)
+ || JUMP_P (p))
break;
if (! INSN_P (p))
continue;
/* reg_set_p is overly conservative for CALL_INSNS, thinks that all
hard regs are clobbered. Thus, we only use it for src for
non-call insns. */
- if (GET_CODE (p) == CALL_INSN)
+ if (CALL_P (p))
{
if (! dst_death)
num_calls++;
&& GET_MODE_SIZE (GET_MODE (dst))
>= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dst))))
{
- src_subreg
- = gen_rtx_SUBREG (GET_MODE (SUBREG_REG (dst)),
- src, SUBREG_BYTE (dst));
dst = SUBREG_REG (dst);
+ src_subreg = lowpart_subreg (GET_MODE (dst),
+ src, GET_MODE (src));
+ if (!src_subreg)
+ continue;
}
if (!REG_P (dst)
|| REGNO (dst) < FIRST_PSEUDO_REGISTER)
if (!REG_P (dst)
|| REGNO (dst) < FIRST_PSEUDO_REGISTER
|| REG_LIVE_LENGTH (REGNO (dst)) < 0
- || RTX_UNCHANGING_P (dst)
|| GET_MODE (src) != GET_MODE (dst))
continue;
/* If we have passed a call instruction, and the
pseudo-reg DST is not already live across a call,
then don't perform the optimization. */
- if (GET_CODE (p) == CALL_INSN)
+ if (CALL_P (p))
{
num_calls++;
rtx src_note = find_reg_note (insn, REG_DEAD, src), dst_note = NULL_RTX;
int length, s_length;
- /* If SRC is marked as unchanging, we may not change it.
- ??? Maybe we could get better code by removing the unchanging bit
- instead, and changing it back if we don't succeed? */
- if (RTX_UNCHANGING_P (src))
- return 0;
-
if (! src_note)
{
/* Look for (set (regX) (op regA constX))
for (length = s_length = 0, p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
{
- if (GET_CODE (p) == CALL_INSN)
+ if (CALL_P (p))
replace_in_call_usage (& CALL_INSN_FUNCTION_USAGE (p),
REGNO (dst), src, p);
/* If we have passed a call instruction, and the pseudo-reg SRC is not
already live across a call, then don't perform the optimization. */
- if (GET_CODE (p) == CALL_INSN)
+ if (CALL_P (p))
{
if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
break;
q = 0;
break;
}
- if (GET_CODE (p) == CALL_INSN)
+ if (CALL_P (p))
num_calls2++;
}
if (q && set2 && SET_DEST (set2) == src && CONSTANT_P (SET_SRC (set2))
mentioning SRC or mentioning / changing DST . If in doubt, presume
it is unstable.
The rationale is that we want to check if we can move an insn easily
- while just paying attention to SRC and DST. A register is considered
- stable if it has the RTX_UNCHANGING_P bit set, but that would still
- leave the burden to update REG_DEAD / REG_UNUSED notes, so we don't
- want any registers but SRC and DST. */
+ while just paying attention to SRC and DST. */
static int
stable_and_no_regs_but_for_p (rtx x, rtx src, rtx dst)
{
if (tmp)
return tmp;
- if (GET_CODE (insn) != INSN
+ if (!NONJUMP_INSN_P (insn)
|| GET_CODE (PATTERN (insn)) != PARALLEL)
return NULL_RTX;
data.insn = insn;
data.memlist = memlist;
- if (GET_CODE (insn) != CALL_INSN && last_sp_set
+ if (!CALL_P (insn) && last_sp_set
&& !for_each_rtx (&PATTERN (insn), record_stack_memrefs, &data))
{
memlist = data.memlist;
/* Otherwise, we were not able to process the instruction.
Do not continue collecting data across such a one. */
if (last_sp_set
- && (GET_CODE (insn) == CALL_INSN
+ && (CALL_P (insn)
|| reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))))
{
if (last_sp_set && last_sp_adjust == 0)
if (last_sp_set && last_sp_adjust == 0)
delete_insn (last_sp_set);
+
+ if (memlist)
+ free_csa_memlist (memlist);
}