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]

cse fold_rtx tweek


!       for (j = 0;
!            j < 2 && replacements[j]
!            && COST (replacements[j]) < COST (XEXP (x, i));

With the cost changes that happened a while back, this line
prevents constants (or anything else for that matter) from
ever being substituted for a register.  Since registers now
have cost 0, nothing is ever cheaper.  The following changes
this so that we prefer constants if they have the same cost.

I'm wondering if maybe we shouldn't prefer *anything* over a
register, so long as the outer code isn't a SET, since this
would provide some measure of height reduction.  E.g.

	(set r101 (plus r100 r99))
	(set r102 (plus r100 r99))
	(set r103 (plus r102 1))
	-- r101 and r103 used later

At present this will simplify to 

	(set r101 (plus r100 r99))
	(set r103 (plus r101 1))

but a better simplification for ia64 would be

	(set r101 (plus r100 r99))
	(set r103 (plus (plus r100 r99) 1))

Combine will not do this because both r101 and r103 are used,
and it doesn't have any concept of combination for height
reduction instead of reducing instruction count.  Similar
examples can be shown with lea-type shift-and-add instructions.

I do not do anything with this idea here; I may shortly just
to see what sorts of effect it does have.

In addition to the > vs >= change, I also rearrange things
slightly so that we can provide the extra knowledge of the
outer code, which rtx_cost knows how to deal with, but we
were not providing in this instance.

Frankly, our treatment of costs here seems extremely hackful.
Note the apparently arbitrary scaling in notreg_cost.  Note
the code in find_best_addr which appears to revert this
scaling, despite the fact that we only compare apples to 
apples.  Why aren't we examining the cost of the insn as a
whole instead of just looking at some random subexpression?

Tested on alpha, and ia64.

It's mostly a wash on alpha; we do get occasional substitutions
that help, e.g.

-       lda $4,1
-       cmpeq $19,$4,$1
+       cmpeq $19,1,$1
+       lda $5,1

but others that don't, e.g.

-       cmovne $3,$9,$11
+       mov $9,$11
+       cmoveq $3,0,$11

Clearly this is a problem with whole-insn costs and/or the
register allocator.  Not sure what to do about this...

On ia64 we can now simplify a sequence of shifts into a rotate
instruction, when the shift count was a constant argument to an
inline function.  I've not examined the assembly differences in
more detail there.



r~


	* cse.c (notreg_cost): New argument outer.  
	(COST): Pass in SET to notreg_cost
	(COST_IN): New.
	(fold_rtx): Use COST_IN.  Prefer constants when costs
	are the same.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cse.c,v
retrieving revision 1.160
diff -c -p -d -r1.160 cse.c
*** cse.c	2000/09/15 02:56:02	1.160
--- cse.c	2000/09/29 07:16:25
*************** struct table_elt
*** 502,508 ****
     || ((N) < FIRST_PSEUDO_REGISTER					\
         && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
  
! #define COST(X) (GET_CODE (X) == REG ? 0 : notreg_cost (X))
  
  /* Get the info associated with register N.  */
  
--- 502,509 ----
     || ((N) < FIRST_PSEUDO_REGISTER					\
         && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
  
! #define COST(X) (GET_CODE (X) == REG ? 0 : notreg_cost (X, SET))
! #define COST_IN(X,OUTER) (GET_CODE (X) == REG ? 0 : notreg_cost (X, OUTER))
  
  /* Get the info associated with register N.  */
  
*************** struct cse_basic_block_data
*** 636,642 ****
  	   || XEXP (X, 0) == virtual_outgoing_args_rtx))	\
     || GET_CODE (X) == ADDRESSOF)
  
! static int notreg_cost		PARAMS ((rtx));
  static int approx_reg_cost_1	PARAMS ((rtx *, void *));
  static int approx_reg_cost	PARAMS ((rtx));
  static int preferrable		PARAMS ((int, int, int, int));
--- 637,643 ----
  	   || XEXP (X, 0) == virtual_outgoing_args_rtx))	\
     || GET_CODE (X) == ADDRESSOF)
  
! static int notreg_cost		PARAMS ((rtx, enum rtx_code));
  static int approx_reg_cost_1	PARAMS ((rtx *, void *));
  static int approx_reg_cost	PARAMS ((rtx));
  static int preferrable		PARAMS ((int, int, int, int));
*************** preferrable (cost_a, regcost_a, cost_b, 
*** 800,807 ****
     from COST macro to keep it simple.  */
  
  static int
! notreg_cost (x)
       rtx x;
  {
    return ((GET_CODE (x) == SUBREG
  	   && GET_CODE (SUBREG_REG (x)) == REG
--- 801,809 ----
     from COST macro to keep it simple.  */
  
  static int
! notreg_cost (x, outer)
       rtx x;
+      enum rtx_code outer;
  {
    return ((GET_CODE (x) == SUBREG
  	   && GET_CODE (SUBREG_REG (x)) == REG
*************** notreg_cost (x)
*** 813,819 ****
  	   && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (x)),
  				     GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))))
  	  ? 0
! 	  : rtx_cost (x, SET) * 2);
  }
  
  /* Return an estimate of the cost of computing rtx X.
--- 815,821 ----
  	   && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (x)),
  				     GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))))
  	  ? 0
! 	  : rtx_cost (x, outer) * 2);
  }
  
  /* Return an estimate of the cost of computing rtx X.
*************** fold_rtx (x, insn)
*** 3752,3758 ****
  	/* Pick the least expensive of the folded argument and an
  	   equivalent constant argument.  */
  	if (const_arg == 0 || const_arg == folded_arg
! 	    || COST (const_arg) > COST (folded_arg))
  	  cheap_arg = folded_arg, expensive_arg = const_arg;
  	else
  	  cheap_arg = const_arg, expensive_arg = folded_arg;
--- 3754,3760 ----
  	/* Pick the least expensive of the folded argument and an
  	   equivalent constant argument.  */
  	if (const_arg == 0 || const_arg == folded_arg
! 	    || COST_IN (const_arg, code) > COST_IN (folded_arg, code))
  	  cheap_arg = folded_arg, expensive_arg = const_arg;
  	else
  	  cheap_arg = const_arg, expensive_arg = folded_arg;
*************** fold_rtx (x, insn)
*** 3772,3783 ****
  	    copied = 1;
  	  }
  
! 	replacements[0] = cheap_arg, replacements[1] = expensive_arg;
! 	for (j = 0;
! 	     j < 2 && replacements[j]
! 	     && COST (replacements[j]) < COST (XEXP (x, i));
! 	     j++)
  	  {
  	    if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
  	      break;
  
--- 3774,3794 ----
  	    copied = 1;
  	  }
  
! 	/* Order the replacements from cheapest to most expensive.  */
! 	replacements[0] = cheap_arg;
! 	replacements[1] = expensive_arg;
! 
! 	for (j = 0; j < 2 && replacements[j];  j++)
  	  {
+ 	    int old_cost = COST_IN (XEXP (x, i), code);
+ 	    int new_cost = COST_IN (replacements[j], code);
+ 
+ 	    /* Stop if what existed before was cheaper.  Prefer constants
+ 	       in the case of a tie.  */
+ 	    if (new_cost > old_cost
+ 		|| (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
+ 	      break;
+ 
  	    if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
  	      break;
  

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