This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
IA64 PATCH: C++ thunks
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 22 Aug 2003 11:30:19 -0700
- Subject: IA64 PATCH: C++ thunks
- Reply-to: mark at codesourcery dot com
Thunks were entirely broken in ILP32 mode on IA64. There were missing
"addp4" instructions and 8-byte loads that should have been 4-byte
loads. That caused a substantial number of failures in the DejaGNU
testsuite.
I've checked in fixes for this on both the 3.3 branch and the
mainline. On the mainline, now that the pointer-to-member
representation problem is fixed, we can generate better code than on
the branch.
For example, on the branch, we generate this:
addp4 r32 = 0,r32
;;
ld4 r2 = [r32]
;;
addp4 r2 = 0,r2
;;
adds r2 = -24, r2
;;
ld4 r2 = [r2]
;;
add r32 = r32, r2
br.sptk.many _ZNK2S113is_kind_of_S1Ev#
;;
while on the mainline, we generate:
addp4 r32 = 0,r32
;;
ld4 r2 = [r32]
;;
addp4 r2 = -24, r2
;;
ld4 r2 = [r2]
;;
add r32 = r32, r2
br.sptk.many .LTHUNK0
;;
In other words, we are able to take advantage of the form of the
"addp4" instruction that adds an immediate constant.
Tested on ia64-hp-hpux11.23 in both 32-bit and 64-bit modes.
The first patch that follows is the mainline patch; the second is the
branch patch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2003-08-22 Mark Mitchell <mark@codesourcery.com>
* config/ia64/ia64.md (*ptr_extend_plus_1): Rename to ...
(ptr_extend_plus_imm): ... this.
* config/ia64/ia64.c (addp4_optimize_ok): Do not disable addp4
optimization in C++.
(ia64_output_mi_thunk): Support ILP32 mode.
Index: ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.241
diff -c -5 -p -r1.241 ia64.c
*** ia64.c 17 Aug 2003 10:00:04 -0000 1.241
--- ia64.c 22 Aug 2003 17:37:05 -0000
*************** ia64_move_ok (rtx dst, rtx src)
*** 1110,1123 ****
C++ because of GNAT c++/6685. */
int
addp4_optimize_ok (rtx op1, rtx op2)
{
-
- if (!strcmp (lang_hooks.name, "GNU C++"))
- return 0;
-
return (basereg_operand (op1, GET_MODE(op1)) !=
basereg_operand (op2, GET_MODE(op2)));
}
/* Check if OP is a mask suitable for use with SHIFT in a dep.z instruction.
--- 1110,1119 ----
*************** ia64_output_mi_thunk (FILE *file, tree t
*** 8358,8367 ****
--- 8354,8375 ----
/* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END);
this = gen_rtx_REG (Pmode, IN_REG (0));
+ if (TARGET_ILP32)
+ {
+ rtx tmp = gen_rtx_REG (ptr_mode, IN_REG (0));
+ REG_POINTER (tmp) = 1;
+ if (delta && CONST_OK_FOR_I (delta))
+ {
+ emit_insn (gen_ptr_extend_plus_imm (this, tmp, GEN_INT (delta)));
+ delta = 0;
+ }
+ else
+ emit_insn (gen_ptr_extend (this, tmp));
+ }
/* Apply the constant offset, if required. */
if (delta)
{
rtx delta_rtx = GEN_INT (delta);
*************** ia64_output_mi_thunk (FILE *file, tree t
*** 8379,8399 ****
if (vcall_offset)
{
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx tmp = gen_rtx_REG (Pmode, 2);
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
! if (!CONST_OK_FOR_J (vcall_offset))
{
! rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
! emit_move_insn (tmp2, vcall_offset_rtx);
! vcall_offset_rtx = tmp2;
}
- emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
emit_insn (gen_adddi3 (this, this, tmp));
}
/* Generate a tail call to the target function. */
--- 8387,8429 ----
if (vcall_offset)
{
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx tmp = gen_rtx_REG (Pmode, 2);
! if (TARGET_ILP32)
! {
! rtx t = gen_rtx_REG (ptr_mode, 2);
! REG_POINTER (t) = 1;
! emit_move_insn (t, gen_rtx_MEM (ptr_mode, this));
! if (CONST_OK_FOR_I (vcall_offset))
! {
! emit_insn (gen_ptr_extend_plus_imm (tmp, t,
! vcall_offset_rtx));
! vcall_offset = 0;
! }
! else
! emit_insn (gen_ptr_extend (tmp, t));
! }
! else
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
! if (vcall_offset)
{
! if (!CONST_OK_FOR_J (vcall_offset))
! {
! rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
! emit_move_insn (tmp2, vcall_offset_rtx);
! vcall_offset_rtx = tmp2;
! }
! emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
}
! if (TARGET_ILP32)
! emit_move_insn (gen_rtx_REG (ptr_mode, 2),
! gen_rtx_MEM (ptr_mode, tmp));
! else
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
emit_insn (gen_adddi3 (this, this, tmp));
}
/* Generate a tail call to the target function. */
Index: ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.111
diff -c -5 -p -r1.111 ia64.md
*** ia64.md 8 Aug 2003 23:49:57 -0000 1.111
--- ia64.md 22 Aug 2003 17:37:05 -0000
***************
*** 5470,5480 ****
[(set_attr "itanium_class" "ialu")])
;;
;; Optimizations for ptr_extend
! (define_insn "*ptr_extend_plus_1"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
(unspec:DI
[(plus:SI (match_operand:SI 1 "basereg_operand" "r")
(match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
UNSPEC_ADDP4))]
--- 5470,5480 ----
[(set_attr "itanium_class" "ialu")])
;;
;; Optimizations for ptr_extend
! (define_insn "ptr_extend_plus_imm"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
(unspec:DI
[(plus:SI (match_operand:SI 1 "basereg_operand" "r")
(match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
UNSPEC_ADDP4))]
2003-08-22 Mark Mitchell <mark@codesourcery.com>
* config/ia64/ia64.c (ia64_output_mi_thunk): Support ILP32 mode.
Index: ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.198.2.12
diff -c -5 -p -r1.198.2.12 ia64.c
*** ia64.c 10 Aug 2003 21:29:18 -0000 1.198.2.12
--- ia64.c 22 Aug 2003 17:31:44 -0000
*************** ia64_output_mi_thunk (file, thunk, delta
*** 8415,8424 ****
--- 8415,8427 ----
/* Mark the end of the (empty) prologue. */
emit_note (NULL, NOTE_INSN_PROLOGUE_END);
this = gen_rtx_REG (Pmode, IN_REG (0));
+ if (TARGET_ILP32)
+ emit_insn (gen_ptr_extend (this,
+ gen_rtx_REG (ptr_mode, IN_REG (0))));
/* Apply the constant offset, if required. */
if (delta)
{
rtx delta_rtx = GEN_INT (delta);
*************** ia64_output_mi_thunk (file, thunk, delta
*** 8436,8456 ****
if (vcall_offset)
{
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx tmp = gen_rtx_REG (Pmode, 2);
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
if (!CONST_OK_FOR_J (vcall_offset))
{
rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
emit_move_insn (tmp2, vcall_offset_rtx);
vcall_offset_rtx = tmp2;
}
emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
emit_insn (gen_adddi3 (this, this, tmp));
}
/* Generate a tail call to the target function. */
--- 8439,8470 ----
if (vcall_offset)
{
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx tmp = gen_rtx_REG (Pmode, 2);
! if (TARGET_ILP32)
! {
! rtx t = gen_rtx_REG (ptr_mode, 2);
! emit_move_insn (t, gen_rtx_MEM (ptr_mode, this));
! emit_insn (gen_ptr_extend (tmp, t));
! }
! else
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
if (!CONST_OK_FOR_J (vcall_offset))
{
rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
emit_move_insn (tmp2, vcall_offset_rtx);
vcall_offset_rtx = tmp2;
}
emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
! if (TARGET_ILP32)
! emit_move_insn (gen_rtx_REG (ptr_mode, 2),
! gen_rtx_MEM (ptr_mode, tmp));
! else
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
emit_insn (gen_adddi3 (this, this, tmp));
}
/* Generate a tail call to the target function. */
2003-08-22 Mark Mitchell <mark@codesourcery.com>
* config/ia64/ia64.c (ia64_output_mi_thunk): Support ILP32 mode.
Index: ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.198.2.12
diff -c -5 -p -r1.198.2.12 ia64.c
*** ia64.c 10 Aug 2003 21:29:18 -0000 1.198.2.12
--- ia64.c 22 Aug 2003 17:31:44 -0000
*************** ia64_output_mi_thunk (file, thunk, delta
*** 8415,8424 ****
--- 8415,8427 ----
/* Mark the end of the (empty) prologue. */
emit_note (NULL, NOTE_INSN_PROLOGUE_END);
this = gen_rtx_REG (Pmode, IN_REG (0));
+ if (TARGET_ILP32)
+ emit_insn (gen_ptr_extend (this,
+ gen_rtx_REG (ptr_mode, IN_REG (0))));
/* Apply the constant offset, if required. */
if (delta)
{
rtx delta_rtx = GEN_INT (delta);
*************** ia64_output_mi_thunk (file, thunk, delta
*** 8436,8456 ****
if (vcall_offset)
{
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx tmp = gen_rtx_REG (Pmode, 2);
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
if (!CONST_OK_FOR_J (vcall_offset))
{
rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
emit_move_insn (tmp2, vcall_offset_rtx);
vcall_offset_rtx = tmp2;
}
emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
emit_insn (gen_adddi3 (this, this, tmp));
}
/* Generate a tail call to the target function. */
--- 8439,8470 ----
if (vcall_offset)
{
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx tmp = gen_rtx_REG (Pmode, 2);
! if (TARGET_ILP32)
! {
! rtx t = gen_rtx_REG (ptr_mode, 2);
! emit_move_insn (t, gen_rtx_MEM (ptr_mode, this));
! emit_insn (gen_ptr_extend (tmp, t));
! }
! else
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
if (!CONST_OK_FOR_J (vcall_offset))
{
rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
emit_move_insn (tmp2, vcall_offset_rtx);
vcall_offset_rtx = tmp2;
}
emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
! if (TARGET_ILP32)
! emit_move_insn (gen_rtx_REG (ptr_mode, 2),
! gen_rtx_MEM (ptr_mode, tmp));
! else
! emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
emit_insn (gen_adddi3 (this, this, tmp));
}
/* Generate a tail call to the target function. */