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]

small reg-stack tweek



Hi,
this patch teach gcc to avoid fxch in front of conditional move, where one argument
aready is top and dies.  THis is handled by reversing the cmov direction (swapping
arguments and reversing condition).

It saves fxch in front of suprisingly many conditional moves as the usual sequence:

if (a<b)
  a=b;

usually has the 'b' as temporary variable, while 'a' is long lived so the stack
comes in exactly reversed.

Regtested athlon, bootstrap/regtesting on i686 in progress.

Mon Sep  3 17:22:37 CEST 2001  Jan Hubicka   <jh@suse.cz>
	* reg-stack.c (subst_stack_reg_pat): Handle reversal of conditional moves.

Index: reg-stack.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reg-stack.c,v
retrieving revision 1.87
diff -c -3 -p -r1.87 reg-stack.c
*** reg-stack.c	2001/08/22 14:35:32	1.87
--- reg-stack.c	2001/09/03 15:17:27
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1775,1780 ****
--- 1775,1786 ----
  	  case IF_THEN_ELSE:
  	    /* This insn requires the top of stack to be the destination.  */
  
+ 	    src1 = get_true_reg (&XEXP (pat_src, 1));
+ 	    src2 = get_true_reg (&XEXP (pat_src, 2));
+ 
+ 	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ 	    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
+ 
  	    /* If the comparison operator is an FP comparison operator,
  	       it is handled correctly by compare_for_stack_reg () who
  	       will move the destination to the top of stack. But if the
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1782,1794 ****
  	       have to handle it here.  */
  	    if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
  		&& REGNO (*dest) != regstack->reg[regstack->top])
! 	      emit_swap_insn (insn, regstack, *dest);	
  
! 	    src1 = get_true_reg (&XEXP (pat_src, 1));
! 	    src2 = get_true_reg (&XEXP (pat_src, 2));
  
! 	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
! 	    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
  
  	    {
  	      rtx src_note [3];
--- 1788,1822 ----
  	       have to handle it here.  */
  	    if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
  		&& REGNO (*dest) != regstack->reg[regstack->top])
! 	      {
! 		/* In case one of operands is the top of stack and the operands
! 		   dies, it is safe to make it the destination operand by reversing
! 		   the direction of cmove and avoid fxch.  */
! 		if ((REGNO (*src1) == regstack->reg[regstack->top]
! 		     && src1_note)
! 		    || (REGNO (*src2) == regstack->reg[regstack->top]
! 			&& src2_note))
! 		  {
  
! 		    /* We know that both sources "dies", as one dies and other
! 		       is overwriten by the destination.  Claim both sources
! 		       to be dead, as the code bellow will properly pop the
! 		       non-top-of-stack note and replace top-of-stack by the
! 		       result by popping source first and then pushing result. */
! 		    if (!src1_note)
! 		      src1_note = REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, *src1,
! 									REG_NOTES (insn));
! 		    if (!src2_note)
! 		      src2_note = REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, *src2,
! 									REG_NOTES (insn));
  
! 		    /* i386 do have comparison always reversible.  */
! 		    PUT_CODE (XEXP (pat_src, 0),
! 			      reversed_comparison_code (XEXP (pat_src, 0), insn));
! 		  }
! 		else
! 	          emit_swap_insn (insn, regstack, *dest);	
! 	      }
  
  	    {
  	      rtx src_note [3];


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