OSDN Git Service

2009-05-08 Paolo Bonzini <bonzini@gnu.org>
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 May 2009 06:51:12 +0000 (06:51 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 May 2009 06:51:12 +0000 (06:51 +0000)
PR rtl-optimization/33928
        * loop-invariant.c (struct use): Add addr_use_p.
        (struct def): Add n_addr_uses.
        (struct invariant): Add cheap_address.
        (create_new_invariant): Set cheap_address.
        (record_use): Accept df_ref.  Set addr_use_p and update n_addr_uses.
        (record_uses): Pass df_ref to record_use.
        (get_inv_cost): Do not add inv->cost to comp_cost for cheap addresses used
only as such.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147270 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/loop-invariant.c

index abe7059..e959348 100644 (file)
@@ -1,3 +1,15 @@
+2009-05-08  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR rtl-optimization/33928
+        * loop-invariant.c (struct use): Add addr_use_p.
+        (struct def): Add n_addr_uses.
+        (struct invariant): Add cheap_address.
+        (create_new_invariant): Set cheap_address.
+        (record_use): Accept df_ref.  Set addr_use_p and update n_addr_uses.
+        (record_uses): Pass df_ref to record_use.
+        (get_inv_cost): Do not add inv->cost to comp_cost for cheap addresses used
+       only as such.
+
 2009-05-08  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        * config/sh/sh.c: Do not include c-pragma.h.
index 82e1829..3d718b1 100644 (file)
@@ -71,7 +71,7 @@ struct use
 {
   rtx *pos;                    /* Position of the use.  */
   rtx insn;                    /* The insn in that the use occurs.  */
-
+  unsigned addr_use_p;         /* Whether the use occurs in an address.  */
   struct use *next;            /* Next use in the list.  */
 };
 
@@ -82,6 +82,7 @@ struct def
   struct use *uses;            /* The list of uses that are uniquely reached
                                   by it.  */
   unsigned n_uses;             /* Number of such uses.  */
+  unsigned n_addr_uses;                /* Number of uses in addresses.  */
   unsigned invno;              /* The corresponding invariant.  */
 };
 
@@ -111,6 +112,9 @@ struct invariant
   /* Whether to move the invariant.  */
   bool move;
 
+  /* Whether the invariant is cheap when used as an address.  */
+  bool cheap_address;
+
   /* Cost of the invariant.  */
   unsigned cost;
 
@@ -679,9 +683,16 @@ create_new_invariant (struct def *def, rtx insn, bitmap depends_on,
   /* If the set is simple, usually by moving it we move the whole store out of
      the loop.  Otherwise we save only cost of the computation.  */
   if (def)
-    inv->cost = rtx_cost (set, SET, speed);
+    {
+      inv->cost = rtx_cost (set, SET, speed);
+      inv->cheap_address = address_cost (SET_SRC (set), word_mode,
+                                        speed) < COSTS_N_INSNS (1);
+    }
   else
-    inv->cost = rtx_cost (SET_SRC (set), SET, speed);
+    {
+      inv->cost = rtx_cost (SET_SRC (set), SET, speed);
+      inv->cheap_address = false;
+    }
 
   inv->move = false;
   inv->reg = NULL_RTX;
@@ -708,17 +719,19 @@ create_new_invariant (struct def *def, rtx insn, bitmap depends_on,
 /* Record USE at DEF.  */
 
 static void
-record_use (struct def *def, rtx *use, rtx insn)
+record_use (struct def *def, df_ref use)
 {
   struct use *u = XNEW (struct use);
 
-  gcc_assert (REG_P (*use));
-
-  u->pos = use;
-  u->insn = insn;
+  u->pos = DF_REF_REAL_LOC (use);
+  u->insn = DF_REF_INSN (use);
+  u->addr_use_p = (DF_REF_TYPE (use) == DF_REF_REG_MEM_LOAD
+                  && DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE);
   u->next = def->uses;
   def->uses = u;
   def->n_uses++;
+  if (u->addr_use_p)
+    def->n_addr_uses++;
 }
 
 /* Finds the invariants USE depends on and store them to the DEPENDS_ON
@@ -865,14 +878,14 @@ record_uses (rtx insn)
       df_ref use = *use_rec;
       inv = invariant_for_use (use);
       if (inv)
-       record_use (inv->def, DF_REF_REAL_LOC (use), DF_REF_INSN (use));
+       record_use (inv->def, use);
     }
   for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++)
     {
       df_ref use = *use_rec;
       inv = invariant_for_use (use);
       if (inv)
-       record_use (inv->def, DF_REF_REAL_LOC (use), DF_REF_INSN (use));
+       record_use (inv->def, use);
     }
 }
 
@@ -992,7 +1005,9 @@ get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed)
   inv->stamp = actual_stamp;
 
   (*regs_needed)++;
-  (*comp_cost) += inv->cost;
+  if (!inv->cheap_address
+      || inv->def->n_addr_uses < inv->def->n_uses)
+    (*comp_cost) += inv->cost;
 
 #ifdef STACK_REGS
   {