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]

Tweak MIPS representation of GOT accesses


This patch changes the representation of MIPS GOT accesses from
non-trapping MEMs to UNSPECs.  This was something I originally
mentioned in:

    http://gcc.gnu.org/ml/gcc-patches/2003-11/msg02307.html

Specifically:

    By the way, the original reason for using MEMs for GOT accesses
    was precisely so that we could have variable call address entries.
    I couldn't think of any other way of handling it, at least not without
    crippling the scheduler.  Wish I'd thought of this a year ago...

    If we do change calls to use UNSPECs rather than MEMs, it might be a
    good idea to do the same for non-call accesses.  It'd only be a
    small change, but not one that's suitable for stage 3.

I did a comparison of c-torture assembly output before and after
this change (options {-O2}{-mabi=32,-mabi=n32,-mabi=64}{,-mxgot})
and verified that the scheduler does have more freedom to move
the GOT accesses around.

Bootstrapped & regression tested on mips-sgi-irix6.5, installed on HEAD.

Richard


	* config/mips/mips-protos.h (mips_load_got_page): Delete.
	(mips_load_got_global): Delete.
	(mips_gotoff_page): Declare.
	* config/mips/mips.c (mips_got_alias_set, mips_load_got): Delete.
	(mips_load_got_page, mips_load_got_global): Delete.
	(mips_gotoff_page): New function.
	(override_options): Don't initialize mips_got_alias_set.
	* config/mips/mips.md (UNSPEC_LOAD_GOT): New constant.
	(*xgot_lo[sd]i, *got_disp[sd]i, *got_page[sd]i): Build an
	UNSPEC_LOAD_GOT pattern rather than a MEM.
	(*load_got[sd]i): New patterns.

Index: config/mips/mips-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips-protos.h,v
retrieving revision 1.63
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.63 mips-protos.h
*** config/mips/mips-protos.h	12 Feb 2004 19:08:33 -0000	1.63
--- config/mips/mips-protos.h	14 Feb 2004 12:58:59 -0000
*************** extern int mips_const_insns (rtx);
*** 32,40 ****
  extern int mips_fetch_insns (rtx);
  extern bool mips_legitimate_address_p (enum machine_mode, rtx, int);
  extern bool mips_legitimize_address (rtx *, enum machine_mode);
  extern rtx mips_gotoff_global (rtx);
- extern rtx mips_load_got_page (rtx);
- extern rtx mips_load_got_global (rtx, rtx);
  extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
  
  extern int m16_uimm3_b (rtx, enum machine_mode);
--- 32,39 ----
  extern int mips_fetch_insns (rtx);
  extern bool mips_legitimate_address_p (enum machine_mode, rtx, int);
  extern bool mips_legitimize_address (rtx *, enum machine_mode);
