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]

Re: Problems with the way we calculate costs


On 7 Sep 2000, Geoff Keating wrote:

> this patch causes the bootstrap to fail on powerpc-linux.

> ; (reg:QI r3) was stored into this location earlier, so this gets
> ; turned into (set (reg:QI 399) (reg:QI 3)).  This is a register
> ; equivalence, but unfortunately CSE doesn't cope very well with
> ; registers that change modes (it's not allowed for pseudos)
> ; and so what CSE actually remembers is that
> ; register 399 is equivalent to (reg:SI 3).
> ; This is a bug.

I remember running into that CSE bug once before, and giving up
trying to fix it.

> However, I don't like the way that CSE stretched the lifespan of r3
> over so many insns in the first place, and would much rather this
> didn't happen.  Explicit hard register uses like this are bad and
> are likely to cause problems later in the compiler.

I can think of several ways to fix that.  One of them is the patch below.
I'm not too happy with it, but none of the other solutions I can think of
are any more elegant.  Any better ideas?


Bernd

	* cse.c (approx_reg_cost): Return INT_MAX if reference to non-fixed
	hardreg is seen.
	(preferrable): Deal with cases where either cost or regcost is
	INT_MAX.
	(cse_insn): Use INT_MAX rather than 10000.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cse.c,v
retrieving revision 1.156
diff -u -p -r1.156 cse.c
--- cse.c	2000/09/06 09:20:37	1.156
+++ cse.c	2000/09/08 12:52:14
@@ -730,7 +730,7 @@ approx_reg_cost_1 (xp, data)
 /* Return an estimate of the cost of the registers used in an rtx.
    This is mostly the number of different REG expressions in the rtx;
    however for some excecptions like fixed registers we use a cost of
-   0.  */
+   0.  If any other hard register reference occurs, return INT_MAX.  */
 
 static int
 approx_reg_cost (x)
@@ -739,6 +739,7 @@ approx_reg_cost (x)
   regset_head set;
   int i;
   int cost = 0;
+  int hardregs = 0;
 
   INIT_REG_SET (&set);
   for_each_rtx (&x, approx_reg_cost_1, (void *)&set);
@@ -747,11 +748,15 @@ approx_reg_cost (x)
     (&set, 0, i,
      {
        if (! CHEAP_REGNO (i))
-	 cost++;
+	 {
+	   if (i < FIRST_PSEUDO_REGISTER)
+	     hardregs++;
+	   cost++;
+	 }
      });
 
   CLEAR_REG_SET (&set);
-  return cost;
+  return hardregs ? INT_MAX : cost;
 }
 
 /* Return a negative value if an rtx A, whose costs are given by COST_A
@@ -762,8 +767,29 @@ static int
 preferrable (cost_a, regcost_a, cost_b, regcost_b)
      int cost_a, regcost_a, cost_b, regcost_b;
 {
+  /* First, get rid of a cases involving expressions that are entirely
+     unwanted.  */
   if (cost_a != cost_b)
+    {
+      if (cost_a == INT_MAX)
+	return 1;
+      if (cost_b == INT_MAX)
+	return -1;
+    }
+
+  /* Avoid extending lifetimes of hardregs.  */
+  if (regcost_a != regcost_b)
+    {
+      if (regcost_a == INT_MAX)
+	return 1;
+      if (regcost_b == INT_MAX)
+	return -1;
+    }
+
+  /* Normal operation costs take precedence.  */
+  if (cost_a != cost_b)
     return cost_a - cost_b;
+  /* Only if these are identical consider effects on register pressure.  */
   if (regcost_a != regcost_b)
     return regcost_a - regcost_b;
   return 0;
@@ -4874,8 +4900,8 @@ cse_insn (insn, libcall_insn)
       rtx src_const = 0;
       rtx src_related = 0;
       struct table_elt *src_const_elt = 0;
-      int src_cost = 10000, src_eqv_cost = 10000, src_folded_cost = 10000;
-      int src_related_cost = 10000, src_elt_cost = 10000;
+      int src_cost = INT_MAX, src_eqv_cost = INT_MAX, src_folded_cost = INT_MAX;
+      int src_related_cost = INT_MAX, src_elt_cost = INT_MAX;
       int src_regcost, src_eqv_regcost, src_folded_regcost;
       int src_related_regcost, src_elt_regcost;
       /* Set non-zero if we need to call force_const_mem on with the
@@ -5378,7 +5404,7 @@ cse_insn (insn, libcall_insn)
 	      && preferrable (src_folded_cost, src_folded_regcost,
 			      src_elt_cost, src_elt_regcost) <= 0)
 	    {
-	      trial = src_folded, src_folded_cost = 10000;
+	      trial = src_folded, src_folded_cost = INT_MAX;
 	      if (src_folded_force_flag)
 		trial = force_const_mem (mode, trial);
 	    }
@@ -5388,20 +5414,20 @@ cse_insn (insn, libcall_insn)
 				   src_related_cost, src_related_regcost) <= 0
 		   && preferrable (src_cost, src_regcost,
 				   src_elt_cost, src_elt_regcost) <= 0)
-	    trial = src, src_cost = 10000;
+	    trial = src, src_cost = INT_MAX;
 	  else if (preferrable (src_eqv_cost, src_eqv_regcost,
 				src_related_cost, src_related_regcost) <= 0
 		   && preferrable (src_eqv_cost, src_eqv_regcost,
 				   src_elt_cost, src_elt_regcost) <= 0)
-	    trial = copy_rtx (src_eqv_here), src_eqv_cost = 10000;
+	    trial = copy_rtx (src_eqv_here), src_eqv_cost = INT_MAX;
 	  else if (preferrable (src_related_cost, src_related_regcost,
 				src_elt_cost, src_elt_regcost) <= 0)
-  	    trial = copy_rtx (src_related), src_related_cost = 10000;
+  	    trial = copy_rtx (src_related), src_related_cost = INT_MAX;
 	  else
 	    {
 	      trial = copy_rtx (elt->exp);
 	      elt = elt->next_same_value;
-	      src_elt_cost = 10000;
+	      src_elt_cost = INT_MAX;
 	    }
 
 	  /* We don't normally have an insn matching (set (pc) (pc)), so


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