diff mbox

[SPARC] Backport a couple of fixes to 4.5 branch

Message ID 201101031304.25921.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou Jan. 3, 2011, 12:04 p.m. UTC
They are related to the -freorder-* family of switches; applied on the branch.


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.
diff mbox

Patch

Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 168407)
+++ config/sparc/sparc.c	(working copy)
@@ -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 mod
       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 re
 
   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 re
 	}
       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 re
       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);