]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport i386 -mregparm fix to the 2.95 branch
authorBernd Schmidt <bernds@redhat.co.uk>
Fri, 22 Dec 2000 14:03:13 +0000 (14:03 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Fri, 22 Dec 2000 14:03:13 +0000 (14:03 +0000)
From-SVN: r38454

gcc/ChangeLog
gcc/combine.c

index b3504408b3e6fce2baf0124520e2e9a55df995fd..9a16210917dc2cef5b6a3eb78aeabca91e499c76 100644 (file)
@@ -1,3 +1,17 @@
+2000-12-22  Bernd Schmidt  <bernds@redhat.co.uk>
+
+       Fri Dec 15 15:32:16 MET 2000  Jan Hubicka  <jh@suse.cz>
+       * combine.c (cant_combine_insn_p): Get around SUBREGs when determining
+       hardreg<->reg moves.
+
+       2000-12-01  Bernd Schmidt  <bernds@redhat.co.uk>
+       * combine.c (cant_combine_insn_p): Only disallow insns involving
+       hard regs if they are reg-reg moves.
+
+       2000-11-24  Bernd Schmidt  <bernds@redhat.co.uk>
+       * combine.c (cant_combine_insn_p): New function.
+       (try_combine): Use it.
+
 2000-12-20  Bernd Schmidt  <bernds@redhat.co.uk>
 
        * version.c: Bump.
index 1f2375603f48cd9c2987364a273e5a4e78e44a32..e84e31bf84c16eac49cca0be12c7516ebe20196a 100644 (file)
@@ -392,6 +392,7 @@ static int n_occurrences;
 static void init_reg_last_arrays       PROTO((void));
 static void setup_incoming_promotions   PROTO((void));
 static void set_nonzero_bits_and_sign_copies  PROTO((rtx, rtx));
+static int cant_combine_insn_p PROTO((rtx));
 static int can_combine_p       PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *));
 static int sets_function_arg_p PROTO((rtx));
 static int combinable_i3pat    PROTO((rtx, rtx *, rtx, rtx, int, rtx *));
@@ -1312,6 +1313,49 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
   return 1;
 }
 \f
+/* Determine whether INSN can be used in a combination.  Return nonzero if
+   not.  This is used in try_combine to detect early some cases where we
+   can't perform combinations.  */
+
+static int
+cant_combine_insn_p (insn)
+     rtx insn;
+{
+  rtx set;
+  rtx src, dest;
+  
+  /* If this isn't really an insn, we can't do anything.
+     This can occur when flow deletes an insn that it has merged into an
+     auto-increment address.  */
+  if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+    return 1;
+
+  /* Never combine loads and stores involving hard regs.  The register
+     allocator can usually handle such reg-reg moves by tying.  If we allow
+     the combiner to make substitutions of hard regs, we risk aborting in
+     reload on machines that have SMALL_REGISTER_CLASSES.
+     As an exception, we allow combinations involving fixed regs; these are
+     not available to the register allocator so there's no risk involved.  */
+
+  set = single_set (insn);
+  if (! set)
+    return 0;
+  src = SET_SRC (set);
+  dest = SET_DEST (set);
+  if (GET_CODE (src) == SUBREG)
+    src = SUBREG_REG (src);
+  if (GET_CODE (dest) == SUBREG)
+    dest = SUBREG_REG (dest);
+  if (REG_P (src) && REG_P (dest)
+      && ((REGNO (src) < FIRST_PSEUDO_REGISTER
+          && ! fixed_regs[REGNO (src)])
+         || (REGNO (dest) < FIRST_PSEUDO_REGISTER
+             && ! fixed_regs[REGNO (dest)])))
+    return 1;
+
+  return 0;
+}
+
 /* Try to combine the insns I1 and I2 into I3.
    Here I1 and I2 appear earlier than I3.
    I1 can be zero; then we combine just I2 into I3.
@@ -1362,21 +1406,20 @@ try_combine (i3, i2, i1)
   register rtx link;
   int i;
 
-  /* If any of I1, I2, and I3 isn't really an insn, we can't do anything.
-     This can occur when flow deletes an insn that it has merged into an
-     auto-increment address.  We also can't do anything if I3 has a
-     REG_LIBCALL note since we don't want to disrupt the contiguity of a
-     libcall.  */
-
-  if (GET_RTX_CLASS (GET_CODE (i3)) != 'i'
-      || GET_RTX_CLASS (GET_CODE (i2)) != 'i'
-      || (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i')
+  /* Exit early if one of the insns involved can't be used for
+     combinations.  */
+  if (cant_combine_insn_p (i3)
+      || cant_combine_insn_p (i2)
+      || (i1 && cant_combine_insn_p (i1))
+      /* We also can't do anything if I3 has a
+        REG_LIBCALL note since we don't want to disrupt the contiguity of a
+        libcall.  */
 #if 0
       /* ??? This gives worse code, and appears to be unnecessary, since no
         pass after flow uses REG_LIBCALL/REG_RETVAL notes.  */
       || find_reg_note (i3, REG_LIBCALL, NULL_RTX)
 #endif
-)
+      )
     return 0;
 
   combine_attempts++;