From 73c77563c6409ad46357e083f378716defd9b1a7 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Wed, 3 Aug 2016 18:54:49 +0000 Subject: [PATCH] re PR rtl-optimization/72778 (internal compiler error: in create_pre_exit, at mode-switching.c:451) 2016-08-03 Vladimir Makarov 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 --- gcc/ChangeLog | 6 ++++++ gcc/lra-spills.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2223290bd53..8dcd430a6c7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-08-03 Vladimir Makarov + + 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 * config/nvptx/nvptx.c (nvptx_declare_function_name): Round frame diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index a5073b69f46..d7529ea371f 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; } -- 2.30.2