OSDN Git Service

* config/mips/mips-protos.h (mips_initial_elimination_offset): Declare.
[pf3gnuchains/gcc-fork.git] / gcc / unroll.c
index cc38656..a795dcb 100644 (file)
@@ -268,53 +268,6 @@ unroll_loop (loop, insn_count, strength_reduce_p)
       return;
     }
 
-  /* When emitting debugger info, we can't unroll loops with unequal numbers
-     of block_beg and block_end notes, because that would unbalance the block
-     structure of the function.  This can happen as a result of the
-     "if (foo) bar; else break;" optimization in jump.c.  */
-  /* ??? Gcc has a general policy that -g is never supposed to change the code
-     that the compiler emits, so we must disable this optimization always,
-     even if debug info is not being output.  This is rare, so this should
-     not be a significant performance problem.  */
-
-  if (1 /* write_symbols != NO_DEBUG */)
-    {
-      int block_begins = 0;
-      int block_ends = 0;
-
-      for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
-       {
-         if (GET_CODE (insn) == NOTE)
-           {
-             if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
-               block_begins++;
-             else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
-               block_ends++;
-             if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
-                 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
-               {
-                 /* Note, would be nice to add code to unroll EH
-                    regions, but until that time, we punt (don't
-                    unroll).  For the proper way of doing it, see
-                    expand_inline_function.  */
-
-                 if (loop_dump_stream)
-                   fprintf (loop_dump_stream,
-                            "Unrolling failure: cannot unroll EH regions.\n");
-                 return;
-               }
-           }
-       }
-
-      if (block_begins != block_ends)
-       {
-         if (loop_dump_stream)
-           fprintf (loop_dump_stream,
-                    "Unrolling failure: Unbalanced block notes.\n");
-         return;
-       }
-    }
-
   /* Determine type of unroll to perform.  Depends on the number of iterations
      and the size of the loop.  */
 
@@ -721,8 +674,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
 
   if (max_labelno > 0)
     {
-      map->label_map = (rtx *) xmalloc (max_labelno * sizeof (rtx));
-
+      map->label_map = (rtx *) xcalloc (max_labelno, sizeof (rtx));
       local_label = (char *) xcalloc (max_labelno, sizeof (char));
     }
 
@@ -1074,7 +1026,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
              LABEL_NUSES (labels[0])++;
            }
 
-         sequence = gen_sequence ();
+         sequence = get_insns ();
          end_sequence ();
          loop_insn_hoist (loop, sequence);
 
@@ -1636,7 +1588,7 @@ calculate_giv_inc (pattern, src_insn, regno)
          rtx second_part = XEXP (increment, 1);
          enum rtx_code code = GET_CODE (increment);
 
-         increment = find_last_value (XEXP (increment, 0), 
+         increment = find_last_value (XEXP (increment, 0),
                                       &src_insn, NULL_RTX, 0);
          /* Don't need the last insn anymore.  */
          delete_related_insns (get_last_insn ());
@@ -1733,7 +1685,7 @@ final_reg_note_copy (notesp, map)
   while (*notesp)
     {
       rtx note = *notesp;
-      
+
       if (GET_CODE (note) == INSN_LIST)
        {
          /* Sometimes, we have a REG_WAS_0 note that points to a
@@ -1806,12 +1758,6 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
 
   start_sequence ();
 
-  /* Emit a NOTE_INSN_DELETED to force at least two insns onto the sequence.
-     Else gen_sequence could return a raw pattern for a jump which we pass
-     off to emit_insn_before (instead of emit_jump_insn_before) which causes
-     a variety of losing behaviors later.  */
-  emit_note (0, NOTE_INSN_DELETED);
-
   insn = copy_start;
   do
     {
@@ -2047,6 +1993,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
              copy = emit_insn (pattern);
            }
          REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
+         INSN_SCOPE (copy) = INSN_SCOPE (insn);
 
 #ifdef HAVE_cc0
          /* If this insn is setting CC0, it may need to look at
@@ -2093,6 +2040,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
          pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
          copy = emit_jump_insn (pattern);
          REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
+         INSN_SCOPE (copy) = INSN_SCOPE (insn);
 
          if (JUMP_LABEL (insn))
            {
@@ -2216,6 +2164,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
          pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
          copy = emit_call_insn (pattern);
          REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
+         INSN_SCOPE (copy) = INSN_SCOPE (insn);
          SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
 
          /* Because the USAGE information potentially contains objects other
@@ -2323,7 +2272,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
   if (final_label && LABEL_NUSES (final_label) > 0)
     emit_label (final_label);
 
-  tem = gen_sequence ();
+  tem = get_insns ();
   end_sequence ();
   loop_insn_emit_before (loop, 0, insert_before, tem);
 }
@@ -2580,7 +2529,7 @@ find_splittable_regs (loop, unroll_type, unroll_number)
                  rtx tem = gen_reg_rtx (bl->biv->mode);
 
                  record_base_value (REGNO (tem), bl->biv->add_val, 0);
-                 loop_insn_hoist (loop, 
+                 loop_insn_hoist (loop,
                                   gen_move_insn (tem, bl->biv->src_reg));
 
                  if (loop_dump_stream)
@@ -3001,7 +2950,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
                      ret = force_operand (v->new_reg, tem);
                      if (ret != tem)
                        emit_move_insn (tem, ret);
-                     sequence = gen_sequence ();
+                     sequence = get_insns ();
                      end_sequence ();
                      loop_insn_hoist (loop, sequence);
 
@@ -3300,7 +3249,8 @@ final_giv_value (loop, v)
 
   /* Try to calculate the final value as a function of the biv it depends
      upon.  The only exit from the loop must be the fall through at the bottom
-     (otherwise it may not have its final value when the loop exits).  */
+     and the insn that sets the giv must be executed on every iteration
+     (otherwise the giv may not have its final value when the loop exits).  */
 
   /* ??? Can calculate the final giv value by subtracting off the
      extra biv increments times the giv's mult_val.  The loop must have
@@ -3308,7 +3258,8 @@ final_giv_value (loop, v)
      to be known.  */
 
   if (n_iterations != 0
-      && ! loop->exit_count)
+      && ! loop->exit_count
+      && v->always_executed)
     {
       /* ?? It is tempting to use the biv's value here since these insns will
         be put after the loop, and hence the biv will have its final value
@@ -3357,7 +3308,7 @@ final_giv_value (loop, v)
                    tem = expand_simple_binop (GET_MODE (tem), MINUS, tem,
                                               biv->add_val, NULL_RTX, 0,
                                               OPTAB_LIB_WIDEN);
-                   seq = gen_sequence ();
+                   seq = get_insns ();
                    end_sequence ();
                    loop_insn_sink (loop, seq);
                  }
@@ -3595,7 +3546,7 @@ loop_iterations (loop)
                  && INSN_LUID (JUMP_LABEL (temp)) < INSN_LUID (loop->cont))
                {
                  if (loop_dump_stream)
-                   fprintf 
+                   fprintf
                      (loop_dump_stream,
                       "Loop iterations: Loop has multiple back edges.\n");
                  return 0;