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]

IA64 PATCH: C++ thunks


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.  */


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