Fix hard reg cost calculations in CSE; some minor cleanups
authorBernd Schmidt <bernds@redhat.co.uk>
Tue, 12 Sep 2000 08:39:36 +0000 (08:39 +0000)
committerBernd Schmidt <crux@gcc.gnu.org>
Tue, 12 Sep 2000 08:39:36 +0000 (08:39 +0000)
From-SVN: r36354

gcc/ChangeLog
gcc/cse.c
gcc/loop.c
gcc/rtl.h

index fff0a3152e8af3d089bdf2c988c5c0954bdd9236..48f476b8ac1b1d0ad7347a33b88a3eb439123ed2 100644 (file)
@@ -1,3 +1,18 @@
+2000-09-12  Bernd Schmidt  <bernds@redhat.co.uk>
+
+       * cse.c (approx_reg_cost): If SMALL_REGISTER_CLASSES, return INT_MAX
+       if a reference to non-fixed hardreg is seen.  Otherwise, count hard
+       regs with a higher cost.
+       (preferrable): Deal with cases where either cost or regcost is
+       MAX_COST.
+       (cse_insn): Use MAX_COST rather than 10000.  Always initialize
+       regcost values.
+       (COSTS_N_INSNS): Move definition...
+       * rtl.h: ...here.
+       (MAX_COST): New macro.
+       * loop.c (init_loop): Use COSTS_N_INSNS macro instead of hardcoded
+       constant.
+
 2000-09-11  Mark Mitchell  <mark@codesourcery.com>
 
        * c-common.h (genrtl_clear_out_block): Remove.
index b86843595eac4e0d0bdcdc76d68af5adcdf7f5d0..553ffaec37103e17ed5f596e7673853331a00d34 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -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 MAX_COST.  */
 
 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,16 @@ approx_reg_cost (x)
     (&set, 0, i,
      {
        if (! CHEAP_REGNO (i))
-        cost++;
+        {
+          if (i < FIRST_PSEUDO_REGISTER)
+            hardregs++;
+
+          cost += i < FIRST_PSEUDO_REGISTER ? 2 : 1;
+        }
      });
 
   CLEAR_REG_SET (&set);
-  return cost;
+  return hardregs && SMALL_REGISTER_CLASSES ? MAX_COST : cost;
 }
 
 /* Return a negative value if an rtx A, whose costs are given by COST_A
@@ -762,8 +768,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 == MAX_COST)
+       return 1;
+      if (cost_b == MAX_COST)
+       return -1;
+    }
+
+  /* Avoid extending lifetimes of hardregs.  */
+  if (regcost_a != regcost_b)
+    {
+      if (regcost_a == MAX_COST)
+       return 1;
+      if (regcost_b == MAX_COST)
+       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;
@@ -789,12 +816,6 @@ notreg_cost (x)
          : rtx_cost (x, SET) * 2);
 }
 
-/* Return the right cost to give to an operation
-   to make the cost of the corresponding register-to-register instruction
-   N times that of a fast register-to-register instruction.  */
-
-#define COSTS_N_INSNS(N) ((N) * 2)
-
 /* Return an estimate of the cost of computing rtx X.
    One use is in cse, to decide which expression to keep in the hash table.
    Another is in rtl generation, to pick the cheapest way to multiply.
@@ -4881,8 +4902,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 = MAX_COST, src_eqv_cost = MAX_COST, src_folded_cost = MAX_COST;
+      int src_related_cost = MAX_COST, src_elt_cost = MAX_COST;
       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
@@ -5291,7 +5312,7 @@ cse_insn (insn, libcall_insn)
       if (src)
        {
          if (rtx_equal_p (src, dest))
-           src_cost = -1;
+           src_cost = src_regcost = -1;
          else
            {
              src_cost = COST (src);
@@ -5302,7 +5323,7 @@ cse_insn (insn, libcall_insn)
       if (src_eqv_here)
        {
          if (rtx_equal_p (src_eqv_here, dest))
-           src_eqv_cost = -1;
+           src_eqv_cost = src_eqv_regcost = -1;
          else
            {
              src_eqv_cost = COST (src_eqv_here);
@@ -5313,7 +5334,7 @@ cse_insn (insn, libcall_insn)
       if (src_folded)
        {
          if (rtx_equal_p (src_folded, dest))
-           src_folded_cost = -1;
+           src_folded_cost = src_folded_regcost = -1;
          else
            {
              src_folded_cost = COST (src_folded);
@@ -5324,7 +5345,7 @@ cse_insn (insn, libcall_insn)
       if (src_related)
        {
          if (rtx_equal_p (src_related, dest))
-           src_related_cost = -1;
+           src_related_cost = src_related_regcost = -1;
          else
            {
              src_related_cost = COST (src_related);
@@ -5335,7 +5356,7 @@ cse_insn (insn, libcall_insn)
       /* If this was an indirect jump insn, a known label will really be
         cheaper even though it looks more expensive.  */
       if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
-       src_folded = src_const, src_folded_cost = -1;
+       src_folded = src_const, src_folded_cost = src_folded_regcost -1;
 
       /* Terminate loop when replacement made.  This must terminate since
          the current contents will be tested and will always be valid.  */
@@ -5385,7 +5406,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 = MAX_COST;
              if (src_folded_force_flag)
                trial = force_const_mem (mode, trial);
            }
@@ -5395,20 +5416,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 = MAX_COST;
          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 = MAX_COST;
          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 = MAX_COST;
          else
            {
              trial = copy_rtx (elt->exp);
              elt = elt->next_same_value;
-             src_elt_cost = 10000;
+             src_elt_cost = MAX_COST;
            }
 
          /* We don't normally have an insn matching (set (pc) (pc)), so
index d266ab0c91d991ee32d069041ef45cbba8b2d16a..7d172e9147a0f511c7ea52d4331e6c0789a210d1 100644 (file)
@@ -300,7 +300,7 @@ init_loop ()
 
   reg_address_cost = address_cost (reg, SImode);
 
-  copy_cost = 2;
+  copy_cost = COSTS_N_INSNS (1);
 
   /* Free the objects we just allocated.  */
   obfree (free_point);
index a2f9087f066dc65066ed584039b9cbd49ac27ec4..37acbd5ed819f931601cd18e3ff839f108b439c3 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1633,6 +1633,16 @@ extern void push_obstacks                PARAMS ((struct obstack *,
                                                struct obstack *));
 /* In cse.c */
 struct cse_basic_block_data;
+
+/* Return the right cost to give to an operation
+   to make the cost of the corresponding register-to-register instruction
+   N times that of a fast register-to-register instruction.  */
+#define COSTS_N_INSNS(N) ((N) * 4)
+
+/* Maximum cost of a rtl expression.  This value has the special meaning
+   not to use an rtx with this cost under any circumstances.  */
+#define MAX_COST INT_MAX
+
 extern int rtx_cost                    PARAMS ((rtx, enum rtx_code));
 extern int address_cost                        PARAMS ((rtx, enum machine_mode));
 extern void delete_trivially_dead_insns        PARAMS ((rtx, int));