*** empty log message ***
authorRichard Stallman <rms@gnu.org>
Mon, 23 Mar 1992 19:42:32 +0000 (19:42 +0000)
committerRichard Stallman <rms@gnu.org>
Mon, 23 Mar 1992 19:42:32 +0000 (19:42 +0000)
From-SVN: r579

gcc/combine.c
gcc/config/m68k/sun3.h

index a01193214200f97eebc2050e0946c5d6e845c548..ef116ef69a1fca5bd700548cc9716a9ec20616bb 100644 (file)
@@ -114,7 +114,7 @@ static int combine_successes;
 static int total_attempts, total_merges, total_extras, total_successes;
 \f
 /* Vector mapping INSN_UIDs to cuids.
-   The cuids are like uids but increase monononically always.
+   The cuids are like uids but increase monotonically always.
    Combine always uses cuids so that it can compare them.
    But actually renumbering the uids, which we used to do,
    proves to be a bad idea because it makes it hard to compare
@@ -174,7 +174,7 @@ static int previous_num_undos;
 \f
 /* The next group of arrays allows the recording of the last value assigned
    to (hard or pseudo) register n.  We use this information to see if a
-   operation being processed is redundant given the a prior operation peformed
+   operation being processed is redundant given a prior operation performed
    on the register.  For example, an `and' with a constant is redundant if
    all the zero bits are already known to be turned off.
 
@@ -517,7 +517,7 @@ combine_instructions (f, nregs)
 
          /* Finally, see if any of the insns that this insn links to
             explicitly references CC0.  If so, try this insn, that insn,
-            and its prececessor if it sets CC0.  */
+            and its predecessor if it sets CC0.  */
          for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
            if (GET_CODE (XEXP (links, 0)) == INSN
                && GET_CODE (PATTERN (XEXP (links, 0))) == SET
@@ -576,7 +576,7 @@ set_significant (x, set)
        return;
 
       /* If this is a complex assignment, see if we can convert it into a
-        simple assignent.  */
+        simple assignment.  */
       set = expand_field_assignment (set);
       if (SET_DEST (set) == x)
        reg_significant[REGNO (x)]
@@ -682,9 +682,16 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
         It can worsen register allocation, and can even make invalid reload
         insns, since the reg inside may need to be copied from in the
         outside mode, and that may be invalid if it is an fp reg copied in
-        integer mode.  */
+        integer mode.  As a special exception, we can allow this if
+        I3 is simply copying DEST, a REG,  to CC0.  */
       || (GET_CODE (src) == SUBREG
-         && ! MODES_TIEABLE_P (GET_MODE (src), GET_MODE (SUBREG_REG (src))))
+         && ! MODES_TIEABLE_P (GET_MODE (src), GET_MODE (SUBREG_REG (src)))
+#ifdef HAVE_cc0
+         && ! (GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET
+               && SET_DEST (PATTERN (i3)) == cc0_rtx
+               && GET_CODE (dest) == REG && dest == SET_SRC (PATTERN (i3)))
+#endif
+         )
       /* If we couldn't eliminate a field assignment, we can't combine.  */
       || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
       /* Don't combine with an insn that sets a register to itself if it has
@@ -1031,29 +1038,56 @@ try_combine (i3, i2, i1)
       && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
       && GET_CODE (PATTERN (i2)) == PARALLEL
       && ! side_effects_p (SET_DEST (PATTERN (i3)))
+      /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code
+        below would need to check what is inside (and reg_overlap_mentioned_p
+        doesn't support those codes anyway).  Don't allow those destinations;
+        the resulting insn isn't likely to be recognized anyway.  */
+      && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT
+      && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART
       && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)),
                                    SET_DEST (PATTERN (i3)))
       && next_real_insn (i2) == i3)
