Kill recombine_givs.
authorBernd Schmidt <bernds@redhat.co.uk>
Tue, 19 Sep 2000 16:01:13 +0000 (09:01 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 19 Sep 2000 16:01:13 +0000 (09:01 -0700)
From-SVN: r36536

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

index c0a425351c1c5665dbf379a1e9de4f5095dda05c..4000a6c69867d61f93a02d51cc52fe8ea617fc5e 100644 (file)
@@ -1,3 +1,27 @@
+2000-09-19  Bernd Schmidt  <bernds@redhat.co.uk>
+
+       Undo most of the Wed Jan 27 23:39:53 1999 patch:
+       * loop.h (struct induction): Delete members derived, ix and last_use.
+       (struct loop_ivs): Delete members first_increment_giv and
+       last_increment_giv.
+       * loop.c (verify_dominator, find_life_end, cmp_recombine_givs_stats,
+       recombine_givs): Delete functions.
+       (find_and_verify_loops): Don't initialize cont_dominator.
+       (strength_reduce): Lose code to try to find bivs that can be
+       expressed as givs of another biv, and to convert biv increments
+       into givs.
+       Lose loop_scan_start variable, always use loop->scan_start.
+       Don't call recombine_givs.  Don't handle derived givs.
+       (record_giv): Don't initialize derived and last_use fields.
+       (biv_eliminiation_giv_has_0_offset): Lose code to handle derived
+       givs.
+       * unroll.c (derived_regs): Delete static variable.
+       (unroll_loop): Don't initialize it.
+       (copy_loop_body): Lose code to handle derived givs.
+       (find_splittable_givs): Don't check for givs made from biv
+       increments.
+       Don't set derived_regs.
+
 2000-09-19  Bernd Schmidt  <bernds@redhat.co.uk>
 
        Fix misapplied earlier patch:
 
 Mon 18-Sep-2000 22:12:44 BST  Neil Booth  <NeilB@earthling.net>
 
-        * cpp.texi: Update documentation, including some clarifications,
+       * cpp.texi: Update documentation, including some clarifications,
        the treatment of various newline combinations, and space between
        backslash and newline.
 
index a48cbec26450b77f8bbfff40290a2b3b1753689c..b53b148eadf7986c7d8f2fd87ead2b9cbe888528 100644 (file)
@@ -159,7 +159,6 @@ FILE *loop_dump_stream;
 
 /* Forward declarations.  */
 
-static void verify_dominator PARAMS ((struct loop *));
 static void find_and_verify_loops PARAMS ((rtx, struct loops *));
 static void mark_loop_jump PARAMS ((rtx, struct loop *));
 static void prescan_loop PARAMS ((struct loop *));
@@ -219,13 +218,8 @@ static int consec_sets_giv PARAMS ((const struct loop *, int, rtx,
 static int check_dbra_loop PARAMS ((struct loop *, int));
 static rtx express_from_1 PARAMS ((rtx, rtx, rtx));
 static rtx combine_givs_p PARAMS ((struct induction *, struct induction *));
+static int cmp_combine_givs_stats PARAMS ((const PTR, const PTR));
 static void combine_givs PARAMS ((struct loop_regs *, struct iv_class *));
-struct recombine_givs_stats;
-static int find_life_end PARAMS ((const struct loop *, rtx,
-                                 struct recombine_givs_stats *,
-                                 rtx, rtx));
-static void recombine_givs PARAMS ((const struct loop *, struct iv_class *,
-                                   int));
 static int product_cheap_p PARAMS ((rtx, rtx));
 static int maybe_eliminate_biv PARAMS ((const struct loop *, struct iv_class *,
                                        int, int, int));
@@ -2431,58 +2425,6 @@ prescan_loop (loop)
     }
 }
 \f
-/* LOOP->CONT_DOMINATOR is now the last label between the loop start
-   and the continue note that is a the destination of a (cond)jump after
-   the continue note.  If there is any (cond)jump between the loop start
-   and what we have so far as LOOP->CONT_DOMINATOR that has a
-   target between LOOP->CONT_DOMINATOR and the continue note, move
-   LOOP->CONT_DOMINATOR forward to that label; if a jump's
-   destination cannot be determined, clear LOOP->CONT_DOMINATOR.  */
-
-static void
-verify_dominator (loop)
-     struct loop *loop;
-{
-  rtx insn;
-
-  if (! loop->cont_dominator)
-    /* This can happen for an empty loop, e.g. in
-       gcc.c-torture/compile/920410-2.c  */
-    return;
-  if (loop->cont_dominator == const0_rtx)
-    {
-      loop->cont_dominator = 0;
-      return;
-    }
-  for (insn = loop->start; insn != loop->cont_dominator;
-       insn = NEXT_INSN (insn))
-    {
-      if (GET_CODE (insn) == JUMP_INSN
-         && GET_CODE (PATTERN (insn)) != RETURN)
-       {
-         rtx label = JUMP_LABEL (insn);
-         int label_luid;
-
-         /* If it is not a jump we can easily understand or for
-            which we do not have jump target information in the JUMP_LABEL
-            field (consider ADDR_VEC and ADDR_DIFF_VEC insns), then clear
-            LOOP->CONT_DOMINATOR.  */
-         if (! any_condjump_p (insn)
-             || label == NULL_RTX)
-           {
-             loop->cont_dominator = NULL_RTX;
-             return;
-           }
-
-         label_luid = INSN_LUID (label);
-         if (label_luid < INSN_LUID (loop->cont)
-             && (label_luid
-                 > INSN_LUID (loop->cont)))
-           loop->cont_dominator = label;
-       }
-    }
-}
-
 /* Scan the function looking for loops.  Record the start and end of each loop.
    Also mark as invalid loops any loops that contain a setjmp or are branched
    to from outside the loop.  */
@@ -2553,51 +2495,12 @@ find_and_verify_loops (f, loops)
              abort ();
 
            current_loop->end = insn;
-           verify_dominator (current_loop);
            current_loop = current_loop->outer;
            break;
 
          default:
            break;
          }
