]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/64317 (Ineffective allocation of PIC base register)
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 23 Jan 2015 20:15:56 +0000 (20:15 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 23 Jan 2015 20:15:56 +0000 (20:15 +0000)
2015-01-23  Vladimir Makarov  <vmakarov@redhat.com>

PR target/64317
* lra-lives.c (make_hard_regno_born): Add parameter.  Don't make
REAL_PIC_OFFSET_TABLE_REGNUM conflicting with pic offset pseudo.
(mark_regno_live, process_bb_lives): Pass new paramater value to
make_hard_regno_born.

2015-01-23  Vladimir Makarov  <vmakarov@redhat.com>

PR target/64317
* gcc.target/i386/pr64317.c: New test.

From-SVN: r220060

gcc/ChangeLog
gcc/lra-lives.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr64317.c [new file with mode: 0644]

index 34e8ad1e6512a551edf3d47548b9db549931d39e..57d08a886bf5c3740f27293bd0320d09c86affa8 100644 (file)
@@ -1,3 +1,11 @@
+2015-01-23  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/64317
+       * lra-lives.c (make_hard_regno_born): Add parameter.  Don't make
+       REAL_PIC_OFFSET_TABLE_REGNUM conflicting with pic offset pseudo.
+       (mark_regno_live, process_bb_lives): Pass new paramater value to
+       make_hard_regno_born.
+
 2015-01-23  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/63637
index 50d3969ea3bde8f70754b1c3159582e0cd342417..9dfffb6f28788b22df01b9922faa8463065bee04 100644 (file)
@@ -264,10 +264,12 @@ lra_intersected_live_ranges_p (lra_live_range_t r1, lra_live_range_t r2)
 }
 
 /* The function processing birth of hard register REGNO.  It updates
-   living hard regs, conflict hard regs for living pseudos, and
-   START_LIVING.  */
+   living hard regs, START_LIVING, and conflict hard regs for living
+   pseudos.  Conflict hard regs for the pic pseudo is not updated if
+   REGNO is REAL_PIC_OFFSET_TABLE_REGNUM and CHECK_PIC_PSEUDO_P is
+   true.  */
 static void
-make_hard_regno_born (int regno)
+make_hard_regno_born (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED)
 {
   unsigned int i;
 
@@ -277,7 +279,13 @@ make_hard_regno_born (int regno)
   SET_HARD_REG_BIT (hard_regs_live, regno);
   sparseset_set_bit (start_living, regno);
   EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i)
-    SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno);
+#ifdef REAL_PIC_OFFSET_TABLE_REGNUM
+    if (! check_pic_pseudo_p
+       || regno != REAL_PIC_OFFSET_TABLE_REGNUM
+       || pic_offset_table_rtx == NULL
+       || i != REGNO (pic_offset_table_rtx))
+#endif
+      SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno);
 }
 
 /* Process the death of hard register REGNO.  This updates
@@ -352,7 +360,7 @@ mark_regno_live (int regno, machine_mode mode, int point)
       for (last = regno + hard_regno_nregs[regno][mode];
           regno < last;
           regno++)
-       make_hard_regno_born (regno);
+       make_hard_regno_born (regno, false);
     }
   else
     {
@@ -833,7 +841,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
        if (reg->type != OP_IN)
-         make_hard_regno_born (reg->regno);
+         make_hard_regno_born (reg->regno, false);
 
       sparseset_copy (unused_set, start_living);
 
@@ -892,12 +900,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
        if (reg->type == OP_IN)
-         make_hard_regno_born (reg->regno);
+         make_hard_regno_born (reg->regno, false);
 
       if (curr_id->arg_hard_regs != NULL)
-       /* Make argument hard registers live.  */
+       /* Make argument hard registers live.  Don't create conflict
+          of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo.  */
        for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
-         make_hard_regno_born (regno);
+         make_hard_regno_born (regno, true);
 
       sparseset_and_compl (dead_set, start_living, start_dying);
 
@@ -953,7 +962,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 
        if (regno == INVALID_REGNUM)
          break;
-       make_hard_regno_born (regno);
+       make_hard_regno_born (regno, false);
       }
 #endif
 
@@ -968,7 +977,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
       EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, px)
        lra_reg_info[px].no_stack_p = true;
       for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++)
-       make_hard_regno_born (px);
+       make_hard_regno_born (px, false);
 #endif
       /* No need to record conflicts for call clobbered regs if we
         have nonlocal labels around, as we don't ever try to
@@ -976,7 +985,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
       if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb))
        for (px = 0; px < FIRST_PSEUDO_REGISTER; px++)
          if (call_used_regs[px])
-           make_hard_regno_born (px);
+           make_hard_regno_born (px, false);
     }
 
   bool live_change_p = false;
index 39a1741f745b0cf74a04c22e1813e90cfd4e2c78..ef497e476357153f81324818dbb251020b83159d 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-23  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/64317
+       * gcc.target/i386/pr64317.c: New test.
+
 2015-01-23  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/63637
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
new file mode 100644 (file)
index 0000000..46c3c6f
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O2 -fPIE -pie" } */
+/* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
+long c;
+
+int bar();
+
+int foo (unsigned int iters)
+{
+  unsigned int i;
+  
+  int res = 0;
+  static long t1;
+  
+  for (i = 0; i < iters; i++)
+    {
+      res = bar();
+      t1 = c + res;
+    }
+  
+  return t1 + res;
+}