From bc3591eb9fba3f19958f7642c755cf65c137f9a1 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Mon, 29 Oct 2012 00:42:25 +0000 Subject: [PATCH] re PR rtl-optimization/55106 (ice: Maximum number of LRA constraint passes is achieved (15)) 2012-10-28 Vladimir Makarov 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 --- gcc/ChangeLog | 8 +++++ gcc/lra-constraints.c | 77 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e1235d2df0c7..107d6f6f651a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-10-28 Vladimir Makarov + + 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. + 2012-10-29 Jonathan Wakely * doc/cpp.texi (Search Path): Fix outdated C++ path. diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 4b3dbc01ec30..c9a8cd48330a 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));