#include "toplev.h"
#include "except.h"
#include "tree.h"
+#include "timevar.h"
+#include "tree-pass.h"
static int reload_cse_noop_set_p (rtx);
static void reload_cse_simplify (rtx, rtx);
op_alt_regno[i][j] = regno;
}
j++;
+ class = (int) NO_REGS;
break;
}
p += CONSTRAINT_LEN (c, p);
int this_nregs = alternative_nregs[alternative_order[j]];
if (this_reject < best_reject
- || (this_reject == best_reject && this_nregs < best_nregs))
+ || (this_reject == best_reject && this_nregs > best_nregs))
{
best = j;
best_reject = this_reject;
destination. */
min_labelno = get_first_label_num ();
n_labels = max_label_num () - min_labelno;
- label_live = xmalloc (n_labels * sizeof (HARD_REG_SET));
+ label_live = XNEWVEC (HARD_REG_SET, n_labels);
CLEAR_HARD_REG_SET (ever_live_at_start);
FOR_EACH_BB_REVERSE (bb)
if (apply_change_group ())
{
- rtx *np;
-
/* Delete the reg-reg addition. */
delete_insn (insn);
if (reg_state[regno].offset != const0_rtx)
/* Previous REG_EQUIV / REG_EQUAL notes for PREV
are now invalid. */
- for (np = ®_NOTES (prev); *np;)
- {
- if (REG_NOTE_KIND (*np) == REG_EQUAL
- || REG_NOTE_KIND (*np) == REG_EQUIV)
- *np = XEXP (*np, 1);
- else
- np = &XEXP (*np, 1);
- }
+ remove_reg_equal_equiv_notes (prev);
reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
reg_state[REGNO (const_reg)].store_ruid
rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
validate_change (insn, &SET_SRC (pat), tem, 0);
}
- else
+ else if (GET_MODE (reg) != BImode)
{
enum machine_mode narrow_mode;
for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
{
unsigned int regno = 0;
+ unsigned int nregs = 0;
unsigned int i;
enum machine_mode mode = GET_MODE (dst);
GET_MODE (SUBREG_REG (dst)),
SUBREG_BYTE (dst),
GET_MODE (dst));
+ nregs = subreg_nregs (dst);
dst = SUBREG_REG (dst);
}
return;
regno += REGNO (dst);
+ if (!nregs)
+ nregs = hard_regno_nregs[regno][mode];
if (SCALAR_INT_MODE_P (GET_MODE (dst))
- && hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET
+ && nregs == 1 && GET_CODE (set) == SET
&& GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
&& GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
{
}
else
{
- unsigned int endregno = regno + hard_regno_nregs[regno][mode];
+ unsigned int endregno = regno + nregs;
for (i = regno; i < endregno; i++)
/* Reset the information about this register. */
reg_set_luid[i] = 0;
}
}
+\f
+static bool
+gate_handle_postreload (void)
+{
+ return (optimize > 0);
+}
+
+
+static unsigned int
+rest_of_handle_postreload (void)
+{
+ /* Do a very simple CSE pass over just the hard registers. */
+ reload_cse_regs (get_insns ());
+ /* reload_cse_regs can eliminate potentially-trapping MEMs.
+ Remove any EH edges associated with them. */
+ if (flag_non_call_exceptions)
+ purge_all_dead_edges ();
+ return 0;
+}
+
+struct tree_opt_pass pass_postreload_cse =
+{
+ "postreload", /* name */
+ gate_handle_postreload, /* gate */
+ rest_of_handle_postreload, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_RELOAD_CSE_REGS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func, /* todo_flags_finish */
+ 'o' /* letter */
+};
+