i387 comaprison tweek

Jan Hubicka jh@suse.cz
Fri Jul 13 16:29:00 GMT 2001


Hi,
I do have this patch waiting for a while.  It makes ix86_expand_compare to avoid
creating compare-and-branch instruction when doing so is not needed - we use fcomi
instruction followed by single branch.

This improves the code generation in some cases, as we handle these instructions
better and can CSE.

Bootstrapped i686
Honza

So čec 14 01:29:10 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* i386-protos.h (ix86_split_fp_branch): Update prototype.
	(ix86_fp_jump_nontrivial_p): New.
	* i386.md (fp_jcc_?): Update call of split_fp_branch;
	use ix86_fp_jump_nontrivial_p.
	* i386.c (ix86_fp_jump_nontrivial_p): New.
	(ix86_split_fp_branch): Accept code instead of rtx.
	(ix86_expand_compare): Expand comparison early in case
	doing so is resonably cheap.

*** i386-protos.h.old	Thu Jul 12 18:21:51 2001
--- i386-protos.h	Thu Jul 12 18:57:18 2001
*************** extern int x86_64_zero_extended_value PA
*** 142,148 ****
  
  extern rtx ix86_force_to_memory PARAMS ((enum machine_mode, rtx));
  extern void ix86_free_from_memory PARAMS ((enum machine_mode));
! extern void ix86_split_fp_branch PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
  extern int ix86_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
  extern int ix86_register_move_cost PARAMS ((enum machine_mode, enum reg_class,
  					    enum reg_class));
--- 142,149 ----
  
  extern rtx ix86_force_to_memory PARAMS ((enum machine_mode, rtx));
  extern void ix86_free_from_memory PARAMS ((enum machine_mode));
! extern void ix86_split_fp_branch PARAMS ((enum rtx_code code, rtx,
! 					  rtx, rtx, rtx, rtx));
  extern int ix86_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
  extern int ix86_register_move_cost PARAMS ((enum machine_mode, enum reg_class,
  					    enum reg_class));
*************** extern int ix86_memory_move_cost PARAMS 
*** 155,160 ****
--- 156,162 ----
  					  int));
  extern void ix86_set_move_mem_attrs PARAMS ((rtx, rtx, rtx, rtx, rtx));
  extern void emit_i387_cw_initialization PARAMS ((rtx, rtx));
+ extern bool ix86_fp_jump_nontrivial_p PARAMS ((enum rtx_code));
  
  
  #ifdef TREE_CODE
*** i386.md.old	Thu Jul 12 18:22:14 2001
--- i386.md	Sat Jul 14 00:56:09 2001
***************
*** 12686,12692 ****
    "TARGET_CMOVE && TARGET_80387
     && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_insn "*fp_jcc_1_sse"
--- 12747,12754 ----
    "TARGET_CMOVE && TARGET_80387
     && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_1_sse"
***************
*** 12700,12706 ****
     (clobber (reg:CCFP 17))]
    "TARGET_80387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_insn "*fp_jcc_1_sse_only"
--- 12762,12769 ----
     (clobber (reg:CCFP 17))]
    "TARGET_80387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_1_sse_only"
***************
*** 12713,12719 ****
     (clobber (reg:CCFP 18))
     (clobber (reg:CCFP 17))]
    "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_insn "*fp_jcc_2"
--- 12776,12783 ----
     (clobber (reg:CCFP 18))
     (clobber (reg:CCFP 17))]
    "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_2"
***************
*** 12728,12734 ****
    "TARGET_CMOVE && TARGET_80387
     && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_insn "*fp_jcc_2_sse"
--- 12792,12799 ----
    "TARGET_CMOVE && TARGET_80387
     && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_2_sse"
***************
*** 12742,12748 ****
     (clobber (reg:CCFP 17))]
    "TARGET_80387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_insn "*fp_jcc_2_sse_only"
