OSDN Git Service

libiberty:
[pf3gnuchains/gcc-fork.git] / gcc / loop.c
index 37f0f26..7eb4d0d 100644 (file)
@@ -253,8 +253,9 @@ static int iv_add_mult_cost PARAMS ((rtx, rtx, rtx, rtx));
 
 static rtx loop_insn_emit_after PARAMS((const struct loop *, basic_block, 
                                        rtx, rtx));
-static rtx loop_insn_emit_before PARAMS((const struct loop *, basic_block, 
-                                        rtx, rtx));
+static rtx loop_call_insn_emit_before PARAMS((const struct loop *,
+                                             basic_block, rtx, rtx));
+static rtx loop_call_insn_hoist PARAMS((const struct loop *, rtx));
 static rtx loop_insn_sink_or_swim PARAMS((const struct loop *, rtx));
 
 static void loop_dump_aux PARAMS ((const struct loop *, FILE *, int));
@@ -1885,13 +1886,13 @@ move_movables (loop, movables, threshold, insn_count)
                              if (GET_CODE (temp) == CALL_INSN
                                  && fn_address != 0
                                  && reg_referenced_p (fn_reg, body))
-                               emit_insn_after (gen_move_insn (fn_reg,
-                                                               fn_address),
-                                                fn_address_insn);
+                               loop_insn_emit_after (loop, 0, fn_address_insn,
+                                                     gen_move_insn
+                                                     (fn_reg, fn_address));
 
                              if (GET_CODE (temp) == CALL_INSN)
                                {
-                                 i1 = emit_call_insn_before (body, loop_start);
+                                 i1 = loop_call_insn_hoist (loop, body);
                                  /* Because the USAGE information potentially
                                     contains objects other than hard registers
                                     we need to copy it.  */
@@ -1937,7 +1938,7 @@ move_movables (loop, movables, threshold, insn_count)
                        }
                      else if (GET_CODE (p) == CALL_INSN)
                        {
-                         i1 = emit_call_insn_before (PATTERN (p), loop_start);
+                         i1 = loop_call_insn_hoist (loop, PATTERN (p));
                          /* Because the USAGE information potentially
                             contains objects other than hard registers
                             we need to copy it.  */
@@ -4052,8 +4053,8 @@ loop_givs_rescan (loop, bl, reg_map)
        {
          /* Not replaceable; emit an insn to set the original giv reg from
             the reduced giv, same as above.  */
-         emit_insn_after (gen_move_insn (v->dest_reg, v->new_reg),
-                          v->insn);
+         loop_insn_emit_after (loop, 0, v->insn, 
+                               gen_move_insn (v->dest_reg, v->new_reg));
        }
       
       /* When a loop is reversed, givs which depend on the reversed
@@ -4134,17 +4135,19 @@ loop_giv_reduce_benefit (loop, bl, v, test_reg)
       && benefit > 0
       && GET_CODE (v->mult_val) == CONST_INT)
     {
+      int size = GET_MODE_SIZE (GET_MODE (v->mem));
+
       if (HAVE_POST_INCREMENT
-         && INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+         && INTVAL (v->mult_val) == size)
        benefit += add_cost * bl->biv_count;
       else if (HAVE_PRE_INCREMENT
-              && INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+              && INTVAL (v->mult_val) == size)
        benefit += add_cost * bl->biv_count;
       else if (HAVE_POST_DECREMENT
-              && -INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+              && -INTVAL (v->mult_val) == size)
        benefit += add_cost * bl->biv_count;
       else if (HAVE_PRE_DECREMENT
-              && -INTVAL (v->mult_val) == GET_MODE_SIZE (GET_MODE (v->mem)))
+              && -INTVAL (v->mult_val) == size)
        benefit += add_cost * bl->biv_count;
     }
 #endif
@@ -6481,7 +6484,8 @@ check_ext_dependant_givs (bl, loop_info)
   int ze_ok = 0, se_ok = 0, info_ok = 0;
   enum machine_mode biv_mode = GET_MODE (bl->biv->src_reg);
   HOST_WIDE_INT start_val;
-  unsigned HOST_WIDE_INT u_end_val, u_start_val;
+  unsigned HOST_WIDE_INT u_end_val = 0;
+  unsigned HOST_WIDE_INT u_start_val = 0;
   rtx incr = pc_rtx;
   struct induction *v;
 
@@ -7255,6 +7259,7 @@ check_dbra_loop (loop, insn_count)
       if (bl->giv_count == 0 && ! loop->exit_count)
        {
          rtx bivreg = regno_reg_rtx[bl->regno];
+         struct iv_class *blt;
 
          /* If there are no givs for this biv, and the only exit is the
             fall through at the end of the loop, then
@@ -7291,6 +7296,14 @@ check_dbra_loop (loop, insn_count)
                    break;
                  }
              }
+
+         /* A biv has uses besides counting if it is used to set another biv.  */
+         for (blt = ivs->list; blt; blt = blt->next)
+           if (blt->init_set && reg_mentioned_p (bivreg, SET_SRC (blt->init_set)))
+             {
+               no_use_except_counting = 0;
+               break;
+             }
        }
 
       if (no_use_except_counting)
