summaryrefslogtreecommitdiff
path: root/gcc/lra-spills.c
diff options
context:
space:
mode:
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2016-08-03 18:54:49 +0000
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2016-08-03 18:54:49 +0000
commitc2a19a33ff6de1e64d32e0cc86f36c8ca5c00a56 (patch)
treec046941efb74a2e8a43bf0d4c9f9df8640b69577 /gcc/lra-spills.c
parentf5f4272ebadde9c9f232751212d2f8df7632ae86 (diff)
downloadgcc-c2a19a33ff6de1e64d32e0cc86f36c8ca5c00a56.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239091 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lra-spills.c')
-rw-r--r--gcc/lra-spills.c32
1 files changed, 28 insertions, 4 deletions
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;
}