Commit 73ca989c by Richard Sandiford Committed by Richard Sandiford

poly_int: lra frame offsets

This patch makes LRA use poly_int64s rather than HOST_WIDE_INTs
to store a frame offset (including in things like eliminations).

2017-12-20  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* lra-int.h (lra_reg): Change offset from int to poly_int64.
	(lra_insn_recog_data): Change sp_offset from HOST_WIDE_INT
	to poly_int64.
	(lra_eliminate_regs_1, eliminate_regs_in_insn): Change
	update_sp_offset from a HOST_WIDE_INT to a poly_int64.
	(lra_update_reg_val_offset, lra_reg_val_equal_p): Take the
	offset as a poly_int64 rather than an int.
	* lra-assigns.c (find_hard_regno_for_1): Handle poly_int64 offsets.
	(setup_live_pseudos_and_spill_after_risky_transforms): Likewise.
	* lra-constraints.c (equiv_address_substitution): Track offsets
	as poly_int64s.
	(emit_inc): Check poly_int_rtx_p instead of CONST_INT_P.
	(curr_insn_transform): Handle the new form of sp_offset.
	* lra-eliminations.c (lra_elim_table): Change previous_offset
	and offset from HOST_WIDE_INT to poly_int64.
	(print_elim_table, update_reg_eliminate): Update accordingly.
	(self_elim_offsets): Change from HOST_WIDE_INT to poly_int64_pod.
	(get_elimination): Update accordingly.
	(form_sum): Check poly_int_rtx_p instead of CONST_INT_P.
	(lra_eliminate_regs_1, eliminate_regs_in_insn): Change
	update_sp_offset from a HOST_WIDE_INT to a poly_int64.  Handle
	poly_int64 offsets generally.
	(curr_sp_change): Change from HOST_WIDE_INT to poly_int64.
	(mark_not_eliminable, init_elimination): Update accordingly.
	(remove_reg_equal_offset_note): Return a bool and pass the new
	offset back by pointer as a poly_int64.
	* lra-remat.c (change_sp_offset): Take sp_offset as a poly_int64
	rather than a HOST_WIDE_INT.
	(do_remat): Track offsets poly_int64s.
	* lra.c (lra_update_insn_recog_data, setup_sp_offset): Likewise.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r255876
