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
......
...@@ -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