]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/47038 (failure of gcc.dg/pr46685.c)
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 3 Jan 2011 12:06:19 +0000 (12:06 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 3 Jan 2011 12:06:19 +0000 (12:06 +0000)
Backport from mainline
2010-12-30  Eric Botcazou  <ebotcazou@adacore.com>

PR target/47038
* config/sparc/sparc.c (sparc_file_end): Call resolve_unique_section
on the GOT helper if USE_HIDDEN_LINKONCE.

2010-12-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.

From-SVN: r168418

gcc/ChangeLog
gcc/config/sparc/sparc.c

index de26b22228ed39f6bfca37118e754590fe3f3a4c..f03cfee9a088682855ebfdd4418ab2ebef09bd28 100644 (file)
@@ -1,3 +1,22 @@
+2011-01-03  Eric Botcazou  <ebotcazou@adacore.com>
+
+       Backport from mainline
+       2010-12-30  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/47038
+       * config/sparc/sparc.c (sparc_file_end): Call resolve_unique_section
+       on the GOT helper if USE_HIDDEN_LINKONCE.
+
+       2010-12-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-30  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        * config/pa/pa.md: Add ",*" condition to 64-bit add/subtract boolean
index 8daa3c44932036da619c4e591662bee8160cf0ae..33b0234a332598f16dbdd529ba46950c6d2af843 100644 (file)
@@ -966,6 +966,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
@@ -1000,14 +1030,9 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
       if (pic_address_needs_scratch (operands[1]))
        operands[1] = 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)
            {
@@ -3389,7 +3414,7 @@ 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;
@@ -3440,11 +3465,13 @@ 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);
@@ -3482,9 +3509,8 @@ 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;
@@ -9082,7 +9108,9 @@ sparc_file_end (void)
          make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
          DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
          DECL_VISIBILITY_SPECIFIED (decl) = 1;
+         resolve_unique_section (decl, 0, flag_function_sections);
          allocate_struct_function (decl, true);
+         cfun->is_thunk = 1;
          current_function_decl = decl;
          init_varasm_status ();
          assemble_start_function (decl, name);