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]

ia64 .got manipulation changes


This is intended to reduce the number and frequency of loads
from the GOT. 

First, force things like `x' and `x+4' to use the same GOT entry,
with extra addition to make the +4.  Not quite ideal, since if
`x+4' was used all by itself we'd like to just load that.  However,
that I think is going to be a lot less common than just referencing
`x' all by itself, or the Fortran common block in which we're 
likely to directly reference dozens of offsets.

Second, mark the loads from the GOT as unchanging.



r~


        * config/ia64/ia64.c (symbolic_operand): Reject CONST expressions
        with the low 13 bits set.
        (move_operand): Check for CONST|SYMBOL_REF|LABEL_REF directly.
        * config/ia64/ia64.md (movdi): Likewise.  Expand a CONST with one
        of the low 13 bits into a CONST plus an adddi3.
        (load_symptr): Set RTX_UNCHANGING_P.

Index: gcc/config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.c,v
retrieving revision 1.28
diff -c -p -d -r1.28 ia64.c
*** ia64.c	2000/06/27 17:36:59	1.28
--- ia64.c	2000/07/01 21:10:04
*************** symbolic_operand (op, mode)
*** 186,191 ****
--- 186,205 ----
    switch (GET_CODE (op))
      {
      case CONST:
+       op = XEXP (op, 0);
+       if (GET_CODE (op) != PLUS)
+ 	return 0;
+       if (GET_CODE (XEXP (op, 0)) != SYMBOL_REF)
+ 	return 0;
+       op = XEXP (op, 1);
+       if (GET_CODE (op) != CONST_INT)
+ 	return 0;
+       /* Force the low 13 bits of the constant to zero so that we do not
+ 	 use up so many GOT entries.  */
+       if (! TARGET_NO_PIC && ! TARGET_AUTO_PIC && (INTVAL (op) & 0x1fff) != 0)
+ 	return 0;
+       return 1;
+ 
      case SYMBOL_REF:
      case LABEL_REF:
        return 1;
*************** move_operand (op, mode)
*** 270,276 ****
       rtx op;
       enum machine_mode mode;
  {
!   if (! TARGET_NO_PIC && symbolic_operand (op, mode))
      return 0;
  
    return general_operand (op, mode);
--- 284,293 ----
       rtx op;
       enum machine_mode mode;
  {
!   if (! TARGET_NO_PIC
!       && (GET_CODE (op) == CONST
! 	  || GET_CODE (op) == SYMBOL_REF
! 	  || GET_CODE (op) == LABEL_REF))
      return 0;
  
    return general_operand (op, mode);
Index: gcc/config/ia64/ia64.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.md,v
retrieving revision 1.20
diff -c -p -d -r1.20 ia64.md
*** ia64.md	2000/06/27 17:36:59	1.20
--- ia64.md	2000/07/01 21:10:04
***************
*** 255,261 ****
  {
    /* ??? Should generalize this, so that we can also support 32 bit
       pointers.  */
!   if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
      {
        rtx temp;
  
--- 255,264 ----
  {
    /* ??? Should generalize this, so that we can also support 32 bit
       pointers.  */
!   if (! TARGET_NO_PIC
!       && (GET_CODE (operands[1]) == CONST
! 	  || GET_CODE (operands[1]) == SYMBOL_REF
! 	  || GET_CODE (operands[1]) == LABEL_REF))
      {
        rtx temp;
  
***************
*** 273,278 ****
--- 276,296 ----
  	emit_insn (gen_load_fptr (temp, operands[1]));
        else if (sdata_symbolic_operand (operands[1], DImode))
  	emit_insn (gen_load_gprel (temp, operands[1]));
+       else if (GET_CODE (operands[1]) == CONST
+ 	       && GET_CODE (XEXP (operands[1], 0)) == PLUS
+ 	       && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT
+ 	       && (INTVAL (XEXP (XEXP (operands[1], 0), 1)) & 0x1fff) != 0)
+ 	{
+ 	  HOST_WIDE_INT ofs = INTVAL (XEXP (XEXP (operands[1], 0), 1));
+ 	  rtx sym = XEXP (XEXP (operands[1], 0), 0);
+ 	  rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
+ 
+ 	  sym = plus_constant (sym, ofs & ~(HOST_WIDE_INT)0x1fff);
+ 	  ofs &= 0x1fff;
+ 
+ 	  emit_insn (gen_load_symptr (subtarget, sym));
+ 	  emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (ofs)));
+ 	}
        else
  	emit_insn (gen_load_symptr (temp, operands[1]));
  
***************
*** 358,371 ****
  (define_expand "load_symptr"
    [(set (match_dup 2)
  	(plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" "")))
!    (set (match_operand:DI 0 "register_operand" "") (mem:DI (match_dup 2)))]
    ""
    "
  {
!   if (reload_in_progress)
!     operands[2] = operands[0];
!   else
!     operands[2] = gen_reg_rtx (DImode);
  }")
  
  (define_insn "*load_symptr_internal1"
--- 376,388 ----
  (define_expand "load_symptr"
    [(set (match_dup 2)
  	(plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" "")))
!    (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
    ""
    "
  {
!   operands[2] = reload_in_progress ? operands[0] : gen_reg_rtx (DImode);
!   operands[3] = gen_rtx_MEM (DImode, operands[2]);
!   RTX_UNCHANGING_P (operands[3]) = 1;
  }")
  
  (define_insn "*load_symptr_internal1"

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