-    for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
-      if (SET_DEST (XVECEXP (PATTERN (i2), 0, i)) == SET_SRC (PATTERN (i3)))
-       {
-         combine_merges++;
+    {
+      rtx p2 = PATTERN (i2);
+
+      /* Make sure that the destination of I3,
+        which we are going to substitute into one output of I2,
+        is not used within another output of I2.  We must avoid making this:
+        (parallel [(set (mem (reg 69)) ...)
+                   (set (reg 69) ...)])
+        which is not well-defined as to order of actions.
+        (Besides, reload can't handle output reloads for this.)
+
+        The problem can also happen if the dest of I3 is a memory ref,
+        if another dest in I2 is an indirect memory ref.  */
+      for (i = 0; i < XVECLEN (p2, 0); i++)
+       if (GET_CODE (XVECEXP (p2, 0, i)) == SET
+           && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
+                                       SET_DEST (XVECEXP (p2, 0, i))))
+         break;
 
-         subst_insn = i3;
-         subst_low_cuid = INSN_CUID (i2);
+      if (i == XVECLEN (p2, 0))
+       for (i = 0; i < XVECLEN (p2, 0); i++)
+         if (SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
+           {
+             combine_merges++;
 
-         added_sets_2 = 0;
-         i2dest = SET_SRC (PATTERN (i3));
+             subst_insn = i3;
+             subst_low_cuid = INSN_CUID (i2);
 
-         /* Replace the dest in I2 with our dest and make the resulting
-            insn the new pattern for I3.  Then skip to where we
-            validate the pattern.  Everything was set up above.  */
-         SUBST (SET_DEST (XVECEXP (PATTERN (i2), 0, i)), 
-                SET_DEST (PATTERN (i3)));
+             added_sets_2 = 0;
+             i2dest = SET_SRC (PATTERN (i3));
 
-         newpat = PATTERN (i2);
-         goto validate_replacement;
-       }
+             /* Replace the dest in I2 with our dest and make the resulting
+                insn the new pattern for I3.  Then skip to where we
+                validate the pattern.  Everything was set up above.  */
+             SUBST (SET_DEST (XVECEXP (p2, 0, i)), 
+                    SET_DEST (PATTERN (i3)));
+
+             newpat = p2;
+             goto validate_replacement;
+           }
+    }
 
 #ifndef HAVE_cc0
   /* If we have no I1 and I2 looks like:
@@ -1134,7 +1168,7 @@ try_combine (i3, i2, i1)
      output operand.  However, that exception can give rise to insns like
        mov r3,(r3)+
      which is a famous insn on the PDP-11 where the value of r3 used as the
-     source was model-dependant.  Avoid this sort of thing.  */
+     source was model-dependent.  Avoid this sort of thing.  */
 
 #if 0
   if (!(GET_CODE (PATTERN (i3)) == SET
@@ -1175,7 +1209,7 @@ try_combine (i3, i2, i1)
 
   /* If the set in I2 needs to be kept around, we must make a copy of
      PATTERN (I2), so that when we substitute I1SRC for I1DEST in
-     PATTERN (I2), we are only substituing for the original I1DEST, not into
+     PATTERN (I2), we are only substituting for the original I1DEST, not into
      an already-substituted copy.  This also prevents making self-referential
      rtx.  If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
      I2DEST.  */
@@ -1517,6 +1551,50 @@ try_combine (i3, i2, i1)
       i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
       if (i2_code_number >= 0)
        insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
+
+      if (insn_code_number >= 0)
+       {
+         rtx insn;
+         rtx link;
+
+         /* If we will be able to accept this, we have made a change to the
+            destination of I3.  This can invalidate a LOG_LINKS pointing
+            to I3.  No other part of combine.c makes such a transformation.
+
+            The new I3 will have a destination that was previously the
+            destination of I1 or I2 and which was used in i2 or I3.  Call
+            distribute_links to make a LOG_LINK from the next use of
+            that destination.  */
+
+         PATTERN (i3) = newpat;
+         distribute_links (gen_rtx (INSN_LIST, VOIDmode, i3, 0));
+
+         /* I3 now uses what used to be its destination and which is
+            now I2's destination.  That means we need a LOG_LINK from
+            I3 to I2.  But we used to have one, so we still will.
+
+            However, some later insn might be using I2's dest and have
+            a LOG_LINK pointing at I3.  We must remove this link.
+            The simplest way to remove the link is to point it at I1,
+            which we know will be a NOTE.  */
+
+         for (insn = NEXT_INSN (i3);
+              insn && GET_CODE (insn) != CODE_LABEL
+              && GET_CODE (PREV_INSN (insn)) != JUMP_INSN;
+              insn = NEXT_INSN (insn))
+           {
+             if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+                 && reg_referenced_p (SET_DEST (newi2pat), PATTERN (insn)))
+               {
+                 for (link = LOG_LINKS (insn); link;
+                      link = XEXP (link, 1))
+                   if (XEXP (link, 0) == i3)
+                     XEXP (link, 0) = i1;
+
+                 break;
+               }
+           }
+       }
     }
            
   /* Similarly, check for a case where we have a PARALLEL of two independent
@@ -1620,7 +1698,7 @@ try_combine (i3, i2, i1)
 
     /* Ensure that we do not have something that should not be shared but
        occurs multiple times in the new insns.  Check this by first
-       restting all the `used' flags and then copying anything is shared.  */
+       resetting all the `used' flags and then copying anything is shared.  */
 
     reset_used_flags (i3notes);
     reset_used_flags (i2notes);
@@ -2082,7 +2160,7 @@ find_split_point (loc)
    
    IN_DEST is non-zero if we are processing the SET_DEST of a SET.
 
-   UNIQUE_COPY is non-zero if each substition must be unique.  We do this
+   UNIQUE_COPY is non-zero if each substitution must be unique.  We do this
    by copying if `n_occurrences' is non-zero.  */
 
 static rtx
