PR target/46685
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Dec 2010 22:33:16 +0000 (22:33 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Dec 2010 22:33:16 +0000 (22:33 +0000)
* config/sparc/sparc.c (can_use_mov_pic_label_ref): New predicate.
(sparc_expand_move): Call it to decide whether to emit the special
mov{si,di}_pic_label_ref patterns.
(sparc_legitimize_pic_address): Call it to decide whether to emit
the regular PIC sequence for labels.  Fix long line.
(sparc_file_end): Set is_thunk for the PIC helper.

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

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr46685.c [new file with mode: 0644]

index 5bcef5d..fe73581 100644 (file)
@@ -1,3 +1,13 @@
+2010-11-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/46685
+       * config/sparc/sparc.c (can_use_mov_pic_label_ref): New predicate.
+       (sparc_expand_move): Call it to decide whether to emit the special
+       mov{si,di}_pic_label_ref patterns.
+       (sparc_legitimize_pic_address): Call it to decide whether to emit
+       the regular PIC sequence for labels.  Fix long line.
+       (sparc_file_end): Set is_thunk for the PIC helper.
+
 2010-12-02  Eric Botcazou  <ebotcazou@adacore.com>
 
        * tree.c (build_range_type_1): Do not SET_TYPE_STRUCTURAL_EQUALITY
 2010-11-02  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/46149
-       * tree-ssa-structalias.c (get_constraint_for_1): Properly handle
+       * tree-ssa-structalias.c (get_constraint_fop_1): Properly handle
        non-indirect MEM_REF variants.
 
 2010-11-02  Richard Guenther  <rguenther@suse.de>
index 85387cc..223408d 100644 (file)
@@ -1025,6 +1025,36 @@ fp_high_losum_p (rtx op)
   return 0;
 }
 
+/* Return true if the address of LABEL can be loaded by means of the
+   mov{si,di}_pic_label_ref patterns in PIC mode.  */
+
+static bool
+can_use_mov_pic_label_ref (rtx label)
+{
+  /* VxWorks does not impose a fixed gap between segments; the run-time
+     gap can be different from the object-file gap.  We therefore can't
+     assume X - _GLOBAL_OFFSET_TABLE_ is a link-time constant unless we
+     are absolutely sure that X is in the same segment as the GOT.
+     Unfortunately, the flexibility of linker scripts means that we
+     can't be sure of that in general, so assume that GOT-relative
+     accesses are never valid on VxWorks.  */
+  if (TARGET_VXWORKS_RTP)
+    return false;
+
+  /* Similarly, if the label is non-local, it might end up being placed
+     in a different section than the current one; now mov_pic_label_ref
+     requires the label and the code to be in the same section.  */
+  if (LABEL_REF_NONLOCAL_P (label))
+    return false;
+
+  /* Finally, if we are reordering basic blocks and partition into hot
+     and cold sections, this might happen for any label.  */
+  if (flag_reorder_blocks_and_partition)
+    return false;
+
+  return true;
+}
+
 /* Expand a move instruction.  Return true if all work is done.  */
 
 bool
@@ -1059,14 +1089,9 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
       if (pic_address_needs_scratch (operands[1]))
        operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX);
 
-      /* VxWorks does not impose a fixed gap between segments; the run-time
-        gap can be different from the object-file gap.  We therefore can't
-        assume X - _GLOBAL_OFFSET_TABLE_ is a link-time constant unless we
-        are absolutely sure that X is in the same segment as the GOT.
-        Unfortunately, the flexibility of linker scripts means that we
-        can't be sure of that in general, so assume that _G_O_T_-relative
-        accesses are never valid on VxWorks.  */
-      if (GET_CODE (operands[1]) == LABEL_REF && !TARGET_VXWORKS_RTP)
+      /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases.  */
+      if (GET_CODE (operands[1]) == LABEL_REF
+         && can_use_mov_pic_label_ref (operands[1]))
        {
          if (mode == SImode)
            {
@@ -3425,7 +3450,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
 
   if (GET_CODE (orig) == SYMBOL_REF
       /* See the comment in sparc_expand_move.  */
-      || (TARGET_VXWORKS_RTP && GET_CODE (orig) == LABEL_REF))
+      || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig)))
     {
       rtx pic_ref, address;
       rtx insn;
@@ -3478,11 +3503,13 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
        }
       else
        {
-         pic_ref = gen_const_mem (Pmode,
-                                  gen_rtx_PLUS (Pmode,
-                                                pic_offset_table_rtx, address));
+         pic_ref
+           = gen_const_mem (Pmode,
+                            gen_rtx_PLUS (Pmode,
+                                          pic_offset_table_rtx, address));
          insn = emit_move_insn (reg, pic_ref);
        }
+
       /* Put a REG_EQUAL note on this insn, so that it can be optimized
         by loop.  */
       set_unique_reg_note (insn, REG_EQUAL, orig);
@@ -3520,9 +3547,8 @@ sparc_legitimize_pic_address (rtx orig, rtx reg)
       return gen_rtx_PLUS (Pmode, base, offset);
     }
   else if (GET_CODE (orig) == LABEL_REF)
-    /* ??? Why do we do this?  */
-    /* Now movsi_pic_label_ref uses it, but we ought to be checking that
-       the register is live instead, in case it is eliminated.  */
+    /* ??? We ought to be checking that the register is live instead, in case
+       it is eliminated.  */
     crtl->uses_pic_offset_table = 1;
 
   return orig;
@@ -9453,6 +9479,7 @@ sparc_file_end (void)
          DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
          DECL_VISIBILITY_SPECIFIED (decl) = 1;
          allocate_struct_function (decl, true);
+         cfun->is_thunk = 1;
          current_function_decl = decl;
          init_varasm_status ();
          assemble_start_function (decl, name);
index 3eeee83..71faa57 100644 (file)
@@ -1,3 +1,7 @@
+2010-11-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.dg/pr46685.c: New test.
+
 2010-12-02  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR tree-optimization/45199
diff --git a/gcc/testsuite/gcc.dg/pr46685.c b/gcc/testsuite/gcc.dg/pr46685.c
new file mode 100644 (file)
index 0000000..6277bcc
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target freorder } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -freorder-blocks-and-partition -fpic" } */
+
+__attribute__((noinline, noclone))
+void bar (void *x)
+{
+  asm volatile ("" : : "r" (x) : "memory");
+}
+
+__attribute__((noinline, noclone))
+void baz (void)
+{
+  asm volatile ("" : : : "memory");
+}
+
+__attribute__((noinline, noclone))
+int foo (int x)
+{
+  __label__ lab;
+  if (__builtin_expect (x, 0))
+    {
+      lab:
+      baz ();
+      return 2;
+    }
+  bar (&&lab);
+  return 1;
+}
+
+int
+main (void)
+{
+  int x, i;
+  asm volatile ("" : "=r" (x) : "0" (0));
+  for (i = 0; i < 1000000; i++)
+    foo (x);
+  return 0;
+}