parent d05d7551
...@@ -2,6 +2,41 @@ ...@@ -2,6 +2,41 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* lra-int.h (lra_reg): Change offset from int to poly_int64.
(lra_insn_recog_data): Change sp_offset from HOST_WIDE_INT
to poly_int64.
(lra_eliminate_regs_1, eliminate_regs_in_insn): Change
update_sp_offset from a HOST_WIDE_INT to a poly_int64.
(lra_update_reg_val_offset, lra_reg_val_equal_p): Take the
offset as a poly_int64 rather than an int.
* lra-assigns.c (find_hard_regno_for_1): Handle poly_int64 offsets.
(setup_live_pseudos_and_spill_after_risky_transforms): Likewise.
* lra-constraints.c (equiv_address_substitution): Track offsets
as poly_int64s.
(emit_inc): Check poly_int_rtx_p instead of CONST_INT_P.
(curr_insn_transform): Handle the new form of sp_offset.
* lra-eliminations.c (lra_elim_table): Change previous_offset
and offset from HOST_WIDE_INT to poly_int64.
(print_elim_table, update_reg_eliminate): Update accordingly.
(self_elim_offsets): Change from HOST_WIDE_INT to poly_int64_pod.
(get_elimination): Update accordingly.
(form_sum): Check poly_int_rtx_p instead of CONST_INT_P.
(lra_eliminate_regs_1, eliminate_regs_in_insn): Change
update_sp_offset from a HOST_WIDE_INT to a poly_int64. Handle
poly_int64 offsets generally.
(curr_sp_change): Change from HOST_WIDE_INT to poly_int64.
(mark_not_eliminable, init_elimination): Update accordingly.
(remove_reg_equal_offset_note): Return a bool and pass the new
offset back by pointer as a poly_int64.
* lra-remat.c (change_sp_offset): Take sp_offset as a poly_int64
rather than a HOST_WIDE_INT.
(do_remat): Track offsets poly_int64s.
* lra.c (lra_update_insn_recog_data, setup_sp_offset): Likewise.
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* rtl.h (mem_attrs): Add a default constructor. Change size and * rtl.h (mem_attrs): Add a default constructor. Change size and
offset from HOST_WIDE_INT to poly_int64. offset from HOST_WIDE_INT to poly_int64.
* emit-rtl.h (set_mem_offset, set_mem_size, adjust_address_1) * emit-rtl.h (set_mem_offset, set_mem_size, adjust_address_1)
...@@ -485,7 +485,8 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, ...@@ -485,7 +485,8 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno,
int hr, conflict_hr, nregs; int hr, conflict_hr, nregs;
machine_mode biggest_mode; machine_mode biggest_mode;
unsigned int k, conflict_regno; unsigned int k, conflict_regno;
int offset, val, biggest_nregs, nregs_diff; poly_int64 offset;
int val, biggest_nregs, nregs_diff;
enum reg_class rclass; enum reg_class rclass;
bitmap_iterator bi; bitmap_iterator bi;
bool *rclass_intersect_p; bool *rclass_intersect_p;
...@@ -1147,7 +1148,8 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap ...@@ -1147,7 +1148,8 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap
{ {
int p, i, j, n, regno, hard_regno; int p, i, j, n, regno, hard_regno;
unsigned int k, conflict_regno; unsigned int k, conflict_regno;
int val, offset; poly_int64 offset;
int val;
HARD_REG_SET conflict_set; HARD_REG_SET conflict_set;
machine_mode mode; machine_mode mode;
lra_live_range_t r; lra_live_range_t r;
......
...@@ -3084,7 +3084,8 @@ static bool ...@@ -3084,7 +3084,8 @@ static bool
equiv_address_substitution (struct address_info *ad) equiv_address_substitution (struct address_info *ad)
{ {
rtx base_reg, new_base_reg, index_reg, new_index_reg, *base_term, *index_term; rtx base_reg, new_base_reg, index_reg, new_index_reg, *base_term, *index_term;
HOST_WIDE_INT disp, scale; poly_int64 disp;
HOST_WIDE_INT scale;
bool change_p; bool change_p;
base_term = strip_subreg (ad->base_term); base_term = strip_subreg (ad->base_term);
...@@ -3115,6 +3116,7 @@ equiv_address_substitution (struct address_info *ad) ...@@ -3115,6 +3116,7 @@ equiv_address_substitution (struct address_info *ad)
} }
if (base_reg != new_base_reg) if (base_reg != new_base_reg)
{ {
poly_int64 offset;
if (REG_P (new_base_reg)) if (REG_P (new_base_reg))
{ {
*base_term = new_base_reg; *base_term = new_base_reg;
...@@ -3122,10 +3124,10 @@ equiv_address_substitution (struct address_info *ad) ...@@ -3122,10 +3124,10 @@ equiv_address_substitution (struct address_info *ad)
} }
else if (GET_CODE (new_base_reg) == PLUS else if (GET_CODE (new_base_reg) == PLUS
&& REG_P (XEXP (new_base_reg, 0)) && REG_P (XEXP (new_base_reg, 0))
&& CONST_INT_P (XEXP (new_base_reg, 1)) && poly_int_rtx_p (XEXP (new_base_reg, 1), &offset)
&& can_add_disp_p (ad)) && can_add_disp_p (ad))
{ {
disp += INTVAL (XEXP (new_base_reg, 1)); disp += offset;
*base_term = XEXP (new_base_reg, 0); *base_term = XEXP (new_base_reg, 0);
change_p = true; change_p = true;
} }
...@@ -3134,6 +3136,7 @@ equiv_address_substitution (struct address_info *ad) ...@@ -3134,6 +3136,7 @@ equiv_address_substitution (struct address_info *ad)
} }
if (index_reg != new_index_reg) if (index_reg != new_index_reg)
{ {
poly_int64 offset;
if (REG_P (new_index_reg)) if (REG_P (new_index_reg))
{ {
*index_term = new_index_reg; *index_term = new_index_reg;
...@@ -3141,16 +3144,16 @@ equiv_address_substitution (struct address_info *ad) ...@@ -3141,16 +3144,16 @@ equiv_address_substitution (struct address_info *ad)
} }
else if (GET_CODE (new_index_reg) == PLUS else if (GET_CODE (new_index_reg) == PLUS
&& REG_P (XEXP (new_index_reg, 0)) && REG_P (XEXP (new_index_reg, 0))
&& CONST_INT_P (XEXP (new_index_reg, 1)) && poly_int_rtx_p (XEXP (new_index_reg, 1), &offset)
&& can_add_disp_p (ad) && can_add_disp_p (ad)
&& (scale = get_index_scale (ad))) && (scale = get_index_scale (ad)))
{ {
disp += INTVAL (XEXP (new_index_reg, 1)) * scale; disp += offset * scale;
*index_term = XEXP (new_index_reg, 0); *index_term = XEXP (new_index_reg, 0);
change_p = true; change_p = true;
} }
} }
if (disp != 0) if (maybe_ne (disp, 0))
{ {
if (ad->disp != NULL) if (ad->disp != NULL)
*ad->disp = plus_constant (GET_MODE (*ad->inner), *ad->disp, disp); *ad->disp = plus_constant (GET_MODE (*ad->inner), *ad->disp, disp);
...@@ -3630,9 +3633,10 @@ emit_inc (enum reg_class new_rclass, rtx in, rtx value, int inc_amount) ...@@ -3630,9 +3633,10 @@ emit_inc (enum reg_class new_rclass, rtx in, rtx value, int inc_amount)
register. */ register. */
if (plus_p) if (plus_p)
{ {
if (CONST_INT_P (inc)) poly_int64 offset;
if (poly_int_rtx_p (inc, &offset))
emit_insn (gen_add2_insn (result, emit_insn (gen_add2_insn (result,
gen_int_mode (-INTVAL (inc), gen_int_mode (-offset,
GET_MODE (result)))); GET_MODE (result))));
else else
emit_insn (gen_sub2_insn (result, inc)); emit_insn (gen_sub2_insn (result, inc));
...@@ -4000,10 +4004,13 @@ curr_insn_transform (bool check_only_p) ...@@ -4000,10 +4004,13 @@ curr_insn_transform (bool check_only_p)
if (INSN_CODE (curr_insn) >= 0 if (INSN_CODE (curr_insn) >= 0
&& (p = get_insn_name (INSN_CODE (curr_insn))) != NULL) && (p = get_insn_name (INSN_CODE (curr_insn))) != NULL)
fprintf (lra_dump_file, " {%s}", p); fprintf (lra_dump_file, " {%s}", p);
if (curr_id->sp_offset != 0) if (maybe_ne (curr_id->sp_offset, 0))
fprintf (lra_dump_file, " (sp_off=%" HOST_WIDE_INT_PRINT "d)", {
curr_id->sp_offset); fprintf (lra_dump_file, " (sp_off=");
fprintf (lra_dump_file, "\n"); print_dec (curr_id->sp_offset, lra_dump_file);
fprintf (lra_dump_file, ")");
}
fprintf (lra_dump_file, "\n");
} }
/* Right now, for any pair of operands I and J that are required to /* Right now, for any pair of operands I and J that are required to
......
...@@ -79,9 +79,9 @@ struct lra_elim_table ...@@ -79,9 +79,9 @@ struct lra_elim_table
int to; int to;
/* Difference between values of the two hard registers above on /* Difference between values of the two hard registers above on
previous iteration. */ previous iteration. */
HOST_WIDE_INT previous_offset; poly_int64 previous_offset;
/* Difference between the values on the current iteration. */ /* Difference between the values on the current iteration. */
HOST_WIDE_INT offset; poly_int64 offset;
/* Nonzero if this elimination can be done. */ /* Nonzero if this elimination can be done. */
bool can_eliminate; bool can_eliminate;
/* CAN_ELIMINATE since the last check. */ /* CAN_ELIMINATE since the last check. */
...@@ -120,10 +120,14 @@ print_elim_table (FILE *f) ...@@ -120,10 +120,14 @@ print_elim_table (FILE *f)
struct lra_elim_table *ep; struct lra_elim_table *ep;
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++) for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
fprintf (f, "%s eliminate %d to %d (offset=" HOST_WIDE_INT_PRINT_DEC {
", prev_offset=" HOST_WIDE_INT_PRINT_DEC ")\n", fprintf (f, "%s eliminate %d to %d (offset=",
ep->can_eliminate ? "Can" : "Can't", ep->can_eliminate ? "Can" : "Can't", ep->from, ep->to);
ep->from, ep->to, ep->offset, ep->previous_offset); print_dec (ep->offset, f);
fprintf (f, ", prev_offset=");
print_dec (ep->previous_offset, f);
fprintf (f, ")\n");
}
} }
/* Print info about elimination table to stderr. */ /* Print info about elimination table to stderr. */
...@@ -161,7 +165,7 @@ static struct lra_elim_table self_elim_table; ...@@ -161,7 +165,7 @@ static struct lra_elim_table self_elim_table;
/* Offsets should be used to restore original offsets for eliminable /* Offsets should be used to restore original offsets for eliminable
hard register which just became not eliminable. Zero, hard register which just became not eliminable. Zero,
otherwise. */ otherwise. */
static HOST_WIDE_INT self_elim_offsets[FIRST_PSEUDO_REGISTER]; static poly_int64_pod self_elim_offsets[FIRST_PSEUDO_REGISTER];
/* Map: hard regno -> RTL presentation. RTL presentations of all /* Map: hard regno -> RTL presentation. RTL presentations of all
potentially eliminable hard registers are stored in the map. */ potentially eliminable hard registers are stored in the map. */
...@@ -193,6 +197,7 @@ static rtx ...@@ -193,6 +197,7 @@ static rtx
form_sum (rtx x, rtx y) form_sum (rtx x, rtx y)
{ {
machine_mode mode = GET_MODE (x); machine_mode mode = GET_MODE (x);
poly_int64 offset;
if (mode == VOIDmode) if (mode == VOIDmode)
mode = GET_MODE (y); mode = GET_MODE (y);
...@@ -200,10 +205,10 @@ form_sum (rtx x, rtx y) ...@@ -200,10 +205,10 @@ form_sum (rtx x, rtx y)
if (mode == VOIDmode) if (mode == VOIDmode)
mode = Pmode; mode = Pmode;
if (CONST_INT_P (x)) if (poly_int_rtx_p (x, &offset))
return plus_constant (mode, y, INTVAL (x)); return plus_constant (mode, y, offset);
else if (CONST_INT_P (y)) else if (poly_int_rtx_p (y, &offset))
return plus_constant (mode, x, INTVAL (y)); return plus_constant (mode, x, offset);
else if (CONSTANT_P (x)) else if (CONSTANT_P (x))
std::swap (x, y); std::swap (x, y);
...@@ -252,14 +257,14 @@ get_elimination (rtx reg) ...@@ -252,14 +257,14 @@ get_elimination (rtx reg)
{ {
int hard_regno; int hard_regno;
struct lra_elim_table *ep; struct lra_elim_table *ep;
HOST_WIDE_INT offset;
lra_assert (REG_P (reg)); lra_assert (REG_P (reg));
if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
return NULL; return NULL;
if ((ep = elimination_map[hard_regno]) != NULL) if ((ep = elimination_map[hard_regno]) != NULL)
return ep->from_rtx != reg ? NULL : ep; return ep->from_rtx != reg ? NULL : ep;
if ((offset = self_elim_offsets[hard_regno]) == 0) poly_int64 offset = self_elim_offsets[hard_regno];
if (known_eq (offset, 0))
return NULL; return NULL;
/* This is an iteration to restore offsets just after HARD_REGNO /* This is an iteration to restore offsets just after HARD_REGNO
stopped to be eliminable. */ stopped to be eliminable. */
...@@ -325,7 +330,7 @@ move_plus_up (rtx x) ...@@ -325,7 +330,7 @@ move_plus_up (rtx x)
rtx rtx
lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
bool subst_p, bool update_p, bool subst_p, bool update_p,
HOST_WIDE_INT update_sp_offset, bool full_p) poly_int64 update_sp_offset, bool full_p)
{ {
enum rtx_code code = GET_CODE (x); enum rtx_code code = GET_CODE (x);
struct lra_elim_table *ep; struct lra_elim_table *ep;
...@@ -335,7 +340,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -335,7 +340,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
int copied = 0; int copied = 0;
lra_assert (!update_p || !full_p); lra_assert (!update_p || !full_p);
lra_assert (update_sp_offset == 0 || (!subst_p && update_p && !full_p)); lra_assert (known_eq (update_sp_offset, 0)
|| (!subst_p && update_p && !full_p));
if (! current_function_decl) if (! current_function_decl)
return x; return x;
...@@ -360,7 +366,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -360,7 +366,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
{ {
rtx to = subst_p ? ep->to_rtx : ep->from_rtx; rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
if (update_sp_offset != 0) if (maybe_ne (update_sp_offset, 0))
{ {
if (ep->to_rtx == stack_pointer_rtx) if (ep->to_rtx == stack_pointer_rtx)
return plus_constant (Pmode, to, update_sp_offset); return plus_constant (Pmode, to, update_sp_offset);
...@@ -387,20 +393,21 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -387,20 +393,21 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
{ {
if ((ep = get_elimination (XEXP (x, 0))) != NULL) if ((ep = get_elimination (XEXP (x, 0))) != NULL)
{ {
HOST_WIDE_INT offset; poly_int64 offset, curr_offset;
rtx to = subst_p ? ep->to_rtx : ep->from_rtx; rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
if (! update_p && ! full_p) if (! update_p && ! full_p)
return gen_rtx_PLUS (Pmode, to, XEXP (x, 1)); return gen_rtx_PLUS (Pmode, to, XEXP (x, 1));
if (update_sp_offset != 0) if (maybe_ne (update_sp_offset, 0))
offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0; offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0;
else else
offset = (update_p offset = (update_p
? ep->offset - ep->previous_offset : ep->offset); ? ep->offset - ep->previous_offset : ep->offset);
if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
offset -= lra_get_insn_recog_data (insn)->sp_offset; offset -= lra_get_insn_recog_data (insn)->sp_offset;
if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == -offset) if (poly_int_rtx_p (XEXP (x, 1), &curr_offset)
&& known_eq (curr_offset, -offset))
return to; return to;
else else
return gen_rtx_PLUS (Pmode, to, return gen_rtx_PLUS (Pmode, to,
...@@ -449,7 +456,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -449,7 +456,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
{ {
rtx to = subst_p ? ep->to_rtx : ep->from_rtx; rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
if (update_sp_offset != 0) if (maybe_ne (update_sp_offset, 0))
{ {
if (ep->to_rtx == stack_pointer_rtx) if (ep->to_rtx == stack_pointer_rtx)
return plus_constant (Pmode, return plus_constant (Pmode,
...@@ -464,7 +471,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ...@@ -464,7 +471,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
* INTVAL (XEXP (x, 1))); * INTVAL (XEXP (x, 1)));
else if (full_p) else if (full_p)
{ {
HOST_WIDE_INT offset = ep->offset; poly_int64 offset = ep->offset;
if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
offset -= lra_get_insn_recog_data (insn)->sp_offset; offset -= lra_get_insn_recog_data (insn)->sp_offset;
...@@ -711,7 +718,7 @@ lra_eliminate_regs (rtx x, machine_mode mem_mode, ...@@ -711,7 +718,7 @@ lra_eliminate_regs (rtx x, machine_mode mem_mode,
/* Stack pointer offset before the current insn relative to one at the /* Stack pointer offset before the current insn relative to one at the
func start. RTL insns can change SP explicitly. We keep the func start. RTL insns can change SP explicitly. We keep the
changes from one insn to another through this variable. */ changes from one insn to another through this variable. */
static HOST_WIDE_INT curr_sp_change; static poly_int64 curr_sp_change;
/* Scan rtx X for references to elimination source or target registers /* Scan rtx X for references to elimination source or target registers
in contexts that would prevent the elimination from happening. in contexts that would prevent the elimination from happening.
...@@ -725,6 +732,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) ...@@ -725,6 +732,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode)
struct lra_elim_table *ep; struct lra_elim_table *ep;
int i, j; int i, j;
const char *fmt; const char *fmt;
poly_int64 offset = 0;
switch (code) switch (code)
{ {
...@@ -738,7 +746,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) ...@@ -738,7 +746,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode)
&& ((code != PRE_MODIFY && code != POST_MODIFY) && ((code != PRE_MODIFY && code != POST_MODIFY)
|| (GET_CODE (XEXP (x, 1)) == PLUS || (GET_CODE (XEXP (x, 1)) == PLUS
&& XEXP (x, 0) == XEXP (XEXP (x, 1), 0) && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
&& CONST_INT_P (XEXP (XEXP (x, 1), 1))))) && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset))))
{ {
int size = GET_MODE_SIZE (mem_mode); int size = GET_MODE_SIZE (mem_mode);
...@@ -752,7 +760,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) ...@@ -752,7 +760,7 @@ mark_not_eliminable (rtx x, machine_mode mem_mode)
else if (code == PRE_INC || code == POST_INC) else if (code == PRE_INC || code == POST_INC)
curr_sp_change += size; curr_sp_change += size;
else if (code == PRE_MODIFY || code == POST_MODIFY) else if (code == PRE_MODIFY || code == POST_MODIFY)
curr_sp_change += INTVAL (XEXP (XEXP (x, 1), 1)); curr_sp_change += offset;
} }
else if (REG_P (XEXP (x, 0)) else if (REG_P (XEXP (x, 0))
&& REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER) && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
...@@ -802,9 +810,9 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) ...@@ -802,9 +810,9 @@ mark_not_eliminable (rtx x, machine_mode mem_mode)
if (SET_DEST (x) == stack_pointer_rtx if (SET_DEST (x) == stack_pointer_rtx
&& GET_CODE (SET_SRC (x)) == PLUS && GET_CODE (SET_SRC (x)) == PLUS
&& XEXP (SET_SRC (x), 0) == SET_DEST (x) && XEXP (SET_SRC (x), 0) == SET_DEST (x)
&& CONST_INT_P (XEXP (SET_SRC (x), 1))) && poly_int_rtx_p (XEXP (SET_SRC (x), 1), &offset))
{ {
curr_sp_change += INTVAL (XEXP (SET_SRC (x), 1)); curr_sp_change += offset;
return; return;
} }
if (! REG_P (SET_DEST (x)) if (! REG_P (SET_DEST (x))
...@@ -859,11 +867,11 @@ mark_not_eliminable (rtx x, machine_mode mem_mode) ...@@ -859,11 +867,11 @@ mark_not_eliminable (rtx x, machine_mode mem_mode)
#ifdef HARD_FRAME_POINTER_REGNUM #ifdef HARD_FRAME_POINTER_REGNUM
/* Find offset equivalence note for reg WHAT in INSN and return the /* Search INSN's reg notes to see whether the destination is equal to
found elmination offset. If the note is not found, return NULL. WHAT + C for some constant C. Return true if so, storing C in
Remove the found note. */ *OFFSET_OUT and removing the reg note. */
static rtx static bool
remove_reg_equal_offset_note (rtx_insn *insn, rtx what) remove_reg_equal_offset_note (rtx_insn *insn, rtx what, poly_int64 *offset_out)
{ {
rtx link, *link_loc; rtx link, *link_loc;
...@@ -873,12 +881,12 @@ remove_reg_equal_offset_note (rtx_insn *insn, rtx what) ...@@ -873,12 +881,12 @@ remove_reg_equal_offset_note (rtx_insn *insn, rtx what)
if (REG_NOTE_KIND (link) == REG_EQUAL if (REG_NOTE_KIND (link) == REG_EQUAL
&& GET_CODE (XEXP (link, 0)) == PLUS && GET_CODE (XEXP (link, 0)) == PLUS
&& XEXP (XEXP (link, 0), 0) == what && XEXP (XEXP (link, 0), 0) == what
&& CONST_INT_P (XEXP (XEXP (link, 0), 1))) && poly_int_rtx_p (XEXP (XEXP (link, 0), 1), offset_out))
{ {
*link_loc = XEXP (link, 1); *link_loc = XEXP (link, 1);
return XEXP (XEXP (link, 0), 1); return true;
} }
return NULL_RTX; return false;
} }
#endif #endif
...@@ -899,7 +907,7 @@ remove_reg_equal_offset_note (rtx_insn *insn, rtx what) ...@@ -899,7 +907,7 @@ remove_reg_equal_offset_note (rtx_insn *insn, rtx what)
void void
eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
HOST_WIDE_INT update_sp_offset) poly_int64 update_sp_offset)
{ {
int icode = recog_memoized (insn); int icode = recog_memoized (insn);
rtx old_set = single_set (insn); rtx old_set = single_set (insn);
...@@ -940,28 +948,21 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, ...@@ -940,28 +948,21 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
nonlocal goto. */ nonlocal goto. */
{ {
rtx src = SET_SRC (old_set); rtx src = SET_SRC (old_set);
rtx off = remove_reg_equal_offset_note (insn, ep->to_rtx); poly_int64 offset = 0;
/* We should never process such insn with non-zero /* We should never process such insn with non-zero
UPDATE_SP_OFFSET. */ UPDATE_SP_OFFSET. */
lra_assert (update_sp_offset == 0); lra_assert (known_eq (update_sp_offset, 0));
if (off != NULL_RTX if (remove_reg_equal_offset_note (insn, ep->to_rtx, &offset)
|| src == ep->to_rtx || strip_offset (src, &offset) == ep->to_rtx)
|| (GET_CODE (src) == PLUS
&& XEXP (src, 0) == ep->to_rtx
&& CONST_INT_P (XEXP (src, 1))))
{ {
HOST_WIDE_INT offset;
if (replace_p) if (replace_p)
{ {
SET_DEST (old_set) = ep->to_rtx; SET_DEST (old_set) = ep->to_rtx;
lra_update_insn_recog_data (insn); lra_update_insn_recog_data (insn);
return; return;
} }
offset = (off != NULL_RTX ? INTVAL (off)
: src == ep->to_rtx ? 0 : INTVAL (XEXP (src, 1)));
offset -= (ep->offset - ep->previous_offset); offset -= (ep->offset - ep->previous_offset);
src = plus_constant (Pmode, ep->to_rtx, offset); src = plus_constant (Pmode, ep->to_rtx, offset);
...@@ -997,13 +998,13 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, ...@@ -997,13 +998,13 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
currently support: a single set with the source or a REG_EQUAL currently support: a single set with the source or a REG_EQUAL
note being a PLUS of an eliminable register and a constant. */ note being a PLUS of an eliminable register and a constant. */
plus_src = plus_cst_src = 0; plus_src = plus_cst_src = 0;
poly_int64 offset = 0;
if (old_set && REG_P (SET_DEST (old_set))) if (old_set && REG_P (SET_DEST (old_set)))
{ {
if (GET_CODE (SET_SRC (old_set)) == PLUS) if (GET_CODE (SET_SRC (old_set)) == PLUS)
plus_src = SET_SRC (old_set); plus_src = SET_SRC (old_set);
/* First see if the source is of the form (plus (...) CST). */ /* First see if the source is of the form (plus (...) CST). */
if (plus_src if (plus_src && poly_int_rtx_p (XEXP (plus_src, 1), &offset))
&& CONST_INT_P (XEXP (plus_src, 1)))
plus_cst_src = plus_src; plus_cst_src = plus_src;
/* Check that the first operand of the PLUS is a hard reg or /* Check that the first operand of the PLUS is a hard reg or
the lowpart subreg of one. */ the lowpart subreg of one. */
...@@ -1021,7 +1022,6 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, ...@@ -1021,7 +1022,6 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
if (plus_cst_src) if (plus_cst_src)
{ {
rtx reg = XEXP (plus_cst_src, 0); rtx reg = XEXP (plus_cst_src, 0);
HOST_WIDE_INT offset = INTVAL (XEXP (plus_cst_src, 1));
if (GET_CODE (reg) == SUBREG) if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg); reg = SUBREG_REG (reg);
...@@ -1032,7 +1032,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, ...@@ -1032,7 +1032,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
if (! replace_p) if (! replace_p)
{ {
if (update_sp_offset == 0) if (known_eq (update_sp_offset, 0))
offset += (ep->offset - ep->previous_offset); offset += (ep->offset - ep->previous_offset);
if (ep->to_rtx == stack_pointer_rtx) if (ep->to_rtx == stack_pointer_rtx)
{ {
...@@ -1051,7 +1051,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, ...@@ -1051,7 +1051,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
the cost of the insn by replacing a simple REG with (plus the cost of the insn by replacing a simple REG with (plus
(reg sp) CST). So try only when we already had a PLUS (reg sp) CST). So try only when we already had a PLUS
before. */ before. */
if (offset == 0 || plus_src) if (known_eq (offset, 0) || plus_src)
{ {
rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset); rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset);
...@@ -1239,7 +1239,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) ...@@ -1239,7 +1239,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
if (lra_dump_file != NULL) if (lra_dump_file != NULL)
fprintf (lra_dump_file, " Using elimination %d to %d now\n", fprintf (lra_dump_file, " Using elimination %d to %d now\n",
ep1->from, ep1->to); ep1->from, ep1->to);
lra_assert (ep1->previous_offset == 0); lra_assert (known_eq (ep1->previous_offset, 0));
ep1->previous_offset = ep->offset; ep1->previous_offset = ep->offset;
} }
else else
...@@ -1251,7 +1251,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) ...@@ -1251,7 +1251,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
fprintf (lra_dump_file, " %d is not eliminable at all\n", fprintf (lra_dump_file, " %d is not eliminable at all\n",
ep->from); ep->from);
self_elim_offsets[ep->from] = -ep->offset; self_elim_offsets[ep->from] = -ep->offset;
if (ep->offset != 0) if (maybe_ne (ep->offset, 0))
bitmap_ior_into (insns_with_changed_offsets, bitmap_ior_into (insns_with_changed_offsets,
&lra_reg_info[ep->from].insn_bitmap); &lra_reg_info[ep->from].insn_bitmap);
} }
...@@ -1271,7 +1271,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) ...@@ -1271,7 +1271,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
the usage for pseudos. */ the usage for pseudos. */
if (ep->from != ep->to) if (ep->from != ep->to)
SET_HARD_REG_BIT (temp_hard_reg_set, ep->to); SET_HARD_REG_BIT (temp_hard_reg_set, ep->to);
if (ep->previous_offset != ep->offset) if (maybe_ne (ep->previous_offset, ep->offset))
{ {
bitmap_ior_into (insns_with_changed_offsets, bitmap_ior_into (insns_with_changed_offsets,
&lra_reg_info[ep->from].insn_bitmap); &lra_reg_info[ep->from].insn_bitmap);
...@@ -1357,13 +1357,13 @@ init_elimination (void) ...@@ -1357,13 +1357,13 @@ init_elimination (void)
if (NONDEBUG_INSN_P (insn)) if (NONDEBUG_INSN_P (insn))
{ {
mark_not_eliminable (PATTERN (insn), VOIDmode); mark_not_eliminable (PATTERN (insn), VOIDmode);
if (curr_sp_change != 0 if (maybe_ne (curr_sp_change, 0)
&& find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX)) && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
stop_to_sp_elimination_p = true; stop_to_sp_elimination_p = true;
} }
} }
if (! frame_pointer_needed if (! frame_pointer_needed
&& (curr_sp_change != 0 || stop_to_sp_elimination_p) && (maybe_ne (curr_sp_change, 0) || stop_to_sp_elimination_p)
&& bb->succs && bb->succs->length () != 0) && bb->succs && bb->succs->length () != 0)
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++) for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
if (ep->to == STACK_POINTER_REGNUM) if (ep->to == STACK_POINTER_REGNUM)
......
...@@ -106,7 +106,7 @@ struct lra_reg ...@@ -106,7 +106,7 @@ struct lra_reg
they do not conflict. */ they do not conflict. */
int val; int val;
/* Offset from relative eliminate register to pesudo reg. */ /* Offset from relative eliminate register to pesudo reg. */
int offset; poly_int64 offset;
/* These members are set up in lra-lives.c and updated in /* These members are set up in lra-lives.c and updated in
lra-coalesce.c. */ lra-coalesce.c. */
/* The biggest size mode in which each pseudo reg is referred in /* The biggest size mode in which each pseudo reg is referred in
...@@ -213,7 +213,7 @@ struct lra_insn_recog_data ...@@ -213,7 +213,7 @@ struct lra_insn_recog_data
insn. */ insn. */
int used_insn_alternative; int used_insn_alternative;
/* SP offset before the insn relative to one at the func start. */ /* SP offset before the insn relative to one at the func start. */
HOST_WIDE_INT sp_offset; poly_int64 sp_offset;
/* The insn itself. */ /* The insn itself. */
rtx_insn *insn; rtx_insn *insn;
/* Common data for insns with the same ICODE. Asm insns (their /* Common data for insns with the same ICODE. Asm insns (their
...@@ -406,8 +406,8 @@ extern bool lra_remat (void); ...@@ -406,8 +406,8 @@ extern bool lra_remat (void);
extern void lra_debug_elim_table (void); extern void lra_debug_elim_table (void);
extern int lra_get_elimination_hard_regno (int); extern int lra_get_elimination_hard_regno (int);
extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode, extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode,
bool, bool, HOST_WIDE_INT, bool); bool, bool, poly_int64, bool);
extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, HOST_WIDE_INT); extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64);
extern void lra_eliminate (bool, bool); extern void lra_eliminate (bool, bool);
extern void lra_eliminate_reg_if_possible (rtx *); extern void lra_eliminate_reg_if_possible (rtx *);
...@@ -493,7 +493,7 @@ lra_get_insn_recog_data (rtx_insn *insn) ...@@ -493,7 +493,7 @@ lra_get_insn_recog_data (rtx_insn *insn)
/* Update offset from pseudos with VAL by INCR. */ /* Update offset from pseudos with VAL by INCR. */
static inline void static inline void
lra_update_reg_val_offset (int val, int incr) lra_update_reg_val_offset (int val, poly_int64 incr)
{ {
int i; int i;
...@@ -506,10 +506,10 @@ lra_update_reg_val_offset (int val, int incr) ...@@ -506,10 +506,10 @@ lra_update_reg_val_offset (int val, int incr)
/* Return true if register content is equal to VAL with OFFSET. */ /* Return true if register content is equal to VAL with OFFSET. */
static inline bool static inline bool
lra_reg_val_equal_p (int regno, int val, int offset) lra_reg_val_equal_p (int regno, int val, poly_int64 offset)
{ {
if (lra_reg_info[regno].val == val if (lra_reg_info[regno].val == val
&& lra_reg_info[regno].offset == offset) && known_eq (lra_reg_info[regno].offset, offset))
return true; return true;
return false; return false;
......
...@@ -994,7 +994,7 @@ calculate_global_remat_bb_data (void) ...@@ -994,7 +994,7 @@ calculate_global_remat_bb_data (void)
/* Setup sp offset attribute to SP_OFFSET for all INSNS. */ /* Setup sp offset attribute to SP_OFFSET for all INSNS. */
static void static void
change_sp_offset (rtx_insn *insns, HOST_WIDE_INT sp_offset) change_sp_offset (rtx_insn *insns, poly_int64 sp_offset)
{ {
for (rtx_insn *insn = insns; insn != NULL; insn = NEXT_INSN (insn)) for (rtx_insn *insn = insns; insn != NULL; insn = NEXT_INSN (insn))
eliminate_regs_in_insn (insn, false, false, sp_offset); eliminate_regs_in_insn (insn, false, false, sp_offset);
...@@ -1118,7 +1118,7 @@ do_remat (void) ...@@ -1118,7 +1118,7 @@ do_remat (void)
int i, hard_regno, nregs; int i, hard_regno, nregs;
int dst_hard_regno, dst_nregs; int dst_hard_regno, dst_nregs;
rtx_insn *remat_insn = NULL; rtx_insn *remat_insn = NULL;
HOST_WIDE_INT cand_sp_offset = 0; poly_int64 cand_sp_offset = 0;
if (cand != NULL) if (cand != NULL)
{ {
lra_insn_recog_data_t cand_id lra_insn_recog_data_t cand_id
...@@ -1241,8 +1241,8 @@ do_remat (void) ...@@ -1241,8 +1241,8 @@ do_remat (void)
if (remat_insn != NULL) if (remat_insn != NULL)
{ {
HOST_WIDE_INT sp_offset_change = cand_sp_offset - id->sp_offset; poly_int64 sp_offset_change = cand_sp_offset - id->sp_offset;
if (sp_offset_change != 0) if (maybe_ne (sp_offset_change, 0))
change_sp_offset (remat_insn, sp_offset_change); change_sp_offset (remat_insn, sp_offset_change);
update_scratch_ops (remat_insn); update_scratch_ops (remat_insn);
lra_process_new_insns (insn, remat_insn, NULL, lra_process_new_insns (insn, remat_insn, NULL,
......
...@@ -1188,7 +1188,7 @@ lra_update_insn_recog_data (rtx_insn *insn) ...@@ -1188,7 +1188,7 @@ lra_update_insn_recog_data (rtx_insn *insn)
int n; int n;
unsigned int uid = INSN_UID (insn); unsigned int uid = INSN_UID (insn);
struct lra_static_insn_data *insn_static_data; struct lra_static_insn_data *insn_static_data;
HOST_WIDE_INT sp_offset = 0; poly_int64 sp_offset = 0;
check_and_expand_insn_recog_data (uid); check_and_expand_insn_recog_data (uid);
if ((data = lra_insn_recog_data[uid]) != NULL if ((data = lra_insn_recog_data[uid]) != NULL
...@@ -1831,8 +1831,8 @@ static void ...@@ -1831,8 +1831,8 @@ static void
setup_sp_offset (rtx_insn *from, rtx_insn *last) setup_sp_offset (rtx_insn *from, rtx_insn *last)
{ {
rtx_insn *before = next_nonnote_nondebug_insn_bb (last); rtx_insn *before = next_nonnote_nondebug_insn_bb (last);
HOST_WIDE_INT offset = (before == NULL_RTX || ! INSN_P (before) poly_int64 offset = (before == NULL_RTX || ! INSN_P (before)
? 0 : lra_get_insn_recog_data (before)->sp_offset); ? 0 : lra_get_insn_recog_data (before)->sp_offset);
for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn)) for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
lra_get_insn_recog_data (insn)->sp_offset = offset; lra_get_insn_recog_data (insn)->sp_offset = offset;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment