On 1/22/2014, 2:41 PM, Jakub Jelinek wrote:
On Wed, Jan 22, 2014 at 02:40:46PM -0500, Vladimir Makarov wrote:
The following patch fixes
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59477
The patch was successfully bootstrapped and tested on x86/x86-64.
Committed as rev. 206938.
2014-01-22 Vladimir Makarov <vmaka...@redhat.com>
PR rtl-optimization/59477
* lra-constraints.c (inherit_in_ebb): Process call for living hard
regs. Update reloads_num and potential_reload_hard_regs for all
insns.
2014-01-22 Vladimir Makarov <vmaka...@redhat.com>
PR rtl-optimization/59477
* g++.dg/pr59477.C: New.
ENOPATCH ;)
Jakub
Ops, sorry. The patch is in the attachment.
Index: lra-constraints.c
===================================================================
--- lra-constraints.c (revision 206686)
+++ lra-constraints.c (working copy)
@@ -4992,7 +4992,7 @@
inherit_in_ebb (rtx head, rtx tail)
{
int i, src_regno, dst_regno, nregs;
- bool change_p, succ_p;
+ bool change_p, succ_p, update_reloads_num_p;
rtx prev_insn, next_usage_insns, set, last_insn;
enum reg_class cl;
struct lra_insn_reg *reg;
@@ -5063,6 +5063,7 @@
src_regno = REGNO (SET_SRC (set));
dst_regno = REGNO (SET_DEST (set));
}
+ update_reloads_num_p = true;
if (src_regno < lra_constraint_new_regno_start
&& src_regno >= FIRST_PSEUDO_REGISTER
&& reg_renumber[src_regno] < 0
@@ -5071,6 +5072,7 @@
{
/* 'reload_pseudo <- original_pseudo'. */
reloads_num++;
+ update_reloads_num_p = false;
succ_p = false;
if (usage_insns[src_regno].check == curr_usage_insns_check
&& (next_usage_insns = usage_insns[src_regno].insns) != NULL_RTX)
@@ -5094,6 +5096,7 @@
= usage_insns[dst_regno].insns) != NULL_RTX)
{
reloads_num++;
+ update_reloads_num_p = false;
/* 'original_pseudo <- reload_pseudo'. */
if (! JUMP_P (curr_insn)
&& inherit_reload_reg (true, dst_regno, cl,
@@ -5282,6 +5285,14 @@
add_next_usage_insn (src_regno, use_insn, reloads_num);
}
}
+ /* Process call args. */
+ if (curr_id->arg_hard_regs != NULL)
+ for (i = 0; (src_regno = curr_id->arg_hard_regs[i]) >= 0; i++)
+ if (src_regno < FIRST_PSEUDO_REGISTER)
+ {
+ SET_HARD_REG_BIT (live_hard_regs, src_regno);
+ add_next_usage_insn (src_regno, curr_insn, reloads_num);
+ }
for (i = 0; i < to_inherit_num; i++)
{
src_regno = to_inherit[i].regno;
@@ -5292,6 +5303,26 @@
setup_next_usage_insn (src_regno, curr_insn, reloads_num,
false);
}
}
+ if (update_reloads_num_p
+ && NONDEBUG_INSN_P (curr_insn)
+ && (set = single_set (curr_insn)) != NULL_RTX)
+ {
+ int regno = -1;
+ if ((REG_P (SET_DEST (set))
+ && (regno = REGNO (SET_DEST (set))) >=
lra_constraint_new_regno_start
+ && reg_renumber[regno] < 0
+ && (cl = lra_get_allocno_class (regno)) != NO_REGS)
+ || (REG_P (SET_SRC (set))
+ && (regno = REGNO (SET_SRC (set))) >=
lra_constraint_new_regno_start
+ && reg_renumber[regno] < 0
+ && (cl = lra_get_allocno_class (regno)) != NO_REGS))
+ {
+ reloads_num++;
+ if (hard_reg_set_subset_p (reg_class_contents[cl],
live_hard_regs))
+ IOR_HARD_REG_SET (potential_reload_hard_regs,
+ reg_class_contents[cl]);
+ }
+ }
/* We reached the start of the current basic block. */
if (prev_insn == NULL_RTX || prev_insn == PREV_INSN (head)
|| BLOCK_FOR_INSN (prev_insn) != curr_bb)
Index: testsuite/g++.dg/pr59477.C
===================================================================
--- testsuite/g++.dg/pr59477.C (revision 0)
+++ testsuite/g++.dg/pr59477.C (working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A
+{
+ unsigned *a, b;
+ A (unsigned x) : a (), b (x) {}
+};
+
+struct B
+{
+ B (int);
+ B (const B &) {}
+};
+
+B bar (B, B, A);
+int v;
+
+void
+foo ()
+{
+ B c = 0;
+ bar (c, c, A (1ULL << v));
+}