This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ia64 .got manipulation changes
- To: gcc-patches at gcc dot gnu dot org
- Subject: ia64 .got manipulation changes
- From: Richard Henderson <rth at cygnus dot com>
- Date: Tue, 4 Jul 2000 12:36:53 -0700
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"