+ extern rtx mips_gotoff_page (rtx);
  extern rtx mips_gotoff_global (rtx);
  extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
  
  extern int m16_uimm3_b (rtx, enum machine_mode);
Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.381
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.381 mips.c
*** config/mips/mips.c	14 Feb 2004 12:45:52 -0000	1.381
--- config/mips/mips.c	14 Feb 2004 12:59:02 -0000
*************** static rtx mips_force_temporary (rtx, rt
*** 198,204 ****
  static rtx mips_split_symbol (rtx, rtx);
  static rtx mips_unspec_address (rtx, enum mips_symbol_type);
  static rtx mips_unspec_offset_high (rtx, rtx, rtx, enum mips_symbol_type);
- static rtx mips_load_got (rtx, rtx, enum mips_symbol_type);
  static rtx mips_add_offset (rtx, HOST_WIDE_INT);
  static unsigned int mips_build_shift (struct mips_integer_op *, HOST_WIDE_INT);
  static unsigned int mips_build_lower (struct mips_integer_op *,
--- 198,203 ----
*************** char mips_print_operand_punct[256];
*** 537,545 ****
  /* Map GCC register number to debugger register number.  */
  int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
  
- /* An alias set for the GOT.  */
- static GTY(()) int mips_got_alias_set;
- 
  /* A copy of the original flag_delayed_branch: see override_options.  */
  static int mips_flag_delayed_branch;
  
--- 536,541 ----
*************** mips_unspec_offset_high (rtx temp, rtx b
*** 1744,1767 ****
  }
  
  
! /* Return a memory reference for the GOT slot whose offset is given by
!    mips_unspec_address (ADDR, SYMBOL_TYPE).  Register BASE contains the
!    high part of the offset plus $gp.  */
  
! static rtx
! mips_load_got (rtx base, rtx addr, enum mips_symbol_type symbol_type)
  {
!   rtx mem, offset;
! 
!   offset = mips_unspec_address (addr, symbol_type);
!   mem = gen_rtx_MEM (ptr_mode, gen_rtx_LO_SUM (Pmode, base, offset));
!   set_mem_alias_set (mem, mips_got_alias_set);
! 
!   /* GOT entries are constant and references to them can't trap.  */
!   RTX_UNCHANGING_P (mem) = 1;
!   MEM_NOTRAP_P (mem) = 1;
! 
!   return mem;
  }
  
  
--- 1740,1751 ----
  }
  
  
! /* Return the offset of a GOT page entry for local address ADDR.  */
  
! rtx
! mips_gotoff_page (rtx addr)
  {
!   return mips_unspec_address (addr, SYMBOL_GOTOFF_PAGE);
  }
  
  
*************** mips_gotoff_global (rtx addr)
*** 1775,1799 ****
  }
  
  
- /* Fetch the high part of local_got_operand ADDR from the GOT.  */
- 
- rtx
- mips_load_got_page (rtx addr)
- {
-   return mips_load_got (pic_offset_table_rtx, addr, SYMBOL_GOTOFF_PAGE);
- }
- 
- 
- /* Fetch the address of global_got_operand ADDR from the GOT.  BASE is a
-    register that holds the address _gp + %got_hi(ADDR).  */
- 
- rtx
- mips_load_got_global (rtx base, rtx addr)
- {
-   return mips_load_got (base, addr, SYMBOL_GOTOFF_GLOBAL);
- }
- 
- 
  /* Return a legitimate address for REG + OFFSET.  This function will
     create a temporary register if OFFSET is not a SMALL_OPERAND.  */
  
--- 1759,1764 ----
*************** override_options (void)
*** 5079,5087 ****
  
    /* Function to allocate machine-dependent function status.  */
    init_machine_status = &mips_init_machine_status;