@@ -7563,7 +7576,7 @@ check_dbra_loop (loop, insn_count)
              tem = gen_sequence ();
              end_sequence ();
 
-             p = emit_insn_before (tem, bl->biv->insn);
+             p = loop_insn_emit_before (loop, 0, bl->biv->insn, tem);
              delete_insn (bl->biv->insn);
 
              /* Update biv info to reflect its new status.  */
@@ -7941,8 +7954,9 @@ maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where_bb, where_insn)
                   into a register (it will be a loop invariant.)  */
                tem = gen_reg_rtx (GET_MODE (v->new_reg));
 
-               emit_insn_before (gen_move_insn (tem, copy_rtx (v->add_val)),
-                                 where_insn);
+               loop_insn_emit_before (loop, 0, where_insn,
+                                      gen_move_insn (tem,
+                                                     copy_rtx (v->add_val)));
 
                /* Substitute the new register for its invariant value in
                   the compare expression.  */
@@ -8300,7 +8314,6 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
   rtx tem;
   rtx op0, op1;
   int reverse_code = 0;
-  int did_reverse_condition = 0;
   enum machine_mode mode;
 
   code = GET_CODE (cond);
@@ -8309,10 +8322,9 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
   op1 = XEXP (cond, 1);
 
   if (reverse)
-    {
-      code = reverse_condition (code);
-      did_reverse_condition ^= 1;
-    }
+    code = reversed_comparison_code (cond, insn);
+  if (code == UNKNOWN)
+    return 0;
 
   if (earliest)
     *earliest = insn;
@@ -8363,13 +8375,19 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
 
       if ((prev = prev_nonnote_insn (prev)) == 0
          || GET_CODE (prev) != INSN
-         || FIND_REG_INC_NOTE (prev, 0)
-         || (set = single_set (prev)) == 0)
+         || FIND_REG_INC_NOTE (prev, 0))
+       break;
+
+      set = set_of (op0, prev);
+
+      if (set
+         && (GET_CODE (set) != SET
+             || !rtx_equal_p (SET_DEST (set), op0)))
        break;
 
       /* If this is setting OP0, get what it sets it to if it looks
         relevant.  */
-      if (rtx_equal_p (SET_DEST (set), op0))
+      if (set)
        {
          enum machine_mode inner_mode = GET_MODE (SET_DEST (set));
 
@@ -8429,10 +8447,6 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
                       || mode == VOIDmode || inner_mode == VOIDmode))
 
            {
-             /* We might have reversed a LT to get a GE here.  But this wasn't
-                actually the comparison of data, so we don't flag that we
-                have had to reverse the condition.  */
-             did_reverse_condition ^= 1;
              reverse_code = 1;
              x = SET_SRC (set);
            }
@@ -8450,10 +8464,9 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
            code = GET_CODE (x);
          if (reverse_code)
            {
-             code = reverse_condition (code);
+             code = reversed_comparison_code (x, prev);
              if (code == UNKNOWN)
                return 0;
-             did_reverse_condition ^= 1;
              reverse_code = 0;
            }
 
@@ -8516,15 +8529,6 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
        }
     }
 