-      /* If for any loop, this is a jump insn between the NOTE_INSN_LOOP_CONT
-        and NOTE_INSN_LOOP_END notes, update loop->cont_dominator.  */
-      else if (GET_CODE (insn) == JUMP_INSN
-              && GET_CODE (PATTERN (insn)) != RETURN
-              && current_loop)
-       {
-         rtx label = JUMP_LABEL (insn);
-
-         if (! any_condjump_p (insn))
-           label = NULL_RTX;
-
-         loop = current_loop;
-         do
-           {
-             /* First see if we care about this loop.  */
-             if (loop->cont && loop->cont_dominator != const0_rtx)
-               {
-                 /* If the jump destination is not known, invalidate
-                    loop->cont_dominator.  */
-                 if (! label)
-                   loop->cont_dominator = const0_rtx;
-                 else
-                   /* Check if the destination is between loop start and
-                      cont.  */
-                   if ((INSN_LUID (label)
-                        < INSN_LUID (loop->cont))
-                       && (INSN_LUID (label) > INSN_LUID (loop->start))
-                       /* And if there is no later destination already
-                          recorded.  */
-                       && (! loop->cont_dominator
-                           || (INSN_LUID (label)
-                               > INSN_LUID (loop->cont_dominator))))
-                     loop->cont_dominator = label;
-               }
-             loop = loop->outer;
-           }
-         while (loop);
-       }
 
       /* Note that this will mark the NOTE_INSN_LOOP_END note as being in the
         enclosing loop, but this doesn't matter.  */
@@ -3750,11 +3653,9 @@ strength_reduce (loop, insn_count, flags)
   int call_seen;
   rtx test;
   rtx end_insert_before;
-  int n_extra_increment;
   int unrolled_insn_copies = 0;
   rtx loop_start = loop->start;
   rtx loop_end = loop->end;
-  rtx loop_scan_start = loop->scan_start;
   rtx test_reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
 
   VARRAY_INT_INIT (ivs->reg_iv_type, max_reg_before_loop, "reg_iv_type");
@@ -3907,362 +3808,12 @@ strength_reduce (loop, insn_count, flags)
                }
            }
        }
-      else
-       {
-         struct iv_class *bl2 = 0;
-         rtx increment = NULL_RTX;
-
-         /* Biv initial value is not a simple move.  If it is the sum of
-            another biv and a constant, check if both bivs are incremented
-            in lockstep.  Then we are actually looking at a giv.
-            For simplicity, we only handle the case where there is but a
-            single increment, and the register is not used elsewhere.  */
-         if (bl->biv_count == 1
-             && bl->regno < max_reg_before_loop
-             && uid_luid[REGNO_LAST_UID (bl->regno)] < INSN_LUID (loop_end)
-             && GET_CODE (src) == PLUS
-             && GET_CODE (XEXP (src, 0)) == REG
-             && CONSTANT_P (XEXP (src, 1))
-             && ((increment = biv_total_increment (bl)) != NULL_RTX))
-           {
-             unsigned int regno = REGNO (XEXP (src, 0));
-
-             for (bl2 = ivs->loop_iv_list; bl2; bl2 = bl2->next)
-               if (bl2->regno == regno)
-                 break;
-           }
-
-         /* Now, can we transform this biv into a giv?  */
-         if (bl2
-             && bl2->biv_count == 1
-             && rtx_equal_p (increment, biv_total_increment (bl2))
-             /* init_insn is only set to insns that are before loop_start
-                without any intervening labels.  */
-             && ! reg_set_between_p (bl2->biv->src_reg,
-                                     PREV_INSN (bl->init_insn), loop_start)
-             /* The register from BL2 must be set before the register from
-                BL is set, or we must be able to move the latter set after
-                the former set.  Currently there can't be any labels
-                in-between when biv_total_increment returns nonzero both times
-                but we test it here in case some day some real cfg analysis
-                gets used to set always_computable.  */
-             && (loop_insn_first_p (bl2->biv->insn, bl->biv->insn)
-                 ? no_labels_between_p (bl2->biv->insn, bl->biv->insn)
-                 : (! reg_used_between_p (bl->biv->src_reg, bl->biv->insn,
-                                          bl2->biv->insn)
-                    && no_jumps_between_p (bl->biv->insn, bl2->biv->insn)))
-             && validate_change (bl->biv->insn,
-                                 &SET_SRC (single_set (bl->biv->insn)),
-                                 copy_rtx (src), 0))
-           {
-             rtx dominator = loop->cont_dominator;
-             rtx giv = bl->biv->src_reg;
-             rtx giv_insn = bl->biv->insn;
-             rtx after_giv = NEXT_INSN (giv_insn);
-
-             if (loop_dump_stream)
-               fprintf (loop_dump_stream, "is giv of biv %d\n", bl2->regno);
-             /* Let this giv be discovered by the generic code.  */
-             REG_IV_TYPE (ivs, bl->regno) = UNKNOWN_INDUCT;
-             ivs->reg_biv_class[bl->regno] = (struct iv_class *) NULL_PTR;
-             /* We can get better optimization if we can move the giv setting
-                before the first giv use.  */
-             if (dominator
-                 && ! loop_insn_first_p (dominator, loop_scan_start)
-                 && ! reg_set_between_p (bl2->biv->src_reg, loop_start,
-                                         dominator)
-                 && ! reg_used_between_p (giv, loop_start, dominator)
-                 && ! reg_used_between_p (giv, giv_insn, loop_end))
-               {
-                 rtx p;
-                 rtx next;
-
-                 for (next = NEXT_INSN (dominator);; next = NEXT_INSN (next))
-                   {
-                     if (GET_CODE (next) == JUMP_INSN
-                         || (INSN_P (next)
-                             && insn_dependent_p (giv_insn, next)))
-                       break;
-#ifdef HAVE_cc0
-                     if (! INSN_P (next) || ! sets_cc0_p (PATTERN (next)))
-#endif
-                       dominator = next;
-                   }
-                 if (loop_dump_stream)
-                   fprintf (loop_dump_stream, "move after insn %d\n",
-                            INSN_UID (dominator));
-                 /* Avoid problems with luids by actually moving the insn
-                    and adjusting all luids in the range.  */
-                 reorder_insns (giv_insn, giv_insn, dominator);
-                 for (p = dominator; INSN_UID (p) >= max_uid_for_loop;)
-                   p = PREV_INSN (p);
-                 compute_luids (giv_insn, after_giv, INSN_LUID (p));
-                 /* If the only purpose of the init insn is to initialize
-                    this giv, delete it.  */
-                 if (single_set (bl->init_insn)
-                     && ! reg_used_between_p (giv, bl->init_insn, loop_start))
-                   delete_insn (bl->init_insn);
-               }
-             else if (! loop_insn_first_p (bl2->biv->insn, bl->biv->insn))
-               {
-                 rtx p = PREV_INSN (giv_insn);
-                 while (INSN_UID (p) >= max_uid_for_loop)
-                   p = PREV_INSN (p);
-                 reorder_insns (giv_insn, giv_insn, bl2->biv->insn);
-                 compute_luids (after_giv, NEXT_INSN (giv_insn),
-                                INSN_LUID (p));
-               }
-             /* Remove this biv from the chain.  */
-             *backbl = bl->next;
-           }
-
-         /* If we can't make it a giv,
-            let biv keep initial value of "itself".  */
-         else if (loop_dump_stream)
-           fprintf (loop_dump_stream, "is complex\n");
-       }
+      /* If we can't make it a giv,
+       let biv keep initial value of "itself".  */
+      else if (loop_dump_stream)
+       fprintf (loop_dump_stream, "is complex\n");
     }
 