--- 12807,12814 ----
     (clobber (reg:CCFP 17))]
    "TARGET_80387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_2_sse_only"
***************
*** 12755,12761 ****
     (clobber (reg:CCFP 18))
     (clobber (reg:CCFP 17))]
    "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_insn "*fp_jcc_3"
--- 12821,12828 ----
     (clobber (reg:CCFP 18))
     (clobber (reg:CCFP 17))]
    "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_3"
***************
*** 12773,12779 ****
     && GET_MODE (operands[1]) == GET_MODE (operands[2])
     && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
     && SELECT_CC_MODE (GET_CODE (operands[0]),
! 		      operands[1], operands[2]) == CCFPmode"
    "#")
  
  (define_insn "*fp_jcc_4"
--- 12840,12847 ----
     && GET_MODE (operands[1]) == GET_MODE (operands[2])
     && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
     && SELECT_CC_MODE (GET_CODE (operands[0]),
! 		      operands[1], operands[2]) == CCFPmode
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_4"
***************
*** 12791,12797 ****
     && GET_MODE (operands[1]) == GET_MODE (operands[2])
     && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
     && SELECT_CC_MODE (GET_CODE (operands[0]),
! 		      operands[1], operands[2]) == CCFPmode"
    "#")
  
  (define_insn "*fp_jcc_5"
--- 12859,12866 ----
     && GET_MODE (operands[1]) == GET_MODE (operands[2])
     && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
     && SELECT_CC_MODE (GET_CODE (operands[0]),
! 		      operands[1], operands[2]) == CCFPmode
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_5"
***************
*** 12806,12812 ****
     (clobber (match_scratch:HI 4 "=a"))]
    "TARGET_80387
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_insn "*fp_jcc_6"
--- 12875,12882 ----
     (clobber (match_scratch:HI 4 "=a"))]
    "TARGET_80387
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_insn "*fp_jcc_6"
***************
*** 12821,12827 ****
     (clobber (match_scratch:HI 4 "=a"))]
    "TARGET_80387
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
    "#")
  
  (define_split
--- 12891,12898 ----
     (clobber (match_scratch:HI 4 "=a"))]
    "TARGET_80387
     && FLOAT_MODE_P (GET_MODE (operands[1]))
!    && GET_MODE (operands[1]) == GET_MODE (operands[2])
!    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
    "#")
  
  (define_split
***************
*** 12836,12842 ****
    "reload_completed"
    [(const_int 0)]
  {
!   ix86_split_fp_branch (operands[0], operands[1], operands[2],
  			operands[3], operands[4], NULL_RTX);
    DONE;
  })
--- 12907,12913 ----
    "reload_completed"
    [(const_int 0)]
  {
!   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
  			operands[3], operands[4], NULL_RTX);
    DONE;
  })
***************
*** 12857,12863 ****
  	  (match_dup 3)
  	  (match_dup 4)))]
  {
!   ix86_split_fp_branch (operands[0], operands[1], operands[2],
  			operands[3], operands[4], operands[5]);
    DONE;
  })
--- 12928,12934 ----
  	  (match_dup 3)
  	  (match_dup 4)))]
  {
!   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
  			operands[3], operands[4], operands[5]);
    DONE;
  })
*** i386.c.old	Thu Jul 12 18:11:03 2001
--- i386.c	Thu Jul 12 19:13:30 2001
*************** ix86_expand_compare (code, second_test, 
*** 6060,6065 ****
--- 6060,6077 ----
    return ret;
  }
  
+ /* Return true if the CODE will result in nontrivial jump sequence.  */
+ bool
+ ix86_fp_jump_nontrivial_p (code)
+     enum rtx_code code;
+ {
+   enum rtx_code bypass_code, first_code, second_code;
+   if (!TARGET_CMOVE)
+     return true;
+   ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
+   return bypass_code != NIL || second_code != NIL;
+ }
+ 
  void
  ix86_expand_branch (code, label)
       enum rtx_code code;
