OSDN Git Service

* loop.h (express_from): Declare.
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Feb 1999 12:48:48 +0000 (12:48 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Feb 1999 12:48:48 +0000 (12:48 +0000)
(struct induction): Replace derived flag with derived_from pointer.
* loop.c (strength_reduce, record_giv, recombine_givs): Likewise.
(express_from): No longer static.
* unroll.c (find_splittable_givs): Replace derived with derived_from.
When processing an address giv with which another giv has been
combined that has also been derived from a third giv, handle like
having combined with the third giv.
Set splittable_regs_updates appropriately for derived givs.

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

gcc/ChangeLog
gcc/loop.c
gcc/loop.h
gcc/unroll.c

index 556f5db..95de3cb 100644 (file)
@@ -1,3 +1,15 @@
+Wed Feb  3 20:44:59 1999  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * loop.h (express_from): Declare.
+       (struct induction): Replace derived flag with derived_from pointer.
+       * loop.c (strength_reduce, record_giv, recombine_givs): Likewise.
+       (express_from): No longer static.
+       * unroll.c (find_splittable_givs): Replace derived with derived_from.
+       When processing an address giv with which another giv has been
+       combined that has also been derived from a third giv, handle like
+       having combined with the third giv.
+       Set splittable_regs_updates appropriately for derived givs.
+
 Wed Feb  3 15:26:58 1999  Gavin Romig-Koch  <gavin@cygnus.com>
 
        * config/mips/mips.md (div_trap_mips16): Remove nop's after branches.
index 2f054fb..c0e7892 100644 (file)
@@ -320,7 +320,6 @@ static int general_induction_var PROTO((rtx, rtx *, rtx *, rtx *, int, int *));
 static int consec_sets_giv PROTO((int, rtx, rtx, rtx, rtx *, rtx *, rtx *));
 static int check_dbra_loop PROTO((rtx, int, rtx, struct loop_info *));
 static rtx express_from_1 PROTO((rtx, rtx, rtx));
-static rtx express_from PROTO((struct induction *, struct induction *));
 static rtx combine_givs_p PROTO((struct induction *, struct induction *));
 static void combine_givs PROTO((struct iv_class *));
 struct recombine_givs_stats;
@@ -4180,7 +4179,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
              v->auto_inc_opt = 0;
              v->unrolled = 0;
              v->shared = 0;
-             v->derived = 0;
+             v->derived_from = 0;
              v->always_computable = 1;
              v->always_executed = 1;
              v->replaceable = 1;
@@ -4622,7 +4621,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
 
              v->new_reg = gen_reg_rtx (v->mode);
 
-             if (v->derived)
+             if (v->derived_from)
                {
                  PATTERN (v->insn)
                    = replace_rtx (PATTERN (v->insn), v->dest_reg, v->new_reg);
@@ -5273,7 +5272,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
   v->auto_inc_opt = 0;
   v->unrolled = 0;
   v->shared = 0;
-  v->derived = 0;
+  v->derived_from = 0;
   v->last_use = 0;
 
   /* The v->always_computable field is used in update_giv_derive, to
@@ -6632,7 +6631,7 @@ express_from_1 (a, b, mult)
   return NULL_RTX;
 }
 
-static rtx
+rtx
 express_from (g1, g2)
      struct induction *g1, *g2;
 {
@@ -7290,7 +7289,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
          rtx sum;
 
          v = giv_array[stats[i].giv_number];
-         if (v->giv_type != DEST_REG || v->derived || v->same)
+         if (v->giv_type != DEST_REG || v->derived_from || v->same)
            continue;
          if (! last_giv)
            {
@@ -7347,7 +7346,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
                                  gen_rtx_SET (GET_MODE (v->dest_reg),
                                               v->dest_reg, sum), 0))
            {
-             v->derived = 1;
+             v->derived_from = last_giv;
              v->new_reg = v->dest_reg;
              life_end = stats[i].end_luid;
 
index f183b9e..50279bb 100644 (file)
@@ -101,8 +101,6 @@ struct induction
                                   initialized in unrolled loop.  */
   unsigned shared : 1;
   unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */
-  unsigned derived : 1;         /* For a giv, 1 if we decided to derive this
-                                  giv from another one.  */
   int lifetime;                        /* Length of life of this giv */
   rtx derive_adjustment;       /* If nonzero, is an adjustment to be
                                   subtracted from add_val when this giv
@@ -115,6 +113,8 @@ struct induction
   struct induction *same;      /* If this giv has been combined with another
                                   giv, this points to the base giv.  The base
                                   giv will have COMBINED_WITH non-zero.  */
+  struct induction *derived_from;/* For a giv, if we decided to derive this
+                                  giv from another one.  */
   HOST_WIDE_INT const_adjust;  /* Used by loop unrolling, when an address giv
                                   is split, and a constant is eliminated from
                                   the address, the -constant is stored here
@@ -226,6 +226,7 @@ extern int first_increment_giv, last_increment_giv;
 int invariant_p PROTO((rtx));
 rtx get_condition_for_loop PROTO((rtx));
 void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx));
+rtx express_from PROTO((struct induction *, struct induction *));
 
 /* Forward declarations for non-static functions declared in stmt.c.  */
 void find_loop_tree_blocks PROTO((void));
index 0d1787c..341b805 100644 (file)
@@ -1794,6 +1794,10 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
              giv_dest_reg = SET_DEST (set);
              if (derived_regs[regno])
                {
+                 /* ??? This relies on SET_SRC (SET) to be of
+                    the form (plus (reg) (const_int)), and thus
+                    forces recombine_givs to restrict the kind
+                    of giv derivations it does before unrolling.  */
                  giv_src_reg = XEXP (SET_SRC (set), 0);
                  giv_inc = XEXP (SET_SRC (set), 1);
                }
@@ -2830,7 +2834,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                }
                
              splittable_regs[REGNO (v->new_reg)] = value;
-             derived_regs[REGNO (v->new_reg)] = v->derived;
+             derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
            }
          else
            {
@@ -2886,17 +2890,36 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                     Emit insn to initialize its value before loop start.  */
 
                  rtx tem = gen_reg_rtx (v->mode);
+                 struct induction *same = v->same;
+                 rtx new_reg = v->new_reg;
                  record_base_value (REGNO (tem), v->add_val, 0);
 
+                 if (same && same->derived_from)
+                   {
+                     /* calculate_giv_inc doesn't work for derived givs.
+                        copy_loop_body works around the problem for the
+                        DEST_REG givs themselves, but it can't handle
+                        DEST_ADDR givs that have been combined with
+                        derived a derived DEST_REG giv.
+                        So Handle V as if the giv from which V->SAME has
+                        been derived has been combined with V.
+                        recombine_givs only derives givs from givs that
+                        are reduced the ordinary, so we need not worry
+                        about same->derived_from being in turn derived.  */
+
+                     same = same->derived_from;
+                     new_reg = express_from (same, v);
+                   }
+
                  /* If the address giv has a constant in its new_reg value,
                     then this constant can be pulled out and put in value,
                     instead of being part of the initialization code.  */
                  
-                 if (GET_CODE (v->new_reg) == PLUS
-                     && GET_CODE (XEXP (v->new_reg, 1)) == CONST_INT)
+                 if (GET_CODE (new_reg) == PLUS
+                     && GET_CODE (XEXP (new_reg, 1)) == CONST_INT)
                    {
                      v->dest_reg
-                       = plus_constant (tem, INTVAL (XEXP (v->new_reg,1)));
+                       = plus_constant (tem, INTVAL (XEXP (new_reg, 1)));
 
                      /* Only succeed if this will give valid addresses.
                         Try to validate both the first and the last
@@ -2907,9 +2930,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                          /* Save the negative of the eliminated const, so
                             that we can calculate the dest_reg's increment
                             value later.  */
-                         v->const_adjust = - INTVAL (XEXP (v->new_reg, 1));
+                         v->const_adjust = - INTVAL (XEXP (new_reg, 1));
 
-                         v->new_reg = XEXP (v->new_reg, 0);
+                         new_reg = XEXP (new_reg, 0);
                          if (loop_dump_stream)
                            fprintf (loop_dump_stream,
                                     "Eliminating constant from giv %d\n",
@@ -2938,6 +2961,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                                 INSN_UID (v->insn));
                      continue;
                    }
+
+                 v->new_reg = new_reg;
+                 v->same = same;
                  
                  /* We set this after the address check, to guarantee that
                     the register will be initialized.  */
@@ -2992,6 +3018,15 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                                 INSN_UID (v->insn));
                      continue;
                    }
+                 if (v->same && v->same->derived_from)
+                   {
+                     /* Handle V as if the giv from which V->SAME has
+                        been derived has been combined with V.  */
+
+                     v->same = v->same->derived_from;
+                     v->new_reg = express_from (v->same, v);
+                   }
+
                }
              
              /* Store the value of dest_reg into the insn.  This sharing
@@ -3014,7 +3049,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
                     Make sure that it's giv is marked as splittable here.  */
                  
                  splittable_regs[REGNO (v->new_reg)] = value;
-                 derived_regs[REGNO (v->new_reg)] = v->derived;
+                 derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
                  
                  /* Make it appear to depend upon itself, so that the
                     giv will be properly split in the main loop above.  */
@@ -3058,6 +3093,11 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
          if (! v->ignore)
            count = reg_biv_class[REGNO (v->src_reg)]->biv_count;
 
+         if (count > 1 && v->derived_from)
+            /* In this case, there is one set where the giv insn was and one
+               set each after each biv increment.  (Most are likely dead.)  */
+           count++;
+
          splittable_regs_updates[REGNO (v->new_reg)] = count;
        }