aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-constraints.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r--gcc/lra-constraints.c80
1 files changed, 59 insertions, 21 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index ae55c86..118b65f 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -5458,7 +5458,8 @@ lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno)
/* Do split transformations for insn INSN, which defines or uses
ORIGINAL_REGNO. NEXT_USAGE_INSNS specifies which instruction in
the EBB next uses ORIGINAL_REGNO; it has the same form as the
- "insns" field of usage_insns.
+ "insns" field of usage_insns. If TO is not NULL, we don't use
+ usage_insns, we put restore insns after TO insn.
The transformations look like:
@@ -5480,7 +5481,7 @@ lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno)
transformation. */
static bool
split_reg (bool before_p, int original_regno, rtx_insn *insn,
- rtx next_usage_insns)
+ rtx next_usage_insns, rtx_insn *to)
{
enum reg_class rclass;
rtx original_reg;
@@ -5613,29 +5614,37 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
if (!HARD_REGISTER_NUM_P (original_regno)
&& mode == PSEUDO_REGNO_MODE (original_regno))
lra_copy_reg_equiv (new_regno, original_regno);
- after_p = usage_insns[original_regno].after_p;
lra_reg_info[new_regno].restore_rtx = regno_reg_rtx[original_regno];
bitmap_set_bit (&check_only_regs, new_regno);
bitmap_set_bit (&check_only_regs, original_regno);
bitmap_set_bit (&lra_split_regs, new_regno);
- for (;;)
+ if (to != NULL)
{
- if (GET_CODE (next_usage_insns) != INSN_LIST)
- {
- usage_insn = next_usage_insns;
- break;
- }
- usage_insn = XEXP (next_usage_insns, 0);
- lra_assert (DEBUG_INSN_P (usage_insn));
- next_usage_insns = XEXP (next_usage_insns, 1);
- lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false,
- true);
- lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
- if (lra_dump_file != NULL)
+ usage_insn = to;
+ after_p = TRUE;
+ }
+ else
+ {
+ after_p = usage_insns[original_regno].after_p;
+ for (;;)
{
- fprintf (lra_dump_file, " Split reuse change %d->%d:\n",
- original_regno, new_regno);
- dump_insn_slim (lra_dump_file, as_a <rtx_insn *> (usage_insn));
+ if (GET_CODE (next_usage_insns) != INSN_LIST)
+ {
+ usage_insn = next_usage_insns;
+ break;
+ }
+ usage_insn = XEXP (next_usage_insns, 0);
+ lra_assert (DEBUG_INSN_P (usage_insn));
+ next_usage_insns = XEXP (next_usage_insns, 1);
+ lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false,
+ true);
+ lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
+ if (lra_dump_file != NULL)
+ {
+ fprintf (lra_dump_file, " Split reuse change %d->%d:\n",
+ original_regno, new_regno);
+ dump_insn_slim (lra_dump_file, as_a <rtx_insn *> (usage_insn));
+ }
}
}
lra_assert (NOTE_P (usage_insn) || NONDEBUG_INSN_P (usage_insn));
@@ -5662,6 +5671,35 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
return true;
}
+/* Split a hard reg for reload pseudo REGNO having RCLASS and living
+ in the range [FROM, TO]. Return true if did a split. Otherwise,
+ return false. */
+bool
+spill_hard_reg_in_range (int regno, enum reg_class rclass, rtx_insn *from, rtx_insn *to)
+{
+ int i, hard_regno;
+ int rclass_size;
+ rtx_insn *insn;
+
+ lra_assert (from != NULL && to != NULL);
+ rclass_size = ira_class_hard_regs_num[rclass];
+ for (i = 0; i < rclass_size; i++)
+ {
+ hard_regno = ira_class_hard_regs[rclass][i];
+ if (! TEST_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hard_regno))
+ continue;
+ for (insn = from; insn != NEXT_INSN (to); insn = NEXT_INSN (insn))
+ if (bitmap_bit_p (&lra_reg_info[hard_regno].insn_bitmap,
+ INSN_UID (insn)))
+ break;
+ if (insn != NEXT_INSN (to))
+ continue;
+ if (split_reg (TRUE, hard_regno, from, NULL, to))
+ return true;
+ }
+ return false;
+}
+
/* Recognize that we need a split transformation for insn INSN, which
defines or uses REGNO in its insn biggest MODE (we use it only if
REGNO is a hard register). POTENTIAL_RELOAD_HARD_REGS contains
@@ -5689,7 +5727,7 @@ split_if_necessary (int regno, machine_mode mode,
|| (GET_CODE (next_usage_insns) == INSN_LIST
&& (INSN_UID (XEXP (next_usage_insns, 0)) < max_uid)))
&& need_for_split_p (potential_reload_hard_regs, regno + i)
- && split_reg (before_p, regno + i, insn, next_usage_insns))
+ && split_reg (before_p, regno + i, insn, next_usage_insns, NULL))
res = true;
return res;
}
@@ -6467,7 +6505,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
head_p = false;
}
if (split_reg (false, j, bb_note (curr_bb),
- next_usage_insns))
+ next_usage_insns, NULL))
change_p = true;
}
usage_insns[j].check = 0;