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 @@
Alan Hayward <alan.hayward@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
offset from HOST_WIDE_INT to poly_int64.
* 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,
int hr, conflict_hr, nregs;
machine_mode biggest_mode;
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;
bitmap_iterator bi;
bool *rclass_intersect_p;
......@@ -1147,7 +1148,8 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap
{
int p, i, j, n, regno, hard_regno;
unsigned int k, conflict_regno;
int val, offset;
poly_int64 offset;
int val;
HARD_REG_SET conflict_set;
machine_mode mode;
lra_live_range_t r;
......
......@@ -3084,7 +3084,8 @@ static bool
equiv_address_substitution (struct address_info *ad)
{
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;
base_term = strip_subreg (ad->base_term);
......@@ -3115,6 +3116,7 @@ equiv_address_substitution (struct address_info *ad)
}
if (base_reg != new_base_reg)
{
poly_int64 offset;
if (REG_P (new_base_reg))
{
*base_term = new_base_reg;
......@@ -3122,10 +3124,10 @@ equiv_address_substitution (struct address_info *ad)
}
else if (GET_CODE (new_base_reg) == PLUS
&& 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))
{
disp += INTVAL (XEXP (new_base_reg, 1));
disp += offset;
*base_term = XEXP (new_base_reg, 0);
change_p = true;
}
......@@ -3134,6 +3136,7 @@ equiv_address_substitution (struct address_info *ad)
}
if (index_reg != new_index_reg)
{
poly_int64 offset;
if (REG_P (new_index_reg))
{
*index_term = new_index_reg;
......@@ -3141,16 +3144,16 @@ equiv_address_substitution (struct address_info *ad)
}
else if (GET_CODE (new_index_reg) == PLUS
&& 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)
&& (scale = get_index_scale (ad)))
{
disp += INTVAL (XEXP (new_index_reg, 1)) * scale;
disp += offset * scale;
*index_term = XEXP (new_index_reg, 0);
change_p = true;
}
}
if (disp != 0)
if (maybe_ne (disp, 0))
{
if (ad->disp != NULL)
*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)
register. */
if (plus_p)
{
if (CONST_INT_P (inc))
poly_int64 offset;
if (poly_int_rtx_p (inc, &offset))
emit_insn (gen_add2_insn (result,
gen_int_mode (-INTVAL (inc),
gen_int_mode (-offset,
GET_MODE (result))));
else
emit_insn (gen_sub2_insn (result, inc));
......@@ -4000,10 +4004,13 @@ curr_insn_transform (bool check_only_p)
if (INSN_CODE (curr_insn) >= 0
&& (p = get_insn_name (INSN_CODE (curr_insn))) != NULL)
fprintf (lra_dump_file, " {%s}", p);
if (curr_id->sp_offset != 0)
fprintf (lra_dump_file, " (sp_off=%" HOST_WIDE_INT_PRINT "d)",
curr_id->sp_offset);
fprintf (lra_dump_file, "\n");
if (maybe_ne (curr_id->sp_offset, 0))
{
fprintf (lra_dump_file, " (sp_off=");
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
......
......@@ -106,7 +106,7 @@ struct lra_reg
they do not conflict. */
int val;
/* 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
lra-coalesce.c. */
/* The biggest size mode in which each pseudo reg is referred in
......@@ -213,7 +213,7 @@ struct lra_insn_recog_data
insn. */
int used_insn_alternative;
/* SP offset before the insn relative to one at the func start. */
HOST_WIDE_INT sp_offset;
poly_int64 sp_offset;
/* The insn itself. */
rtx_insn *insn;
/* Common data for insns with the same ICODE. Asm insns (their
......@@ -406,8 +406,8 @@ extern bool lra_remat (void);
extern void lra_debug_elim_table (void);
extern int lra_get_elimination_hard_regno (int);
extern rtx lra_eliminate_regs_1 (rtx_insn *, rtx, machine_mode,
bool, bool, HOST_WIDE_INT, bool);
extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, HOST_WIDE_INT);
bool, bool, poly_int64, bool);
extern void eliminate_regs_in_insn (rtx_insn *insn, bool, bool, poly_int64);
extern void lra_eliminate (bool, bool);
extern void lra_eliminate_reg_if_possible (rtx *);
......@@ -493,7 +493,7 @@ lra_get_insn_recog_data (rtx_insn *insn)
/* Update offset from pseudos with VAL by INCR. */
static inline void
lra_update_reg_val_offset (int val, int incr)
lra_update_reg_val_offset (int val, poly_int64 incr)
{
int i;
......@@ -506,10 +506,10 @@ lra_update_reg_val_offset (int val, int incr)
/* Return true if register content is equal to VAL with OFFSET. */
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
&& lra_reg_info[regno].offset == offset)
&& known_eq (lra_reg_info[regno].offset, offset))
return true;
return false;
......
......@@ -994,7 +994,7 @@ calculate_global_remat_bb_data (void)
/* Setup sp offset attribute to SP_OFFSET for all INSNS. */
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))
eliminate_regs_in_insn (insn, false, false, sp_offset);
......@@ -1118,7 +1118,7 @@ do_remat (void)
int i, hard_regno, nregs;
int dst_hard_regno, dst_nregs;
rtx_insn *remat_insn = NULL;
HOST_WIDE_INT cand_sp_offset = 0;
poly_int64 cand_sp_offset = 0;
if (cand != NULL)
{
lra_insn_recog_data_t cand_id
......@@ -1241,8 +1241,8 @@ do_remat (void)
if (remat_insn != NULL)
{
HOST_WIDE_INT sp_offset_change = cand_sp_offset - id->sp_offset;
if (sp_offset_change != 0)
poly_int64 sp_offset_change = cand_sp_offset - id->sp_offset;
if (maybe_ne (sp_offset_change, 0))
change_sp_offset (remat_insn, sp_offset_change);
update_scratch_ops (remat_insn);
lra_process_new_insns (insn, remat_insn, NULL,
......
......@@ -1188,7 +1188,7 @@ lra_update_insn_recog_data (rtx_insn *insn)
int n;
unsigned int uid = INSN_UID (insn);
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);
if ((data = lra_insn_recog_data[uid]) != NULL
......@@ -1831,8 +1831,8 @@ static void
setup_sp_offset (rtx_insn *from, rtx_insn *last)
{
rtx_insn *before = next_nonnote_nondebug_insn_bb (last);
HOST_WIDE_INT offset = (before == NULL_RTX || ! INSN_P (before)
? 0 : lra_get_insn_recog_data (before)->sp_offset);
poly_int64 offset = (before == NULL_RTX || ! INSN_P (before)
? 0 : lra_get_insn_recog_data (before)->sp_offset);
for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
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