*************** ix86_expand_branch (code, label)
*** 6084,6117 ****
      case DFmode:
      case XFmode:
      case TFmode:
-       /* Don't expand the comparison early, so that we get better code
- 	 when jump or whoever decides to reverse the comparison.  */
        {
  	rtvec vec;
  	int use_fcomi;
  
  	code = ix86_prepare_fp_compare_args (code, &ix86_compare_op0,
  					     &ix86_compare_op1);
  
! 	tmp = gen_rtx_fmt_ee (code, VOIDmode,
! 			      ix86_compare_op0, ix86_compare_op1);
! 	tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
! 				    gen_rtx_LABEL_REF (VOIDmode, label),
! 				    pc_rtx);
! 	tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
! 
! 	use_fcomi = ix86_use_fcomi_compare (code);
! 	vec = rtvec_alloc (3 + !use_fcomi);
! 	RTVEC_ELT (vec, 0) = tmp;
! 	RTVEC_ELT (vec, 1)
! 	  = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 18));
! 	RTVEC_ELT (vec, 2)
! 	  = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 17));
! 	if (! use_fcomi)
! 	  RTVEC_ELT (vec, 3)
! 	    = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
  
!         emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
  	return;
        }
  
--- 6096,6143 ----
      case DFmode:
      case XFmode:
      case TFmode:
        {
  	rtvec vec;
  	int use_fcomi;
+ 	enum rtx_code bypass_code, first_code, second_code;
  
  	code = ix86_prepare_fp_compare_args (code, &ix86_compare_op0,
  					     &ix86_compare_op1);
+ 	
+ 	ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
  
! 	/* Check whether we will use the natural sequence with one jump.  If
! 	   so, we can expand jump early.  Otherwise delay expansion by
! 	   creating compound insn to not confuse optimizers.  */
! 	if (bypass_code == NIL && second_code == NIL
! 	    && TARGET_CMOVE)
! 	  {
! 	    ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
! 				  gen_rtx_LABEL_REF (VOIDmode, label),
! 				  pc_rtx, NULL_RTX);
! 	  }
! 	else
! 	  {
! 	    tmp = gen_rtx_fmt_ee (code, VOIDmode,
! 				  ix86_compare_op0, ix86_compare_op1);
! 	    tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
! 					gen_rtx_LABEL_REF (VOIDmode, label),
! 					pc_rtx);
! 	    tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
! 
! 	    use_fcomi = ix86_use_fcomi_compare (code);
! 	    vec = rtvec_alloc (3 + !use_fcomi);
! 	    RTVEC_ELT (vec, 0) = tmp;
! 	    RTVEC_ELT (vec, 1)
! 	      = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 18));
! 	    RTVEC_ELT (vec, 2)
! 	      = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 17));
! 	    if (! use_fcomi)
! 	      RTVEC_ELT (vec, 3)
! 		= gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
  
! 	    emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
! 	  }
  	return;
        }
  
*************** ix86_expand_branch (code, label)
*** 6235,6246 ****
  
  /* Split branch based on floating point condition.  */
  void
! ix86_split_fp_branch (condition, op1, op2, target1, target2, tmp)
!      rtx condition, op1, op2, target1, target2, tmp;
  {
    rtx second, bypass;
    rtx label = NULL_RTX;
!   enum rtx_code code = GET_CODE (condition);
  
    if (target2 != pc_rtx)
      {
--- 6261,6273 ----
  
  /* Split branch based on floating point condition.  */
  void
! ix86_split_fp_branch (code, op1, op2, target1, target2, tmp)
!      enum rtx_code code;
!      rtx op1, op2, target1, target2, tmp;
  {
    rtx second, bypass;
    rtx label = NULL_RTX;
!   rtx condition;
  
    if (target2 != pc_rtx)
      {



More information about the Gcc-patches mailing list