2014-01-22 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jan 2014 19:38:47 +0000 (19:38 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jan 2014 19:38:47 +0000 (19:38 +0000)
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  <vmakarov@redhat.com>

PR rtl-optimization/59477
* g++.dg/pr59477.C: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206938 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr59477.C [new file with mode: 0644]

index 1012a6d..8e09977 100644 (file)
@@ -1,3 +1,10 @@
+2014-01-22  Vladimir Makarov  <vmakarov@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  Tom Tromey  <tromey@redhat.com>
 
        * config/i386/i386-interix.h (i386_pe_unique_section): Don't use
index dc5e59a..7454229 100644 (file)
@@ -5007,7 +5007,7 @@ static bool
 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;
@@ -5078,6 +5078,7 @@ inherit_in_ebb (rtx head, rtx tail)
          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
@@ -5086,6 +5087,7 @@ inherit_in_ebb (rtx head, rtx tail)
        {
          /* '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)
@@ -5109,6 +5111,7 @@ inherit_in_ebb (rtx head, rtx tail)
                   = 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,
@@ -5297,6 +5300,14 @@ inherit_in_ebb (rtx head, rtx tail)
                      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;
@@ -5307,6 +5318,26 @@ inherit_in_ebb (rtx head, rtx tail)
                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 a00dc8d..6b49a12 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-22  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/59477
+       * g++.dg/pr59477.C: New.
+
 2014-01-22  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gcc.dg/pr44194-1.c: Match "insn " and "insn:", but not "insn/f".
diff --git a/gcc/testsuite/g++.dg/pr59477.C b/gcc/testsuite/g++.dg/pr59477.C
new file mode 100644 (file)
index 0000000..788c751
--- /dev/null
@@ -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));
+}