-  /* If a biv is unconditionally incremented several times in a row, convert
-     all but the last increment into a giv.  */
-
-  /* Get an upper bound for the number of registers
-     we might have after all bivs have been processed.  */
-  ivs->first_increment_giv = max_reg_num ();
-  for (n_extra_increment = 0, bl = ivs->loop_iv_list; bl; bl = bl->next)
-    n_extra_increment += bl->biv_count - 1;
-
-  /* If the loop contains volatile memory references do not allow any
-     replacements to take place, since this could loose the volatile
-     markers.  */
-  if (n_extra_increment  && ! loop_info->has_volatile)
-    {
-      unsigned int nregs = ivs->first_increment_giv + n_extra_increment;
-
-      /* Reallocate ivs->reg_iv_type and ivs->reg_iv_info.  */
-      VARRAY_GROW (ivs->reg_iv_type, nregs);
-      VARRAY_GROW (ivs->reg_iv_info, nregs);
-
-      for (bl = ivs->loop_iv_list; bl; bl = bl->next)
-       {
-         struct induction **vp, *v, *next;
-         int biv_dead_after_loop = 0;
-
-         /* The biv increments lists are in reverse order.  Fix this
-             first.  */
-         for (v = bl->biv, bl->biv = 0; v; v = next)
-           {
-             next = v->next_iv;
-             v->next_iv = bl->biv;
-             bl->biv = v;
-           }
-
-         /* We must guard against the case that an early exit between v->insn
-            and next->insn leaves the biv live after the loop, since that
-            would mean that we'd be missing an increment for the final
-            value.  The following test to set biv_dead_after_loop is like
-            the first part of the test to set bl->eliminable.
-            We don't check here if we can calculate the final value, since
-            this can't succeed if we already know that there is a jump
-            between v->insn and next->insn, yet next->always_executed is
-            set and next->maybe_multiple is cleared.  Such a combination
-            implies that the jump destination is outside the loop.
-            If we want to make this check more sophisticated, we should
-            check each branch between v->insn and next->insn individually
-            to see if the biv is dead at its destination.  */
-
-         if (uid_luid[REGNO_LAST_UID (bl->regno)] < INSN_LUID (loop_end)
-             && bl->init_insn
-             && INSN_UID (bl->init_insn) < max_uid_for_loop
-             && (uid_luid[REGNO_FIRST_UID (bl->regno)]
-                 >= INSN_LUID (bl->init_insn))
-#ifdef HAVE_decrement_and_branch_until_zero
-             && ! bl->nonneg
-#endif
-             && ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
-           biv_dead_after_loop = 1;
-
-         for (vp = &bl->biv, next = *vp; v = next, next = v->next_iv;)
-           {
-             HOST_WIDE_INT offset;
-             rtx set, add_val, old_reg, dest_reg, last_use_insn, note;
-             int old_regno, new_regno;
-             rtx next_loc_insn;
-
-             if (! v->always_executed
-                 || v->maybe_multiple
-                 || GET_CODE (v->add_val) != CONST_INT
-                 || ! next->always_executed
-                 || next->maybe_multiple
-                 || ! CONSTANT_P (next->add_val)
-                 || v->mult_val != const1_rtx
-                 || next->mult_val != const1_rtx
-                 || ! (biv_dead_after_loop
-                       || no_jumps_between_p (v->insn, next->insn)))
-               {
-                 vp = &v->next_iv;
-                 continue;
-               }
-             offset = INTVAL (v->add_val);
-             set = single_set (v->insn);
-             add_val = plus_constant (next->add_val, offset);
-             old_reg = v->dest_reg;
-             dest_reg = gen_reg_rtx (v->mode);
-
-             /* Unlike ivs->reg_iv_type / ivs->reg_iv_info, the other
-                three arrays have been allocated with some slop
-                space, so we may not actually need to reallocate
-                them.  If we do, the following if statement will be
-                executed just once in this loop.  */
-             if ((unsigned) max_reg_num () > regs->n_times_set->num_elements)
-               {
-                 /* Grow all the remaining arrays.  */
-                 VARRAY_GROW (regs->set_in_loop, nregs);
-                 VARRAY_GROW (regs->n_times_set, nregs);
-                 VARRAY_GROW (regs->may_not_optimize, nregs);
-                 VARRAY_GROW (regs->single_usage, nregs);
-               }
-
-             /* Some bivs are incremented with a multi-insn sequence.
-                The first insn contains the add.  */
-             next_loc_insn = next->insn;
-             while (NOTE_P (next_loc_insn)
-                    || ! loc_mentioned_in_p (next->location,
-                                             PATTERN (next_loc_insn)))
-               next_loc_insn = PREV_INSN (next_loc_insn);
-
-             if (next_loc_insn == v->insn)
-               abort ();
-
-             if (! validate_change (next_loc_insn, next->location, add_val, 0))
-               {
-                 vp = &v->next_iv;
-                 continue;
-               }
-
-             /* Here we can try to eliminate the increment by combining
-                it into the uses.  */
-
-             /* Set last_use_insn so that we can check against it.  */
-
-             for (last_use_insn = v->insn, p = NEXT_INSN (v->insn);
-                  p != next_loc_insn;
-                  p = next_insn_in_loop (loop, p))
-               {
-                 if (!INSN_P (p))
-                   continue;
-                 if (reg_mentioned_p (old_reg, PATTERN (p)))
-                   {
-                     last_use_insn = p;
-                   }
-               }
-
-             /* If we can't get the LUIDs for the insns, we can't
-                calculate the lifetime.  This is likely from unrolling
-                of an inner loop, so there is little point in making this
-                a DEST_REG giv anyways.  */
-             if (INSN_UID (v->insn) >= max_uid_for_loop
-                 || INSN_UID (last_use_insn) >= max_uid_for_loop
-                 || ! validate_change (v->insn, &SET_DEST (set), dest_reg, 0))
-               {
-                 /* Change the increment at NEXT back to what it was.  */
-                 if (! validate_change (next_loc_insn, next->location,
-                     next->add_val, 0))
-                   abort ();
-                 vp = &v->next_iv;
-                 continue;
-               }
-             next->add_val = add_val;
-             v->dest_reg = dest_reg;
-             v->giv_type = DEST_REG;
-             v->location = &SET_SRC (set);
-             v->cant_derive = 0;
-             v->combined_with = 0;
-             v->maybe_dead = 0;
-             v->derive_adjustment = 0;
-             v->same = 0;
-             v->ignore = 0;
-             v->new_reg = 0;
-             v->final_value = 0;
-             v->same_insn = 0;
-             v->auto_inc_opt = 0;
-             v->unrolled = 0;
-             v->shared = 0;
-             v->derived_from = 0;
-             v->always_computable = 1;
-             v->always_executed = 1;
-             v->replaceable = 1;
-             v->no_const_addval = 0;
-
-             old_regno = REGNO (old_reg);
-             new_regno = REGNO (dest_reg);
-             VARRAY_INT (regs->set_in_loop, old_regno)--;
-             VARRAY_INT (regs->set_in_loop, new_regno) = 1;
-             VARRAY_INT (regs->n_times_set, old_regno)--;
-             VARRAY_INT (regs->n_times_set, new_regno) = 1;
-             VARRAY_CHAR (regs->may_not_optimize, new_regno) = 0;
-
-             REG_IV_TYPE (ivs, new_regno) = GENERAL_INDUCT;
-             REG_IV_INFO (ivs, new_regno) = v;
-
-             /* If next_insn has a REG_EQUAL note that mentiones OLD_REG,
-                it must be replaced.  */
-             note = find_reg_note (next->insn, REG_EQUAL, NULL_RTX);
-             if (note && reg_mentioned_p (old_reg, XEXP (note, 0)))
-               XEXP (note, 0) = copy_rtx (SET_SRC (single_set (next->insn)));
-
-             /* Remove the increment from the list of biv increments,
-                and record it as a giv.  */
-             *vp = next;
-             bl->biv_count--;
-             v->next_iv = bl->giv;
-             bl->giv = v;
-             bl->giv_count++;
-             v->benefit = rtx_cost (SET_SRC (set), SET);
-             bl->total_benefit += v->benefit;
-
-             /* Now replace the biv with DEST_REG in all insns between
-                the replaced increment and the next increment, and
-                remember the last insn that needed a replacement.  */
-             for (last_use_insn = v->insn, p = NEXT_INSN (v->insn);
-                  p != next_loc_insn;
-                  p = next_insn_in_loop (loop, p))
-               {
-                 rtx note;
-
-                 if (! INSN_P (p))
-                   continue;
-                 if (reg_mentioned_p (old_reg, PATTERN (p)))
-                   {
-                     last_use_insn = p;
-                     if (! validate_replace_rtx (old_reg, dest_reg, p))
-                       abort ();
-                   }
-                 for (note = REG_NOTES (p); note; note = XEXP (note, 1))
-                   {
-                     if (GET_CODE (note) == EXPR_LIST)
-                       XEXP (note, 0)
-                         = replace_rtx (XEXP (note, 0), old_reg, dest_reg);
-                   }
-               }
-
-             v->last_use = last_use_insn;
-             v->lifetime = INSN_LUID (last_use_insn) - INSN_LUID (v->insn);
-             /* If the lifetime is zero, it means that this register is really
-                a dead store.  So mark this as a giv that can be ignored.
-                This will not prevent the biv from being eliminated.  */
-             if (v->lifetime == 0)
-               v->ignore = 1;
-
-             if (loop_dump_stream)
-               fprintf (loop_dump_stream,
-                        "Increment %d of biv %d converted to giv %d.\n\n",
-                        INSN_UID (v->insn), old_regno, new_regno);
-           }
-       }
-    }
-  ivs->last_increment_giv = max_reg_num () - 1;
-
   /* Search the loop for general induction variables.  */
 
   for_each_insn_in_loop (loop, check_insn_for_givs);
@@ -4308,7 +3859,6 @@ strength_reduce (loop, insn_count, flags)
       int benefit;
       int all_reduced;
       rtx final_value = 0;
-      unsigned int nregs;
 
       /* Test whether it will be possible to eliminate this biv
         provided all givs are reduced.  This is possible if either
@@ -4487,16 +4037,8 @@ strength_reduce (loop, insn_count, flags)
              || (v->same && v->same->ignore))
            continue;
 
-         if (v->last_use)
-           {
-             struct induction *v1;
-
-             for (v1 = bl->giv; v1; v1 = v1->next_iv)
-               if (v->last_use == v1->insn)
-                 v->maybe_dead = 1;
-           }
-         else if (v->giv_type == DEST_REG
-                  && REGNO_FIRST_UID (REGNO (v->dest_reg)) == INSN_UID (v->insn))
+         if (v->giv_type == DEST_REG
+             && REGNO_FIRST_UID (REGNO (v->dest_reg)) == INSN_UID (v->insn))
            {
              struct induction *v1;
 
@@ -4506,25 +4048,6 @@ strength_reduce (loop, insn_count, flags)
            }
        }
 
-      /* Now that we know which givs will be reduced, try to rearrange the
-         combinations to reduce register pressure.
-         recombine_givs calls find_life_end, which needs ivs->reg_iv_type and
-        ivs->reg_iv_info to be valid for all pseudos.  We do the necessary
-        reallocation here since it allows to check if there are still
-        more bivs to process.  */
-      nregs = max_reg_num ();
-      if (nregs > ivs->reg_iv_type->num_elements)
-       {
-         /* If there are still more bivs to process, allocate some slack
-            space so that we're not constantly reallocating these arrays.  */
-         if (bl->next)
-           nregs += nregs / 4;
-         /* Reallocate ivs->reg_iv_type and ivs->reg_iv_info.  */
-         VARRAY_GROW (ivs->reg_iv_type, nregs);
-         VARRAY_GROW (ivs->reg_iv_info, nregs);
-       }
-      recombine_givs (loop, bl, flags & LOOP_UNROLL);
-
       /* Reduce each giv that we decided to reduce.  */
 
       for (v = bl->giv; v; v = v->next_iv)
@@ -4539,45 +4062,6 @@ strength_reduce (loop, insn_count, flags)
              if (! v->new_reg)
                v->new_reg = gen_reg_rtx (v->mode);
 
-             if (v->derived_from)
-               {
-                 struct induction *d = v->derived_from;
-
-                 /* In case d->dest_reg is not replaceable, we have
-                    to replace it in v->insn now.  */
-                 if (! d->new_reg)
-                   d->new_reg = gen_reg_rtx (d->mode);
-                 PATTERN (v->insn)
-                   = replace_rtx (PATTERN (v->insn), d->dest_reg, d->new_reg);
-                 PATTERN (v->insn)
-                   = replace_rtx (PATTERN (v->insn), v->dest_reg, v->new_reg);
-                 /* For each place where the biv is incremented, add an
-                    insn to set the new, reduced reg for the giv.
-                    We used to do this only for biv_count != 1, but
-                    this fails when there is a giv after a single biv
-                    increment, e.g. when the last giv was expressed as
-                    pre-decrement.  */
-                 for (tv = bl->biv; tv; tv = tv->next_iv)
-                   {
-                     /* We always emit reduced giv increments before the
-                        biv increment when bl->biv_count != 1.  So by
-                        emitting the add insns for derived givs after the
-                        biv increment, they pick up the updated value of
-                        the reduced giv.
-                        If the reduced giv is processed with
-                        auto_inc_opt == 1, then it is incremented earlier
-                        than the biv, hence we'll still pick up the right
-                        value.
-                        If it's processed with auto_inc_opt == -1,
-                        that implies that the biv increment is before the
-                        first reduced giv's use.  The derived giv's lifetime
-                        is after the reduced giv's lifetime, hence in this
-                        case, the biv increment doesn't matter.  */
-                     emit_insn_after (copy_rtx (PATTERN (v->insn)), tv->insn);
-                   }
-                 continue;
-               }
-
 #ifdef AUTO_INC_DEC
              /* If the target has auto-increment addressing modes, and
                 this is an address giv, then try to put the increment
@@ -4625,11 +4109,11 @@ strength_reduce (loop, insn_count, flags)
                  /* Check for case where increment is before the address
                     giv.  Do this test in "loop order".  */
                  else if ((INSN_LUID (v->insn) > INSN_LUID (bl->biv->insn)
-                           && (INSN_LUID (v->insn) < INSN_LUID (loop_scan_start)
+                           && (INSN_LUID (v->insn) < INSN_LUID (loop->scan_start)
                                || (INSN_LUID (bl->biv->insn)
-                                   > INSN_LUID (loop_scan_start))))
-                          || (INSN_LUID (v->insn) < INSN_LUID (loop_scan_start)
-                              && (INSN_LUID (loop_scan_start)
+                                   > INSN_LUID (loop->scan_start))))
+                          || (INSN_LUID (v->insn) < INSN_LUID (loop->scan_start)
+                              && (INSN_LUID (loop->scan_start)
                                   < INSN_LUID (bl->biv->insn))))
                    auto_inc_opt = -1;
                  else
@@ -5364,8 +4848,6 @@ record_giv (loop, v, insn, src_reg, dest_reg, mult_val, add_val, ext_val,
   v->auto_inc_opt = 0;
   v->unrolled = 0;
   v->shared = 0;
-  v->derived_from = 0;
-  v->last_use = 0;
 
   /* The v->always_computable field is used in update_giv_derive, to
      determine whether a giv can be used to derive another giv.  For a
@@ -6157,8 +5639,6 @@ general_induction_var (loop, x, src_reg, add_val, mult_val, ext_val,
 
 static rtx sge_plus PARAMS ((enum machine_mode, rtx, rtx));
 static rtx sge_plus_constant PARAMS ((rtx, rtx));
-static int cmp_combine_givs_stats PARAMS ((const PTR, const PTR));
-static int cmp_recombine_givs_stats PARAMS ((const PTR, const PTR));
 
 static rtx
 simplify_giv_expr (loop, x, ext_val, benefit)
@@ -7373,444 +6853,6 @@ restart:
   free (can_combine);
 }
 \f
-struct recombine_givs_stats
-{
-  int giv_number;
-  int start_luid, end_luid;
-};
-
-/* Used below as comparison function for qsort.  We want a ascending luid
-   when scanning the array starting at the end, thus the arguments are
-   used in reverse.  */
-static int
-cmp_recombine_givs_stats (xp, yp)
-     const PTR xp;
-     const PTR yp;
-{
-  const struct recombine_givs_stats * const x =
-    (const struct recombine_givs_stats *) xp;
-  const struct recombine_givs_stats * const y =
-    (const struct recombine_givs_stats *) yp;
-  int d;
-  d = y->start_luid - x->start_luid;
-  /* Stabilize the sort.  */
-  if (!d)
-    d = y->giv_number - x->giv_number;
-  return d;
-}
-
-/* Scan X, which is a part of INSN, for the end of life of a giv.  Also
-   look for the start of life of a giv where the start has not been seen
-   yet to unlock the search for the end of its life.
-   Only consider givs that belong to BIV.
-   Return the total number of lifetime ends that have been found.  */
-static int
-find_life_end (loop, x, stats, insn, biv)
-     const struct loop *loop;
-     rtx x, insn, biv;
-     struct recombine_givs_stats *stats;
-{
-  struct loop_ivs *ivs = LOOP_IVS (loop);
-  enum rtx_code code;
-  const char *fmt;
-  int i, j;
-  int retval;
-
-  code = GET_CODE (x);
-  switch (code)
-    {
-    case SET:
-      {
-       rtx reg = SET_DEST (x);
-       if (GET_CODE (reg) == REG)
-         {
-           int regno = REGNO (reg);
-           struct induction *v = REG_IV_INFO (ivs, regno);
-
-           if (REG_IV_TYPE (ivs, regno) == GENERAL_INDUCT
-               && ! v->ignore
-               && v->src_reg == biv
-               && stats[v->ix].end_luid <= 0)
-             {
-               /* If we see a 0 here for end_luid, it means that we have
-                  scanned the entire loop without finding any use at all.
-                  We must not predicate this code on a start_luid match
-                  since that would make the test fail for givs that have
-                  been hoisted out of inner loops.  */
-               if (stats[v->ix].end_luid == 0)
-                 {
-                   stats[v->ix].end_luid = stats[v->ix].start_luid;
-                   return 1 + find_life_end (loop, SET_SRC (x), stats,
-                                             insn, biv);
-                 }
-               else if (stats[v->ix].start_luid == INSN_LUID (insn))
-                 stats[v->ix].end_luid = 0;
-             }
-           return find_life_end (loop, SET_SRC (x), stats, insn, biv);
-         }
-       break;
-      }
-    case REG:
-      {
-       int regno = REGNO (x);
-       struct induction *v = REG_IV_INFO (ivs, regno);
-
-       if (REG_IV_TYPE (ivs, regno) == GENERAL_INDUCT
-           && ! v->ignore
-           && v->src_reg == biv
-           && stats[v->ix].end_luid == 0)
-         {
-           while (INSN_UID (insn) >= max_uid_for_loop)
-             insn = NEXT_INSN (insn);
-           stats[v->ix].end_luid = INSN_LUID (insn);
-           return 1;
-         }
-       return 0;
-      }
-    case LABEL_REF:
-    case CONST_DOUBLE:
-    case CONST_INT:
-    case CONST:
-      return 0;
-    default:
-      break;
-    }
-  fmt = GET_RTX_FORMAT (code);
-  retval = 0;
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-       retval += find_life_end (loop, XEXP (x, i), stats, insn, biv);
-
-      else if (fmt[i] == 'E')
-       for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-         retval += find_life_end (loop, XVECEXP (x, i, j), stats, insn, biv);
-    }
-  return retval;
-}
-
-/* For each giv that has been combined with another, look if
-   we can combine it with the most recently used one instead.
-   This tends to shorten giv lifetimes, and helps the next step:
-   try to derive givs from other givs.  */
-static void
-recombine_givs (loop, bl, unroll_p)
-     const struct loop *loop;
-     struct iv_class *bl;
-     int unroll_p;
-{
-  struct loop_regs *regs = LOOP_REGS (loop);
-  struct induction *v, **giv_array, *last_giv;
-  struct recombine_givs_stats *stats;
-  int giv_count;
-  int i, rescan;
-  int ends_need_computing;
-
-  for (giv_count = 0, v = bl->giv; v; v = v->next_iv)
-    {
-      if (! v->ignore)
-       giv_count++;
-    }
-  giv_array
-    = (struct induction **) xmalloc (giv_count * sizeof (struct induction *));
-  stats = (struct recombine_givs_stats *) xmalloc (giv_count * sizeof *stats);
-
-  /* Initialize stats and set up the ix field for each giv in stats to name
-     the corresponding index into stats.  */
-  for (i = 0, v = bl->giv; v; v = v->next_iv)
-    {
-      rtx p;
-
-      if (v->ignore)
-       continue;
-      giv_array[i] = v;
-      stats[i].giv_number = i;
-      /* If this giv has been hoisted out of an inner loop, use the luid of
-        the previous insn.  */
-      for (p = v->insn; INSN_UID (p) >= max_uid_for_loop; )
-       p = PREV_INSN (p);
-      stats[i].start_luid = INSN_LUID (p);
-      i++;
-    }
-
-  qsort (stats, giv_count, sizeof (*stats), cmp_recombine_givs_stats);
-
-  /* Set up the ix field for each giv in stats to name
-     the corresponding index into stats, and
-     do the actual most-recently-used recombination.  */
-  for (last_giv = 0, i = giv_count - 1; i >= 0; i--)
-    {
-      v = giv_array[stats[i].giv_number];
-      v->ix = i;
-      if (v->same)
-       {
-         struct induction *old_same = v->same;
-         rtx new_combine;
-
-         /* combine_givs_p actually says if we can make this transformation.
-            The other tests are here only to avoid keeping a giv alive
-            that could otherwise be eliminated.  */
-         if (last_giv
-             && ((old_same->maybe_dead && ! old_same->combined_with)
-                 || ! last_giv->maybe_dead
-                 || last_giv->combined_with)
-             && (new_combine = combine_givs_p (last_giv, v)))
-           {
-             old_same->combined_with--;
-             v->new_reg = new_combine;
-             v->same = last_giv;
-             last_giv->combined_with++;
-             /* No need to update lifetimes / benefits here since we have
-                already decided what to reduce.  */
-
-             if (loop_dump_stream)
-               {
-                 fprintf (loop_dump_stream,
-                          "giv at %d recombined with giv at %d as ",
-                          INSN_UID (v->insn), INSN_UID (last_giv->insn));
-                 print_rtl (loop_dump_stream, v->new_reg);
-                 putc ('\n', loop_dump_stream);
-               }
-             continue;
-           }
-         v = v->same;
-       }
-      else if (v->giv_type != DEST_REG)
-       continue;
-      if (! last_giv
-         || (last_giv->maybe_dead && ! last_giv->combined_with)
-         || ! v->maybe_dead
-         || v->combined_with)
-       last_giv = v;
-    }
-
-  ends_need_computing = 0;
-  /* For each DEST_REG giv, compute lifetime starts, and try to compute
-     lifetime ends from regscan info.  */
-  for (i = giv_count - 1; i >= 0; i--)
-    {
-      v = giv_array[stats[i].giv_number];
-      if (v->ignore)
-       continue;
-      if (v->giv_type == DEST_ADDR)
-       {
-         /* Loop unrolling of an inner loop can even create new DEST_REG
-            givs.  */
-         rtx p;
-         for (p = v->insn; INSN_UID (p) >= max_uid_for_loop;)
-           p = PREV_INSN (p);
-         stats[i].start_luid = stats[i].end_luid = INSN_LUID (p);
-         if (p != v->insn)
-           stats[i].end_luid++;
-       }
-      else /* v->giv_type == DEST_REG */
-       {
-         if (v->last_use)
-           {
-             stats[i].start_luid = INSN_LUID (v->insn);
-             stats[i].end_luid = INSN_LUID (v->last_use);
-           }
-         else if (INSN_UID (v->insn) >= max_uid_for_loop)
-           {
-             rtx p;
-             /* This insn has been created by loop optimization on an inner
-                loop.  We don't have a proper start_luid that will match
-                when we see the first set.  But we do know that there will
-                be no use before the set, so we can set end_luid to 0 so that
-                we'll start looking for the last use right away.  */
-             for (p = PREV_INSN (v->insn); INSN_UID (p) >= max_uid_for_loop; )
-               p = PREV_INSN (p);
-             stats[i].start_luid = INSN_LUID (p);
-             stats[i].end_luid = 0;
-             ends_need_computing++;
-           }
-         else
-           {
-             int regno = REGNO (v->dest_reg);
-             int count = VARRAY_INT (regs->n_times_set, regno) - 1;
-             rtx p = v->insn;
-
-             /* Find the first insn that sets the giv, so that we can verify
-                if this giv's lifetime wraps around the loop.  We also need
-                the luid of the first setting insn in order to detect the
-                last use properly.  */
-             while (count)
-               {
-                 p = prev_nonnote_insn (p);
-                 if (reg_set_p (v->dest_reg, p))
-                   count--;
-               }
-
-             stats[i].start_luid = INSN_LUID (p);
-             if (stats[i].start_luid > uid_luid[REGNO_FIRST_UID (regno)])
-               {
-                 stats[i].end_luid = -1;
-                 ends_need_computing++;
-               }
-             else
-               {
-                 stats[i].end_luid = uid_luid[REGNO_LAST_UID (regno)];
-                 if (stats[i].end_luid > INSN_LUID (loop->end))
-                   {
-                     stats[i].end_luid = -1;
-                     ends_need_computing++;
-                   }
-               }
-           }
-       }
-    }
-
-  /* If the regscan information was unconclusive for one or more DEST_REG
-     givs, scan the all insn in the loop to find out lifetime ends.  */
-  if (ends_need_computing)
-    {
-      rtx biv = bl->biv->src_reg;
-      rtx p = loop->end;
-
-      do
-       {
-         if (p == loop->start)
-           p = loop->end;
-         p = PREV_INSN (p);
-         if (! INSN_P (p))
-           continue;
-         ends_need_computing -= find_life_end (loop, PATTERN (p),
-                                               stats, p, biv);
-       }
-      while (ends_need_computing);
-    }
-
-  /* Set start_luid back to the last insn that sets the giv.  This allows
-     more combinations.  */
-  for (i = giv_count - 1; i >= 0; i--)
-    {
-      v = giv_array[stats[i].giv_number];
-      if (v->ignore)
-       continue;
-      if (INSN_UID (v->insn) < max_uid_for_loop)
-       stats[i].start_luid = INSN_LUID (v->insn);
-    }
-
-  /* Now adjust lifetime ends by taking combined givs into account.  */
-  for (i = giv_count - 1; i >= 0; i--)
-    {
-      unsigned luid;
-      int j;
-
-      v = giv_array[stats[i].giv_number];
-      if (v->ignore)
-       continue;
-      if (v->same && ! v->same->ignore)
-       {
-         j = v->same->ix;
-         luid = stats[i].start_luid;
-         /* Use unsigned arithmetic to model loop wrap-around.  */
-         if (luid - stats[j].start_luid
-             > (unsigned) stats[j].end_luid - stats[j].start_luid)
-           stats[j].end_luid = luid;
-       }
-    }
-
-  qsort (stats, giv_count, sizeof (*stats), cmp_recombine_givs_stats);
-
-  /* Try to derive DEST_REG givs from previous DEST_REG givs with the
-     same mult_val and non-overlapping lifetime.  This reduces register
-     pressure.
-     Once we find a DEST_REG giv that is suitable to derive others from,
-     we set last_giv to this giv, and try to derive as many other DEST_REG
-     givs from it without joining overlapping lifetimes.  If we then
-     encounter a DEST_REG giv that we can't derive, we set rescan to the
-     index for this giv (unless rescan is already set).
-     When we are finished with the current LAST_GIV (i.e. the inner loop
-     terminates), we start again with rescan, which then becomes the new
-     LAST_GIV.  */
-  for (i = giv_count - 1; i >= 0; i = rescan)
-    {
-      int life_start = 0, life_end = 0;
-
-      for (last_giv = 0, rescan = -1; i >= 0; i--)
-       {
-         rtx sum;
-
-         v = giv_array[stats[i].giv_number];
-         if (v->giv_type != DEST_REG || v->derived_from || v->same)
-           continue;
-         if (! last_giv)
-           {
-             /* Don't use a giv that's likely to be dead to derive
-                others - that would be likely to keep that giv alive.  */
-             if (! v->maybe_dead || v->combined_with)
-               {
-                 last_giv = v;
-                 life_start = stats[i].start_luid;
-                 life_end = stats[i].end_luid;
-               }
-             continue;
-           }
-         /* Use unsigned arithmetic to model loop wrap around.  */
-         if (((unsigned) stats[i].start_luid - life_start
-              >= (unsigned) life_end - life_start)
-             && ((unsigned) stats[i].end_luid - life_start
-                 > (unsigned) life_end - life_start)
-             /*  Check that the giv insn we're about to use for deriving
-                 precedes all uses of that giv.  Note that initializing the
-                 derived giv would defeat the purpose of reducing register
-                 pressure.
-                 ??? We could arrange to move the insn.  */
-             && ((unsigned) stats[i].end_luid - INSN_LUID (loop->start)
-                  > (unsigned) stats[i].start_luid - INSN_LUID (loop->start))
-             && rtx_equal_p (last_giv->mult_val, v->mult_val)
-             /* ??? Could handle libcalls, but would need more logic.  */
-             && ! find_reg_note (v->insn, REG_RETVAL, NULL_RTX)
-             /* We would really like to know if for any giv that v
-                is combined with, v->insn or any intervening biv increment
-                dominates that combined giv.  However, we
-                don't have this detailed control flow information.
-                N.B. since last_giv will be reduced, it is valid
-                anywhere in the loop, so we don't need to check the
-                validity of last_giv.
-                We rely here on the fact that v->always_executed implies that
-                there is no jump to someplace else in the loop before the
-                giv insn, and hence any insn that is executed before the
-                giv insn in the loop will have a lower luid.  */
-             && (v->always_executed || ! v->combined_with)
-             && (sum = express_from (last_giv, v))
-             /* Make sure we don't make the add more expensive.  ADD_COST
-                doesn't take different costs of registers and constants into
-                account, so compare the cost of the actual SET_SRCs.  */
-             && (rtx_cost (sum, SET)
-                 <= rtx_cost (SET_SRC (single_set (v->insn)), SET))
-             /* ??? unroll can't understand anything but reg + const_int
-                sums.  It would be cleaner to fix unroll.  */
-             && ((GET_CODE (sum) == PLUS
-                  && GET_CODE (XEXP (sum, 0)) == REG
-                  && GET_CODE (XEXP (sum, 1)) == CONST_INT)
-                 || ! unroll_p)
-             && validate_change (v->insn, &PATTERN (v->insn),
-                                 gen_rtx_SET (VOIDmode, v->dest_reg, sum), 0))
-           {
-             v->derived_from = last_giv;
-             life_end = stats[i].end_luid;
-
-             if (loop_dump_stream)
-               {
-                 fprintf (loop_dump_stream,
-                          "giv at %d derived from %d as ",
-                          INSN_UID (v->insn), INSN_UID (last_giv->insn));
-                 print_rtl (loop_dump_stream, sum);
-                 putc ('\n', loop_dump_stream);
-               }
-           }
-         else if (rescan < 0)
-           rescan = i;
-       }
-    }
-
-  /* Clean up.  */
-  free (giv_array);
-  free (stats);
-}
-\f
 /* EMIT code before INSERT_BEFORE to set REG = B * M + A.  */
 
 void
@@ -8695,22 +7737,6 @@ biv_elimination_giv_has_0_offset (biv, giv, insn)
              && loop_insn_first_p (insn, giv->insn))))
     return 0;
 
