This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[arm] patch for GOTOFF relocs


PIC code can be made more efficient by using GOTOFF relocs to address
local variables.  That is, for code like:

static int a;
int f { return a; }

we want to generate

f:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        str     sl, [sp, #-4]!
        ldr     sl, .L3
        ldr     r3, .L3+4
.L2:
        add     sl, pc, sl
        ldr     r0, [sl, r3]
        @ lr needed for prologue
        ldmfd   sp!, {sl}
        mov     pc, lr
.L4:
        .align  2
.L3:
        .word   _GLOBAL_OFFSET_TABLE_-(.L2+8)
        .word   a(GOTOFF)

rather than

f:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, current_function_anonymous_args = 0
        stmfd   sp!, {sl, lr}
        ldr     sl, .L4
        ldr     r2, .L4+4
.L3:
        add     sl, pc, sl
        ldr     r3, [sl, r2]
        ldr     r0, [r3, #0]
        ldmfd   sp!, {sl, pc}
.L5:
        .align  2
.L4:
        .word   _GLOBAL_OFFSET_TABLE_-(.L3+8)
        .word   a(GOT)

The patch below does this. 

Incidentally, is it possible to have the PIC register determined by the
register allocator on a per-function basis, rather than being fixed?  In
the code above, it would be nice if one of the spare call-clobbered regs
could be used to address the GOT, rather than r10 which is call-saved
and needs to be stacked.

p.

--

2002-02-17  Philip Blundell  <pb@nexus.co.uk>

	* config/arm/arm.c (arm_encode_call_attribute): Operate on any
	decl, not just FUNCTION_DECL.
	(legitimize_pic_address): Handle local SYMBOL_REF like LABEL_REF.
	(arm_assemble_integer): Likewise.
	* config/arm/arm.h (ARM_ENCODE_CALL_TYPE): Allow any decl to be
	marked local.
	
Index: arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.193
diff -u -p -r1.193 arm.c
--- arm.c	2002/02/04 20:23:06	1.193
+++ arm.c	2002/02/17 15:23:25
@@ -2099,9 +2099,6 @@ arm_encode_call_attribute (decl, flag)
   int          len = strlen (str);
   char *       newstr;
 
-  if (TREE_CODE (decl) != FUNCTION_DECL)
-    return;
-
   /* Do not allow weak functions to be treated as short call.  */
   if (DECL_WEAK (decl) && flag == SHORT_CALL_FLAG_CHAR)
     return;
@@ -2315,7 +2312,10 @@ legitimize_pic_address (orig, mode, reg)
       else
 	emit_insn (gen_pic_load_addr_thumb (address, orig));
 
-      if (GET_CODE (orig) == LABEL_REF && NEED_GOT_RELOC)
+      if ((GET_CODE (orig) == LABEL_REF
+	   || (GET_CODE (orig) == SYMBOL_REF && 
+	       ENCODED_SHORT_CALL_ATTR_P (XSTR (orig, 0))))
+	  && NEED_GOT_RELOC)
 	pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
       else
 	{
@@ -8605,7 +8599,9 @@ arm_assemble_integer (x, size, aligned_p
       if (NEED_GOT_RELOC && flag_pic && making_const_table &&
 	  (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
 	{
-	  if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
+	  if (GET_CODE (x) == SYMBOL_REF 
+	      && (CONSTANT_POOL_ADDRESS_P (x)
+		  || ENCODED_SHORT_CALL_ATTR_P (XSTR (x, 0))))
 	    fputs ("(GOTOFF)", asm_out_file);
 	  else if (GET_CODE (x) == LABEL_REF)
 	    fputs ("(GOTOFF)", asm_out_file);
Index: arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.136
diff -u -p -r1.136 arm.h
--- arm.h	2002/02/04 20:23:07	1.136
+++ arm.h	2002/02/17 15:23:27
@@ -1891,9 +1891,9 @@ typedef struct
    or known to be defined in this file then encode a short call flag.
    This macro is used inside the ENCODE_SECTION macro.  */
 #define ARM_ENCODE_CALL_TYPE(decl)					\
-  if (TREE_CODE (decl) == FUNCTION_DECL)				\
+  if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')			\
     {									\
-      if (DECL_WEAK (decl))						\
+      if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl))	\
         arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR);		\
       else if (! TREE_PUBLIC (decl))        				\
         arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR);		\


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]