Hi,

When assign_hard_reg, we always check_hard_reg_p, which has code

if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
  return false;

i.e. If a hard_regno is not in profitable_regs, we can not allocate it to
the ira_allocno_t A.

So the conflict on a hard_regno, which does not belong to the
profitable_regs, can be ignored. Please refer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63210 for the detail of the
test case.

Bootstrap and no make check regression on X86-64 and ARM Chromebook.
NO spec2k performance regression on X86-64 and ARM Chromebook.
CSiBE code size is 0.01% better for ARM Cortex-M0.

OK for trunk?
Thanks!
-Zhenqiang

ChangeLog:
2014-09-17  Zhenqiang Chen  <zhenqiang.c...@arm.com>

        PR rtl-optimization/63210
        * ira-color.c (assign_hard_reg): Ignore conflict cost if the
        HARD_REGNO is not availabe for CONFLICT_A.

testsuite/ChangeLog:
2014-09-17  Zhenqiang Chen  <zhenqiang.c...@arm.com>

        * gcc.target/arm/pr63210.c: New test.

diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index e2ea359..e3fea54 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -1709,6 +1709,7 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
         {
          ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
          enum reg_class conflict_aclass;
+         allocno_color_data_t data = ALLOCNO_COLOR_DATA (conflict_a);
 
          /* Reload can give another class so we need to check all
             allocnos.  */
@@ -1780,7 +1781,12 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
                    hard_regno = ira_class_hard_regs[aclass][j];
                    ira_assert (hard_regno >= 0);
                    k =
ira_class_hard_reg_index[conflict_aclass][hard_regno];
-                   if (k < 0)
+                   if (k < 0
+                          /* If HARD_REGNO is not available for CONFLICT_A,
+                             the conflict would be ignored, since
HARD_REGNO
+                             will never be assigned to CONFLICT_A.  */
+                       || !TEST_HARD_REG_BIT (data->profitable_hard_regs,
+                                              hard_regno))
                      continue;
                    full_costs[j] -= conflict_costs[k];
                  }
diff --git a/gcc/testsuite/gcc.target/arm/pr63210.c
b/gcc/testsuite/gcc.target/arm/pr63210.c
new file mode 100644
index 0000000..c3ae928
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr63210.c
@@ -0,0 +1,12 @@
+/* { dg-do assemble } */
+/* { dg-options "-mthumb -Os " }  */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+int foo1 (int c);
+int foo2 (int c);
+
+int test (int c)
+{
+  return (foo1 (c) || foo2 (c));
+}
+/* { dg-final { object-size text <= 28 } } */



Reply via email to