-  /* If the giv V was derived from another giv, and INSN does
-     not occur between the giv insn and the biv insn, then we'd
-     have to adjust the value used here.  This is rare, so we don't
-     bother to make this possible.  */
-  if (giv->derived_from
-      && ! (giv->always_executed
-           && loop_insn_first_p (giv->insn, insn)
-           && loop_insn_first_p (insn, biv->insn)))
-    return 0;
-  if (giv->same
-      && giv->same->derived_from
-      && ! (giv->same->always_executed
-           && loop_insn_first_p (giv->same->insn, insn)
-           && loop_insn_first_p (insn, biv->insn)))
-    return 0;
-
   return 1;
 }
 
index 15c0c3c9cc0b76c4bfb5d0dc8d509adc915d56b2..a1aaf82e099d29461fceb57a63e86b00423fea70 100644 (file)
@@ -133,14 +133,10 @@ 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
                                   for later use.  */
-  int ix;                      /* Used by recombine_givs, as n index into
-                                  the stats array.  */
   struct induction *same_insn; /* If there are multiple identical givs in
                                   the same insn, then all but one have this
                                   field set, and they all point to the giv
@@ -201,12 +197,6 @@ struct loop_ivs
   /* The head of a list which links together (via the next field)
      every iv class for the current loop.  */
   struct iv_class *loop_iv_list;