- 
-   /* Create a unique alias set for GOT references.  */
-   mips_got_alias_set = new_alias_set ();
  
    if (TARGET_EXPLICIT_RELOCS || mips_split_addresses)
      {
--- 5044,5049 ----
Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.216
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.216 mips.md
*** config/mips/mips.md	13 Feb 2004 04:55:41 -0000	1.216
--- config/mips/mips.md	14 Feb 2004 12:59:03 -0000
*************** (define_constants
*** 55,60 ****
--- 55,61 ----
     (UNSPEC_SDR			25)
     (UNSPEC_LOADGP		26)
     (UNSPEC_LOAD_CALL		27)
+    (UNSPEC_LOAD_GOT		28)
  
     (UNSPEC_ADDRESS_FIRST	100)
  
*************** (define_insn_and_split "*xgot_losi"
*** 4170,4177 ****
    "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0) (match_dup 3))]
!   { operands[3] = mips_load_got_global (operands[1], operands[2]); }
    [(set_attr "got" "load")])
  
  (define_insn_and_split "*xgot_hidi"
--- 4171,4179 ----
    "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0)
! 	(unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
!   { operands[3] = mips_gotoff_global (operands[2]); }
    [(set_attr "got" "load")])
  
  (define_insn_and_split "*xgot_hidi"
*************** (define_insn_and_split "*xgot_lodi"
*** 4195,4202 ****
    "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0) (match_dup 3))]
!   { operands[3] = mips_load_got_global (operands[1], operands[2]); }
    [(set_attr "got" "load")])
  
  ;; Insns to fetch a global symbol from a normal GOT.
--- 4197,4205 ----
    "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0)
! 	(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
!   { operands[3] = mips_gotoff_global (operands[2]); }
    [(set_attr "got" "load")])
  
  ;; Insns to fetch a global symbol from a normal GOT.
*************** (define_insn_and_split "*got_dispsi"
*** 4207,4214 ****
    "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0) (match_dup 2))]
!   { operands[2] = mips_load_got_global (pic_offset_table_rtx, operands[1]); }
    [(set_attr "got" "load")])
  
  (define_insn_and_split "*got_dispdi"
--- 4210,4221 ----
    "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0)
! 	(unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
! {
!   operands[2] = pic_offset_table_rtx;
!   operands[3] = mips_gotoff_global (operands[1]);
! }
    [(set_attr "got" "load")])
  
  (define_insn_and_split "*got_dispdi"
*************** (define_insn_and_split "*got_dispdi"
*** 4217,4224 ****
    "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0) (match_dup 2))]
!   { operands[2] = mips_load_got_global (pic_offset_table_rtx, operands[1]); }
    [(set_attr "got" "load")])
  
  ;; Insns for loading the high part of a local symbol.
--- 4224,4235 ----
    "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0)
! 	(unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
! {
!   operands[2] = pic_offset_table_rtx;
!   operands[3] = mips_gotoff_global (operands[1]);
! }
    [(set_attr "got" "load")])
  
  ;; Insns for loading the high part of a local symbol.
*************** (define_insn_and_split "*got_pagesi"
*** 4229,4236 ****
    "TARGET_EXPLICIT_RELOCS"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0) (match_dup 2))]
!   { operands[2] = mips_load_got_page (operands[1]); }
    [(set_attr "got" "load")])
  
  (define_insn_and_split "*got_pagedi"
--- 4240,4251 ----
    "TARGET_EXPLICIT_RELOCS"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0)
! 	(unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
! {
!   operands[2] = pic_offset_table_rtx;
!   operands[3] = mips_gotoff_page (operands[1]);
! }
    [(set_attr "got" "load")])
  
  (define_insn_and_split "*got_pagedi"
*************** (define_insn_and_split "*got_pagedi"
*** 4239,4247 ****
    "TARGET_EXPLICIT_RELOCS"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0) (match_dup 2))]
!   { operands[2] = mips_load_got_page (operands[1]); }
    [(set_attr "got" "load")])
  
  ;; Instructions for adding the low 16 bits of an address to a register.
  ;; Operand 2 is the address: print_operand works out which relocation
--- 4254,4290 ----
    "TARGET_EXPLICIT_RELOCS"
    "#"
    "&& reload_completed"
!   [(set (match_dup 0)
! 	(unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
! {
!   operands[2] = pic_offset_table_rtx;
!   operands[3] = mips_gotoff_page (operands[1]);
! }
    [(set_attr "got" "load")])
+ 
+ ;; Lower-level instructions for loading an address from the GOT.
+ ;; We could use MEMs, but an unspec gives more optimization
+ ;; opportunities.
+ 
+ (define_insn "*load_gotsi"
+   [(set (match_operand:SI 0 "register_operand" "=d")
+ 	(unspec:SI [(match_operand:SI 1 "register_operand" "d")
+ 		    (match_operand:SI 2 "immediate_operand" "")]
+ 		   UNSPEC_LOAD_GOT))]
+   "TARGET_ABICALLS"
+   "lw\t%0,%R2(%1)"
+   [(set_attr "type" "load")
+    (set_attr "length" "4")])
+ 
+ (define_insn "*load_gotdi"
+   [(set (match_operand:DI 0 "register_operand" "=d")
+ 	(unspec:DI [(match_operand:DI 1 "register_operand" "d")
+ 		    (match_operand:DI 2 "immediate_operand" "")]
+ 		   UNSPEC_LOAD_GOT))]
+   "TARGET_ABICALLS"
+   "ld\t%0,%R2(%1)"
+   [(set_attr "type" "load")
+    (set_attr "length" "4")])
  
  ;; Instructions for adding the low 16 bits of an address to a register.
  ;; Operand 2 is the address: print_operand works out which relocation


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