aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2016-08-03 18:54:49 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2016-08-03 18:54:49 +0000
commit73c77563c6409ad46357e083f378716defd9b1a7 (patch)
treec046941efb74a2e8a43bf0d4c9f9df8640b69577
parent32eaac9c919b4b907d685370ef23aacc1e94f18b (diff)
downloadgcc-73c77563c6409ad46357e083f378716defd9b1a7.zip
gcc-73c77563c6409ad46357e083f378716defd9b1a7.tar.gz
gcc-73c77563c6409ad46357e083f378716defd9b1a7.tar.bz2
re PR rtl-optimization/72778 (internal compiler error: in create_pre_exit, at mode-switching.c:451)
2016-08-03 Vladimir Makarov <vmakarov@redhat.com> PR middle-end/72778 * lra-spills.c (regno_in_use_p): Check bb and regno modification. Don't stop on regular insns. From-SVN: r239091
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-spills.c32
2 files changed, 34 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2223290..8dcd430 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-08-03 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR middle-end/72778
+ * lra-spills.c (regno_in_use_p): Check bb and regno modification.
+ Don't stop on regular insns.
+
2016-08-03 Nathan Sidwell <nathan@codesourcery.com>
* config/nvptx/nvptx.c (nvptx_declare_function_name): Round frame
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index a5073b6..d7529ea 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -686,16 +686,40 @@ return_regno_p (unsigned int regno)
return false;
}
-/* Return true if REGNO is one of subsequent USE after INSN. */
+/* Return true if REGNO is in one of subsequent USE after INSN in the
+ same BB. */
static bool
regno_in_use_p (rtx_insn *insn, unsigned int regno)
{
+ static lra_insn_recog_data_t id;
+ static struct lra_static_insn_data *static_id;
+ struct lra_insn_reg *reg;
+ int i, arg_regno;
+ basic_block bb = BLOCK_FOR_INSN (insn);
+
while ((insn = next_nondebug_insn (insn)) != NULL_RTX
- && INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE)
+ && bb == BLOCK_FOR_INSN (insn))
{
- if (REG_P (XEXP (PATTERN (insn), 0))
+ if (! INSN_P (insn))
+ continue;
+ if (GET_CODE (PATTERN (insn)) == USE
+ && REG_P (XEXP (PATTERN (insn), 0))
&& regno == REGNO (XEXP (PATTERN (insn), 0)))
- return TRUE;
+ return true;
+ /* Check that the regno is not modified. */
+ id = lra_get_insn_recog_data (insn);
+ for (reg = id->regs; reg != NULL; reg = reg->next)
+ if (reg->type != OP_IN && reg->regno == (int) regno)
+ return false;
+ static_id = id->insn_static_data;
+ for (reg = static_id->hard_regs; reg != NULL; reg = reg->next)
+ if (reg->type != OP_IN && reg->regno == (int) regno)
+ return false;
+ if (id->arg_hard_regs != NULL)
+ for (i = 0; (arg_regno = id->arg_hard_regs[i]) >= 0; i++)
+ if ((int) regno == (arg_regno >= FIRST_PSEUDO_REGISTER
+ ? arg_regno : arg_regno - FIRST_PSEUDO_REGISTER))
+ return false;
}
return false;
}