#include "toplev.h"
#include "except.h"
#include "tree.h"
+#include "df.h"
#include "target.h"
+#include "dse.h"
/* This file contains the reload pass of the compiler, which is
run after register allocation has been done. It checks that
if (r < 0)
{
/* reload_combine uses the information from
- BASIC_BLOCK->global_live_at_start, which might still
+ DF_RA_LIVE_IN (BASIC_BLOCK), which might still
contain registers that have not actually been allocated
since they have an equivalence. */
gcc_assert (reload_completed);
&& has_nonexceptional_receiver ()))
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
- regs_ever_live[i] = 1;
+ df_set_regs_ever_live (i, true);
/* Find all the pseudo registers that didn't get hard regs
but do have known equivalent constants or memory slots.
if (! frame_pointer_needed)
FOR_EACH_BB (bb)
- CLEAR_REGNO_REG_SET (bb->il.rtl->global_live_at_start,
- HARD_FRAME_POINTER_REGNUM);
-
+ {
+ bitmap_clear_bit (df_get_live_in (bb), HARD_FRAME_POINTER_REGNUM);
+ bitmap_clear_bit (df_get_live_top (bb), HARD_FRAME_POINTER_REGNUM);
+ }
+
/* Come here (with failure set nonzero) if we can't get enough spill
regs. */
failed:
|| REG_NOTE_KIND (*pnote) == REG_UNUSED
|| REG_NOTE_KIND (*pnote) == REG_INC
|| REG_NOTE_KIND (*pnote) == REG_RETVAL
+ || REG_NOTE_KIND (*pnote) == REG_LIBCALL_ID
|| REG_NOTE_KIND (*pnote) == REG_LIBCALL)
*pnote = XEXP (*pnote, 1);
else
static int verbose_warned = 0;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (regs_ever_live[i] && ! fixed_regs[i] && call_used_regs[i])
+ if (df_regs_ever_live_p (i) && ! fixed_regs[i] && call_used_regs[i])
size += UNITS_PER_WORD;
if (size > STACK_CHECK_MAX_FRAME_SIZE)
/* Modify the reg-rtx to contain the new hard reg
number or else to contain its pseudo reg number. */
- REGNO (regno_reg_rtx[i])
- = reg_renumber[i] >= 0 ? reg_renumber[i] : i;
+ SET_REGNO (regno_reg_rtx[i],
+ reg_renumber[i] >= 0 ? reg_renumber[i] : i);
/* If we have a pseudo that is needed but has no hard reg or equivalent,
allocate a stack slot for it. */
inherent space, and no less total space, then the previous slot. */
if (from_reg == -1)
{
+ HOST_WIDE_INT alias_set = new_alias_set ();
+
/* No known place to spill from => no slot to reuse. */
x = assign_stack_local (mode, total_size,
min_align > inherent_align
adjust = inherent_size - total_size;
/* Nothing can alias this slot except this pseudo. */
- set_mem_alias_set (x, new_alias_set ());
+ set_mem_alias_set (x, alias_set);
+ dse_record_singleton_alias_set (alias_set, mode);
}
/* Reuse a stack slot if possible. */
>= inherent_size)
&& MEM_ALIGN (spill_stack_slot[from_reg]) >= min_align)
x = spill_stack_slot[from_reg];
-
/* Allocate a bigger slot. */
else
{
/* All pseudos mapped to this slot can alias each other. */
if (spill_stack_slot[from_reg])
- set_mem_alias_set (x, MEM_ALIAS_SET (spill_stack_slot[from_reg]));
+ {
+ HOST_WIDE_INT alias_set
+ = MEM_ALIAS_SET (spill_stack_slot[from_reg]);
+ set_mem_alias_set (x, alias_set);
+ dse_invalidate_singleton_alias_set (alias_set);
+ }
else
- set_mem_alias_set (x, new_alias_set ());
+ {
+ HOST_WIDE_INT alias_set = new_alias_set ();
+ set_mem_alias_set (x, alias_set);
+ dse_record_singleton_alias_set (alias_set, mode);
+ }
if (BYTES_BIG_ENDIAN)
{
}
}
-/* Mark the slots in regs_ever_live for the hard regs
- used by pseudo-reg number REGNO. */
+/* Mark the slots in regs_ever_live for the hard regs used by
+ pseudo-reg number REGNO, accessed in MODE. */
-void
-mark_home_live (int regno)
+static void
+mark_home_live_1 (int regno, enum machine_mode mode)
{
int i, lim;
i = reg_renumber[regno];
if (i < 0)
return;
- lim = end_hard_regno (PSEUDO_REGNO_MODE (regno), i);
+ lim = end_hard_regno (mode, i);
while (i < lim)
- regs_ever_live[i++] = 1;
+ df_set_regs_ever_live(i++, true);
+}
+
+/* Mark the slots in regs_ever_live for the hard regs
+ used by pseudo-reg number REGNO. */
+
+void
+mark_home_live (int regno)
+{
+ if (reg_renumber[regno] >= 0)
+ mark_home_live_1 (regno, PSEUDO_REGNO_MODE (regno));
}
\f
/* This function handles the tracking of elimination offsets around branches.
if (cant_eliminate)
{
SET_HARD_REG_BIT (bad_spill_regs_global, regno);
- regs_ever_live[regno] = 1;
+ df_set_regs_ever_live (regno, true);
}
/* Spill every pseudo reg that was allocated to this reg
{
spill_reg_order[i] = n_spills;
spill_regs[n_spills++] = i;
- if (num_eliminable && ! regs_ever_live[i])
+ if (num_eliminable && ! df_regs_ever_live_p (i))
something_changed = 1;
- regs_ever_live[i] = 1;
+ df_set_regs_ever_live (i, true);
}
else
spill_reg_order[i] = -1;
if (REG_P (SUBREG_REG (x))
&& (GET_MODE_SIZE (GET_MODE (x))
> reg_max_ref_width[REGNO (SUBREG_REG (x))]))
- reg_max_ref_width[REGNO (SUBREG_REG (x))]
- = GET_MODE_SIZE (GET_MODE (x));
+ {
+ reg_max_ref_width[REGNO (SUBREG_REG (x))]
+ = GET_MODE_SIZE (GET_MODE (x));
+ mark_home_live_1 (REGNO (SUBREG_REG (x)), GET_MODE (x));
+ }
return;
default:
if (rld[j].out != rld[j].in
&& REG_N_DEATHS (REGNO (reg)) == 1
&& REG_N_SETS (REGNO (reg)) == 1
- && REG_BASIC_BLOCK (REGNO (reg)) >= 0
+ && REG_BASIC_BLOCK (REGNO (reg)) >= NUM_FIXED_BLOCKS
&& find_regno_note (insn, REG_DEAD, REGNO (reg)))
{
rtx i2;