combine.c (can_combine_p): Do not prevent building insns that use and clobber the...
authorUlrich Weigand <uweigand@de.ibm.com>
Mon, 28 Jun 2004 13:11:44 +0000 (13:11 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Mon, 28 Jun 2004 13:11:44 +0000 (13:11 +0000)
* combine.c (can_combine_p): Do not prevent building insns that use
and clobber the same fixed hard register.
(reg_dead_at_p): Likewise.

From-SVN: r83785

gcc/ChangeLog
gcc/combine.c

index e65f82346d874b1fe7a69facf662b8ea51d5beb3..fa3ddd5f81a208f5b2a85f51907c80162e438b6f 100644 (file)
@@ -1,3 +1,9 @@
+2004-06-28  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * combine.c (can_combine_p): Do not prevent building insns that use
+       and clobber the same fixed hard register.
+       (reg_dead_at_p): Likewise.
+
 2004-06-28  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * tree-sra.c (is_sra_candidate_ref): Remove second arg; all callers
index 008e351ca1a561f2d1231892fc884b75fd5f1d86..7ce6b32c59a68d895eb997c3e8b48ea795376772 100644 (file)
@@ -1129,16 +1129,30 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
   else if (GET_CODE (dest) != CC0)
     return 0;
 
-  /* Don't substitute for a register intended as a clobberable operand.
-     Similarly, don't substitute an expression containing a register that
-     will be clobbered in I3.  */
+
   if (GET_CODE (PATTERN (i3)) == PARALLEL)
     for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
-      if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
-         && (reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0),
-                                      src)
-             || rtx_equal_p (XEXP (XVECEXP (PATTERN (i3), 0, i), 0), dest)))
-       return 0;
+      if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER)
+       {
+          /* Don't substitute for a register intended as a clobberable
+            operand. */
+         rtx reg = XEXP (XVECEXP (PATTERN (i3), 0, i), 0);
+         if (rtx_equal_p (reg, dest))
+           return 0;
+
+         /* If the clobber represents an earlyclobber operand, we must not
+            substitute an expression containing the clobbered register.
+            As we do not analyse the constraint strings here, we have to
+            make the conservative assumption.  However, if the register is
+            a fixed hard reg, the clobber cannot represent any operand;
+            we leave it up to the machine description to either accept or
+            reject use-and-clobber patterns.  */
+         if (!REG_P (reg)
+             || REGNO (reg) >= FIRST_PSEUDO_REGISTER
+             || !fixed_regs[REGNO (reg)])
+           if (reg_overlap_mentioned_p (reg, src))
+             return 0;
+       }
 
   /* If INSN contains anything volatile, or is an `asm' (whether volatile
      or not), reject, unless nothing volatile comes between it and I3 */
@@ -11142,11 +11156,13 @@ reg_dead_at_p (rtx reg, rtx insn)
 
   reg_dead_flag = 0;
 
-  /* Check that reg isn't mentioned in NEWPAT_USED_REGS.  */
+  /* Check that reg isn't mentioned in NEWPAT_USED_REGS.  For fixed registers
+     we allow the machine description to decide whether use-and-clobber
+     patterns are OK.  */
   if (reg_dead_regno < FIRST_PSEUDO_REGISTER)
     {
       for (i = reg_dead_regno; i < reg_dead_endregno; i++)
-       if (TEST_HARD_REG_BIT (newpat_used_regs, i))
+       if (!fixed_regs[i] && TEST_HARD_REG_BIT (newpat_used_regs, i))
          return 0;
     }