-
-  /* Givs made from biv increments are always splittable for loop
-     unrolling.  Since there is no regscan info for them, we have to
-     keep track of them separately.  */
-  unsigned int first_increment_giv;
-  unsigned int last_increment_giv;
 };
 
 struct loop_regs
index d37423f23d30b55c4ba35b193be152fdf9121ec8..c1a488dc770b6b7fab3f2fedd1fbadf651173bfa 100644 (file)
@@ -189,10 +189,6 @@ static struct induction **addr_combined_regs;
 
 static rtx *splittable_regs;
 
-/* Indexed by register number, if this is a splittable induction variable,
-   this indicates if it was made from a derived giv.  */
-static char *derived_regs;
-
 /* Indexed by register number, if this is a splittable induction variable,
    then this will hold the number of instructions in the loop that modify
    the induction variable.  Used to ensure that only the last insn modifying
@@ -806,7 +802,6 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
      to access the splittable_regs[] and addr_combined_regs[] arrays.  */
 
   splittable_regs = (rtx *) xcalloc (maxregnum, sizeof (rtx));
-  derived_regs = (char *) xcalloc (maxregnum, sizeof (char));
   splittable_regs_updates = (int *) xcalloc (maxregnum, sizeof (int));
   addr_combined_regs
     = (struct induction **) xcalloc (maxregnum, sizeof (struct induction *));
