diff options
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index f880e5a..b19be93 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -45,7 +45,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #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 @@ -546,7 +548,7 @@ compute_use_by_pseudos (HARD_REG_SET *to, regset from) 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); @@ -746,7 +748,7 @@ reload (rtx first, int global) && 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. @@ -1154,9 +1156,11 @@ reload (rtx first, int global) 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: @@ -1274,6 +1278,7 @@ reload (rtx first, int global) || 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 @@ -1310,7 +1315,7 @@ reload (rtx first, int global) 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) @@ -2042,8 +2047,8 @@ alter_reg (int i, int from_reg) /* 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. */ @@ -2072,6 +2077,8 @@ alter_reg (int i, int from_reg) 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 @@ -2084,7 +2091,8 @@ alter_reg (int i, int from_reg) 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. */ @@ -2094,7 +2102,6 @@ alter_reg (int i, int from_reg) >= inherent_size) && MEM_ALIGN (spill_stack_slot[from_reg]) >= min_align) x = spill_stack_slot[from_reg]; - /* Allocate a bigger slot. */ else { @@ -2121,9 +2128,18 @@ alter_reg (int i, int from_reg) /* 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) { @@ -2178,11 +2194,11 @@ alter_reg (int i, int from_reg) } } -/* 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; @@ -2191,7 +2207,17 @@ mark_home_live (int regno) return; lim = end_hard_regno (PSEUDO_REGNO_MODE (regno), 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)); } /* This function handles the tracking of elimination offsets around branches. @@ -3749,7 +3775,7 @@ spill_hard_reg (unsigned int regno, int cant_eliminate) 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 @@ -3793,9 +3819,9 @@ finish_spills (int global) { 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; @@ -3938,8 +3964,11 @@ scan_paradoxical_subregs (rtx x) 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: @@ -8144,7 +8173,7 @@ delete_output_reload (rtx insn, int j, int last_reload_reg) 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; |