aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-lives.c
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2017-01-26 17:08:12 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2017-01-26 17:08:12 +0000
commit15961e4a1bbd3ddd2a4ebe09aad07aa6541ed321 (patch)
tree3ba1dafb844c589e276e71d31cb9c17653dce0c5 /gcc/lra-lives.c
parentb63144aa0fce12fb94e3655bc04017e619f1dfa6 (diff)
downloadgcc-15961e4a1bbd3ddd2a4ebe09aad07aa6541ed321.zip
gcc-15961e4a1bbd3ddd2a4ebe09aad07aa6541ed321.tar.gz
gcc-15961e4a1bbd3ddd2a4ebe09aad07aa6541ed321.tar.bz2
re PR target/79131 (ICE: in extract_constrain_insn, at recog.c:2213, big-endian ARM)
2017-01-26 Vladimir Makarov <vmakarov@redhat.com> PR target/79131 * lra-assigns.c (setup_live_pseudos_and_spill_after_risky): Take endianess for subregs into account. * lra-constraints.c (lra_constraints): Do risky transformations always on the first iteration. * lra-lives.c (check_pseudos_live_through_calls): Add arg last_call_used_reg_set. (process_bb_lives): Define and use last_call_used_reg_set. * lra.c (lra): Always continue after lra_constraints on the first iteration. 2017-01-26 Vladimir Makarov <vmakarov@redhat.com> PR target/79131 * gcc.target/arm/pr79131.c: New. From-SVN: r244942
Diffstat (limited to 'gcc/lra-lives.c')
-rw-r--r--gcc/lra-lives.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index 010d4e6..f019438 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -560,10 +560,11 @@ lra_setup_reload_pseudo_preferenced_hard_reg (int regno,
}
/* Check that REGNO living through calls and setjumps, set up conflict
- regs, and clear corresponding bits in PSEUDOS_LIVE_THROUGH_CALLS and
- PSEUDOS_LIVE_THROUGH_SETJUMPS. */
+ regs using LAST_CALL_USED_REG_SET, and clear corresponding bits in
+ PSEUDOS_LIVE_THROUGH_CALLS and PSEUDOS_LIVE_THROUGH_SETJUMPS. */
static inline void
-check_pseudos_live_through_calls (int regno)
+check_pseudos_live_through_calls (int regno,
+ HARD_REG_SET last_call_used_reg_set)
{
int hr;
@@ -571,7 +572,7 @@ check_pseudos_live_through_calls (int regno)
return;
sparseset_clear_bit (pseudos_live_through_calls, regno);
IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs,
- call_used_reg_set);
+ last_call_used_reg_set);
for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++)
if (HARD_REGNO_CALL_PART_CLOBBERED (hr, PSEUDO_REGNO_MODE (regno)))
@@ -604,11 +605,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
rtx_insn *next;
rtx link, *link_loc;
bool need_curr_point_incr;
-
+ HARD_REG_SET last_call_used_reg_set;
+
reg_live_out = df_get_live_out (bb);
sparseset_clear (pseudos_live);
sparseset_clear (pseudos_live_through_calls);
sparseset_clear (pseudos_live_through_setjumps);
+ CLEAR_HARD_REG_SET (last_call_used_reg_set);
REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out);
AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset);
EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
@@ -795,7 +798,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
need_curr_point_incr
|= mark_regno_live (reg->regno, reg->biggest_mode,
curr_point);
- check_pseudos_live_through_calls (reg->regno);
+ check_pseudos_live_through_calls (reg->regno,
+ last_call_used_reg_set);
}
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
@@ -831,15 +835,27 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
if (call_p)
{
- if (flag_ipa_ra)
+ if (! flag_ipa_ra)
+ COPY_HARD_REG_SET(last_call_used_reg_set, call_used_reg_set);
+ else
{
HARD_REG_SET this_call_used_reg_set;
get_call_reg_set_usage (curr_insn, &this_call_used_reg_set,
call_used_reg_set);
+ bool flush = (! hard_reg_set_empty_p (last_call_used_reg_set)
+ && ! hard_reg_set_equal_p (last_call_used_reg_set,
+ this_call_used_reg_set));
+
EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
- IOR_HARD_REG_SET (lra_reg_info[j].actual_call_used_reg_set,
- this_call_used_reg_set);
+ {
+ IOR_HARD_REG_SET (lra_reg_info[j].actual_call_used_reg_set,
+ this_call_used_reg_set);
+ if (flush)
+ check_pseudos_live_through_calls
+ (j, last_call_used_reg_set);
+ }
+ COPY_HARD_REG_SET(last_call_used_reg_set, this_call_used_reg_set);
}
sparseset_ior (pseudos_live_through_calls,
@@ -866,7 +882,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
need_curr_point_incr
|= mark_regno_live (reg->regno, reg->biggest_mode,
curr_point);
- check_pseudos_live_through_calls (reg->regno);
+ check_pseudos_live_through_calls (reg->regno,
+ last_call_used_reg_set);
}
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
@@ -1009,7 +1026,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
if (sparseset_cardinality (pseudos_live_through_calls) == 0)
break;
if (sparseset_bit_p (pseudos_live_through_calls, j))
- check_pseudos_live_through_calls (j);
+ check_pseudos_live_through_calls (j, last_call_used_reg_set);
}
if (need_curr_point_incr)