@@ -872,14 +867,6 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
                           r);
              }
          }
-      /* Givs that have been created from multiple biv increments always have
-        local registers.  */
-      for (r = ivs->first_increment_giv; r <= ivs->last_increment_giv; r++)
-       {
-         local_regno[r] = 1;
-         if (loop_dump_stream)
-           fprintf (loop_dump_stream, "Marked reg %d as local\n", r);
-       }
     }
 
   /* If this loop requires exit tests when unrolled, check to see if we
@@ -1346,7 +1333,6 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
     }
   free (map->insn_map);
   free (splittable_regs);
-  free (derived_regs);
   free (splittable_regs_updates);
   free (addr_combined_regs);
   free (local_regno);
@@ -1792,8 +1778,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
                 we might accidentally delete insns generated immediately
                 below by emit_unrolled_add.  */
 
-             if (! derived_regs[regno])
-               giv_inc = calculate_giv_inc (set, insn, regno);
+             giv_inc = calculate_giv_inc (set, insn, regno);
 
              /* Now find all address giv's that were combined with this
                 giv 'v'.  */
@@ -1880,23 +1865,12 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
              dest_reg_was_split = 1;
 
              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);
-               }
-             else
-               {
-                 giv_src_reg = giv_dest_reg;
-                 /* Compute the increment value for the giv, if it wasn't
-                    already computed above.  */
-                 if (giv_inc == 0)
-                   giv_inc = calculate_giv_inc (set, insn, regno);
-               }
+             giv_src_reg = giv_dest_reg;
+             /* Compute the increment value for the giv, if it wasn't
+                already computed above.  */
+             if (giv_inc == 0)
+               giv_inc = calculate_giv_inc (set, insn, regno);
+
              src_regno = REGNO (giv_src_reg);
 
              if (unroll_type == UNROLL_COMPLETELY)