-  /* If this was floating-point and we reversed anything other than an
-     EQ or NE or (UN)ORDERED, return zero.  */
-  if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
-      && did_reverse_condition
-      && code != NE && code != EQ && code != UNORDERED && code != ORDERED
-      && ! flag_fast_math
-      && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
-    return 0;
-
 #ifdef HAVE_cc0
   /* Never return CC0; return zero instead.  */
   if (op0 == cc0_rtx)
@@ -8813,7 +8817,7 @@ load_mems (loop)
   rtx end_label;
   /* Nonzero if the next instruction may never be executed.  */
   int next_maybe_never = 0;
-  int last_max_reg = max_reg_num ();
+  unsigned int last_max_reg = max_reg_num ();
 
   if (loop_info->mems_idx == 0)
     return;
@@ -9075,7 +9079,7 @@ load_mems (loop)
              /* Store the memory immediately after END, which is
                 the NOTE_LOOP_END.  */
              set = gen_move_insn (copy_rtx (mem), reg);
-             emit_insn_after (set, label);
+             loop_insn_emit_after (loop, 0, label, set);
            }
 
          if (loop_dump_stream)
@@ -9245,7 +9249,7 @@ try_swap_copy_prop (loop, replacement, regno)
      unsigned int regno;
 {
   rtx insn;
-  rtx set;
+  rtx set = NULL_RTX;
   unsigned int new_regno;
 
   new_regno = REGNO (replacement);
@@ -9255,7 +9259,7 @@ try_swap_copy_prop (loop, replacement, regno)
        insn = next_insn_in_loop (loop, insn))
     {
       /* Search for the insn that copies REGNO to NEW_REGNO?  */
-      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+      if (INSN_P (insn)
          && (set = single_set (insn))
          && GET_CODE (SET_DEST (set)) == REG
          && REGNO (SET_DEST (set)) == new_regno
@@ -9264,7 +9268,7 @@ try_swap_copy_prop (loop, replacement, regno)
        break;
     }
 
-  if (insn != NULL_RTX)
+  if (set)
     {
       rtx prev_insn;
       rtx prev_set;
@@ -9275,7 +9279,7 @@ try_swap_copy_prop (loop, replacement, regno)
 
       prev_insn = PREV_INSN (insn);
 
-      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+      if (INSN_P (insn)
          && (prev_set = single_set (prev_insn))
          && GET_CODE (SET_DEST (prev_set)) == REG
          && REGNO (SET_DEST (prev_set)) == regno)
@@ -9459,7 +9463,7 @@ loop_insn_emit_after (loop, where_bb, where_insn, pattern)
    in basic block WHERE_BB (ignored in the interim) within the loop
    otherwise hoist PATTERN into the loop pre-header.  */
 
-static rtx
+rtx
 loop_insn_emit_before (loop, where_bb, where_insn, pattern)
      const struct loop *loop;
      basic_block where_bb ATTRIBUTE_UNUSED;
@@ -9472,6 +9476,20 @@ loop_insn_emit_before (loop, where_bb, where_insn, pattern)
 }
 
 
+/* Emit call insn for PATTERN before WHERE_INSN in basic block
+   WHERE_BB (ignored in the interim) within the loop.  */
+
+static rtx
+loop_call_insn_emit_before (loop, where_bb, where_insn, pattern)
+     const struct loop *loop ATTRIBUTE_UNUSED;
+     basic_block where_bb ATTRIBUTE_UNUSED;
+     rtx where_insn;
+     rtx pattern;
+{
+  return emit_call_insn_before (pattern, where_insn);
+}
+
+
 /* Hoist insn for PATTERN into the loop pre-header.  */
 
 rtx
@@ -9483,6 +9501,17 @@ loop_insn_hoist (loop, pattern)
 }
 
 
+/* Hoist call insn for PATTERN into the loop pre-header.  */
+
+static rtx
+loop_call_insn_hoist (loop, pattern)
+     const struct loop *loop;
+     rtx pattern;
+{
+  return loop_call_insn_emit_before (loop, 0, loop->start, pattern);
+}
+
+
 /* Sink insn for PATTERN after the loop end.  */
 
 rtx