summaryrefslogtreecommitdiff
path: root/gcc/lra-constraints.c
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2012-10-29 00:42:25 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2012-10-29 00:42:25 +0000
commitbc3591eb9fba3f19958f7642c755cf65c137f9a1 (patch)
treec6b2a86fbc84697b54efacbfc605b86e954cc7b1 /gcc/lra-constraints.c
parent4c358abe604e175a8f9897f3ae44a9fd72725089 (diff)
downloadgcc-bc3591eb9fba3f19958f7642c755cf65c137f9a1.tar.gz
re PR rtl-optimization/55106 (ice: Maximum number of LRA constraint passes is achieved (15))
2012-10-28 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/55106 * lra-constraints.c (skip_usage_debug_insns): New function. (check_secondary_memory_needed_p): Ditto. (inherit_reload_reg): Use the new functions. Improve debug output. From-SVN: r192904
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r--gcc/lra-constraints.c77
1 files changed, 72 insertions, 5 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 4b3dbc01ec3..c9a8cd48330 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -3573,6 +3573,48 @@ substitute_pseudo (rtx *loc, int old_regno, rtx new_reg)
return result;
}
+/* Return first non-debug insn in list USAGE_INSNS. */
+static rtx
+skip_usage_debug_insns (rtx usage_insns)
+{
+ rtx insn;
+
+ /* Skip debug insns. */
+ for (insn = usage_insns;
+ insn != NULL_RTX && GET_CODE (insn) == INSN_LIST;
+ insn = XEXP (insn, 1))
+ ;
+ return insn;
+}
+
+/* Return true if we need secondary memory moves for insn in
+ USAGE_INSNS after inserting inherited pseudo of class INHER_CL
+ into the insn. */
+static bool
+check_secondary_memory_needed_p (enum reg_class inher_cl, rtx usage_insns)
+{
+#ifndef SECONDARY_MEMORY_NEEDED
+ return false;
+#else
+ rtx insn, set, dest;
+ enum reg_class cl;
+
+ if (inher_cl == ALL_REGS
+ || (insn = skip_usage_debug_insns (usage_insns)) == NULL_RTX)
+ return false;
+ lra_assert (INSN_P (insn));
+ if ((set = single_set (insn)) == NULL_RTX || ! REG_P (SET_DEST (set)))
+ return false;
+ dest = SET_DEST (set);
+ if (! REG_P (dest))
+ return false;
+ lra_assert (inher_cl != NO_REGS);
+ cl = get_reg_class (REGNO (dest));
+ return (cl != NO_REGS && cl != ALL_REGS
+ && SECONDARY_MEMORY_NEEDED (inher_cl, cl, GET_MODE (dest)));
+#endif
+}
+
/* Registers involved in inheritance/split in the current EBB
(inheritance/split pseudos and original registers). */
static bitmap_head check_only_regs;
@@ -3610,18 +3652,18 @@ inherit_reload_reg (bool def_p, int original_regno,
lra_assert (! usage_insns[original_regno].after_p);
if (lra_dump_file != NULL)
fprintf (lra_dump_file,
- " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
if (! ira_reg_classes_intersect_p[cl][rclass])
{
if (lra_dump_file != NULL)
{
fprintf (lra_dump_file,
- " Rejecting inheritance for %d "
+ " Rejecting inheritance for %d "
"because of disjoint classes %s and %s\n",
original_regno, reg_class_names[cl],
reg_class_names[rclass]);
fprintf (lra_dump_file,
- " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
}
return false;
}
@@ -3638,6 +3680,31 @@ inherit_reload_reg (bool def_p, int original_regno,
rclass = cl;
}
+ if (check_secondary_memory_needed_p (cl, next_usage_insns))
+ {
+ /* Reject inheritance resulting in secondary memory moves.
+ Otherwise, there is a danger in LRA cycling. Also such
+ transformation will be unprofitable. */
+ if (lra_dump_file != NULL)
+ {
+ rtx insn = skip_usage_debug_insns (next_usage_insns);
+ rtx set = single_set (insn);
+
+ lra_assert (set != NULL_RTX);
+
+ rtx dest = SET_DEST (set);
+
+ lra_assert (REG_P (dest));
+ fprintf (lra_dump_file,
+ " Rejecting inheritance for insn %d(%s)<-%d(%s) "
+ "as secondary mem is needed\n",
+ REGNO (dest), reg_class_names[get_reg_class (REGNO (dest))],
+ original_regno, reg_class_names[cl]);
+ fprintf (lra_dump_file,
+ " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ }
+ return false;
+ }
new_reg = lra_create_new_reg (GET_MODE (original_reg), original_reg,
rclass, "inheritance");
start_sequence ();
@@ -3652,7 +3719,7 @@ inherit_reload_reg (bool def_p, int original_regno,
if (lra_dump_file != NULL)
{
fprintf (lra_dump_file,
- " Rejecting inheritance %d->%d "
+ " Rejecting inheritance %d->%d "
"as it results in 2 or more insns:\n",
original_regno, REGNO (new_reg));
debug_rtl_slim (lra_dump_file, new_insns, NULL_RTX, -1, 0);
@@ -3667,7 +3734,7 @@ inherit_reload_reg (bool def_p, int original_regno,
/* We now have a new usage insn for original regno. */
setup_next_usage_insn (original_regno, new_insns, reloads_num, false);
if (lra_dump_file != NULL)
- fprintf (lra_dump_file, " Original reg change %d->%d (bb%d):\n",
+ fprintf (lra_dump_file, " Original reg change %d->%d (bb%d):\n",
original_regno, REGNO (new_reg), BLOCK_FOR_INSN (insn)->index);
lra_reg_info[REGNO (new_reg)].restore_regno = original_regno;
bitmap_set_bit (&check_only_regs, REGNO (new_reg));