@@ -4435,7 +4513,8 @@ make_field_assignment (x)
   /* Shift OTHER right POS places and make it the source, restricting it
      to the proper length and mode.  */
 
-  src = force_to_mode (simplify_shift_const (0, LSHIFTRT, mode, other, pos),
+  src = force_to_mode (simplify_shift_const (0, LSHIFTRT, GET_MODE (src),
+                                            other, pos),
                       mode, len, dest);
 
   return gen_rtx_combine (SET, VOIDmode, assign, src);
@@ -6253,7 +6332,7 @@ gen_unary (code, mode, op0)
 
    It is possible that we might detect that a comparison is either always
    true or always false.  However, we do not perform general constant
-   folding in combine, so this knowlege isn't useful.  Such tautologies
+   folding in combine, so this knowledge isn't useful.  Such tautologies
    should have been detected earlier.  Hence we ignore all such cases.  */
 
 static enum rtx_code
@@ -6685,7 +6764,7 @@ simplify_comparison (code, pop0, pop1)
 
        case PLUS:
          /* (eq (plus X C1) C2) -> (eq X (minus C2 C1)).  We can only do
-            this for equality comparisons due to pathalogical cases involving
+            this for equality comparisons due to pathological cases involving
             overflows.  */
          if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
              && (tem = simplify_binary_operation (MINUS, mode, op1,
@@ -7576,9 +7655,9 @@ reg_bitfield_target_p (reg, body)
 
   if (GET_CODE (body) == SET)
     return ((GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
-            && reg == XEXP (SET_DEST (body), 0))
+            && rtx_equal_p (reg, XEXP (SET_DEST (body), 0)))
            || (GET_CODE (SET_DEST (body)) == STRICT_LOW_PART
-               && reg == SUBREG_REG (XEXP (SET_DEST (body), 0))));
+               && rtx_equal_p (reg, SUBREG_REG (XEXP (SET_DEST (body), 0)))));
 
   else if (GET_CODE (body) == PARALLEL)
     for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
@@ -7742,7 +7821,11 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
                  {
                    rtx set = single_set (tem);
 
-                   if (set != 0 && ! side_effects_p (SET_SRC (set)))
+                   /* Verify that it was the set, and not a clobber that
+                      modified the register.  */
+
+                   if (set != 0 && ! side_effects_p (SET_SRC (set))
+                       && rtx_equal_p (XEXP (note, 0), SET_DEST (set)))
                      {
                        /* Move the notes and links of TEM elsewhere.
                           This might delete other dead insns recursively. 
@@ -7830,6 +7913,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
                          = emit_insn_before (gen_rtx (USE, VOIDmode, piece),
                                              place);
 
+                       all_used = 0;
                        REG_NOTES (use_insn)
                          = gen_rtx (EXPR_LIST, REG_DEAD, piece,
                                     REG_NOTES (use_insn));
@@ -7878,7 +7962,8 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
 }
 \f
 /* Similarly to above, distribute the LOG_LINKS that used to be present on
-   I3, I2, and I1 to new locations.  */
+   I3, I2, and I1 to new locations.  This is also called in one case to
+   add a link pointing at I3 when I3's destination is changed.  */
 
 static void
 distribute_links (links)
@@ -7921,7 +8006,7 @@ distribute_links (links)
         when we reach a set of the register or the end of the basic block.
 
         Note that this correctly handles the link that used to point from
-        I3 to I2.  Also note that not much seaching is typically done here
+        I3 to I2.  Also note that not much searching is typically done here
         since most links don't point very far away.  */
 
       for (insn = NEXT_INSN (XEXP (link, 0));
index 844b32fdd554cc2d6019840edfffbe54441fa285..5e10494e7670b71c10f62dc2056b16fa5f47b9bf 100644 (file)
@@ -43,7 +43,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* -m68881 is the default */
 #define CPP_SPEC \
 "%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
-%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
+%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}} \
 %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
 
 #else
@@ -51,7 +51,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* -msoft-float is the default */
 #define CPP_SPEC \
 "%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
-%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
+%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}} \
 %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
 
 #endif