@@ -2726,10 +2700,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
              /* Line above always fails if INSN was moved by loop opt.  */
              || (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))]
                  >= INSN_LUID (loop->end)))
-         /* Givs made from biv increments are missed by the above test, so
-            test explicitly for them.  */
-         && (REGNO (v->dest_reg) < ivs->first_increment_giv
-             || REGNO (v->dest_reg) > ivs->last_increment_giv)
          && ! (final_value = v->final_value))
        continue;
 
@@ -2831,7 +2801,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                }
 
              splittable_regs[REGNO (v->new_reg)] = value;
-             derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
            }
          else
            {
@@ -2891,25 +2860,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                  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
-                        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);
-                     new_reg = replace_rtx (new_reg, same->dest_reg,
-                                            same->new_reg);
-                   }
-
                  /* 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.  */
@@ -3017,17 +2967,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                                 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);
-                     v->new_reg = replace_rtx (v->new_reg, v->same->dest_reg,
-                                               v->same->new_reg);
-                   }
-
                }
 
              /* Store the value of dest_reg into the insn.  This sharing
@@ -3050,7 +2989,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                     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_from != 0;
 
                  /* Make it appear to depend upon itself, so that the
                     giv will be properly split in the main loop above.  */
@@ -3094,11 +3032,6 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
          if (! v->ignore)
            count = ivs->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;
        }