/* Reload pseudo regs into hard regs for insns that require hard regs.
- Copyright (C) 1987-2019 Free Software Foundation, Inc.
+ Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GCC.
#include "except.h"
#include "dumpfile.h"
#include "rtl-iter.h"
+#include "function-abi.h"
/* This file contains the reload pass of the compiler, which is
run after register allocation has been done. It checks that
This is only valid if reg_reloaded_contents is set and valid. */
static HARD_REG_SET reg_reloaded_dead;
-/* Indicate whether the register's current value is one that is not
- safe to retain across a call, even for registers that are normally
- call-saved. This is only meaningful for members of reg_reloaded_valid. */
-static HARD_REG_SET reg_reloaded_call_part_clobbered;
-
/* Number of spill-regs so far; number of valid elements of spill_regs. */
static int n_spills;
if (crtl->saves_all_registers)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (! call_used_or_fixed_reg_p (i)
+ if (! crtl->abi->clobbers_full_reg_p (i)
&& ! fixed_regs[i]
&& ! LOCAL_REGNO (i))
df_set_regs_ever_live (i, true);
rtx t = XVECEXP (pat, 0, i);
if (GET_CODE (t) == CLOBBER && STACK_REG_P (XEXP (t, 0)))
SET_HARD_REG_BIT (clobbered, REGNO (XEXP (t, 0)));
- /* CLOBBER_HIGH is only supported for LRA. */
- gcc_assert (GET_CODE (t) != CLOBBER_HIGH);
}
/* Get the operand values and constraints out of the insn. */
&& (inv_reg_alloc_order[regno]
< inv_reg_alloc_order[best_reg])
#else
- && call_used_or_fixed_reg_p (regno)
- && ! call_used_or_fixed_reg_p (best_reg)
+ && crtl->abi->clobbers_full_reg_p (regno)
+ && !crtl->abi->clobbers_full_reg_p (best_reg)
#endif
))
{
structure of the insn in a way that reload can't handle.
We special-case the commonest situation in
eliminate_regs_in_insn, so just replace a PLUS with a
- PLUS here, unless inside a MEM. */
- if (mem_mode != 0
+ PLUS here, unless inside a MEM. In DEBUG_INSNs, it is
+ always ok to replace a PLUS with just a REG. */
+ if ((mem_mode != 0 || (insn && DEBUG_INSN_P (insn)))
&& CONST_INT_P (XEXP (x, 1))
&& known_eq (INTVAL (XEXP (x, 1)), -ep->previous_offset))
return ep->to_rtx;
return x;
case CLOBBER:
- case CLOBBER_HIGH:
case ASM_OPERANDS:
gcc_assert (insn && DEBUG_INSN_P (insn));
break;
elimination_effects (XEXP (x, 0), mem_mode);
return;
- case CLOBBER_HIGH:
- /* CLOBBER_HIGH is only supported for LRA. */
- return;
-
case SET:
/* Check for setting a register that we know about. */
if (REG_P (SET_DEST (x)))
if (dest == hard_frame_pointer_rtx)
return;
- /* CLOBBER_HIGH is only supported for LRA. */
- gcc_assert (GET_CODE (x) != CLOBBER_HIGH);
-
for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
if (reg_eliminate[i].can_eliminate && dest == reg_eliminate[i].to_rtx
&& (GET_CODE (x) != SET
case PC:
case USE:
case CLOBBER:
- case CLOBBER_HIGH:
return;
case SUBREG:
reg_last_reload_reg = XCNEWVEC (rtx, max_regno);
INIT_REG_SET (®_has_output_reload);
CLEAR_HARD_REG_SET (reg_reloaded_valid);
- CLEAR_HARD_REG_SET (reg_reloaded_call_part_clobbered);
set_initial_elim_offsets ();
be partially clobbered by the call. */
else if (CALL_P (insn))
{
- reg_reloaded_valid &= ~(call_used_or_fixed_regs
- | reg_reloaded_call_part_clobbered);
+ reg_reloaded_valid
+ &= ~insn_callee_abi (insn).full_and_partial_reg_clobbers ();
/* If this is a call to a setjmp-type function, we must not
reuse any reload reg contents across the call; that will
to be forgotten later. */
static void
-forget_old_reloads_1 (rtx x, const_rtx setter,
- void *data)
+forget_old_reloads_1 (rtx x, const_rtx, void *data)
{
unsigned int regno;
unsigned int nr;
if (!REG_P (x))
return;
- /* CLOBBER_HIGH is only supported for LRA. */
- gcc_assert (setter == NULL_RTX || GET_CODE (setter) != CLOBBER_HIGH);
-
regno = REGNO (x);
if (regno >= FIRST_PSEUDO_REGISTER)
: out_regno + k);
reg_reloaded_insn[regno + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
- if (targetm.hard_regno_call_part_clobbered (0, regno + k,
- mode))
- SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
- regno + k);
- else
- CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
- regno + k);
}
}
}
: in_regno + k);
reg_reloaded_insn[regno + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
- if (targetm.hard_regno_call_part_clobbered (0, regno + k,
- mode))
- SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
- regno + k);
- else
- CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
- regno + k);
}
}
}
reg_reloaded_insn[src_regno + k] = store_insn;
CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + k);
SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + k);
- if (targetm.hard_regno_call_part_clobbered
- (0, src_regno + k, mode))
- SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
- src_regno + k);
- else
- CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
- src_regno + k);
SET_HARD_REG_BIT (reg_is_output_reload, src_regno + k);
if (note)
SET_HARD_REG_BIT (reg_reloaded_died, src_regno);