]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cse.c
(call_insn_operand): New funcion.
[gcc.git] / gcc / cse.c
index 440424712780f27f66dea3aa00acd9cda3daddd9..3d2702fbbe3c3ccc093d3acaead7038a3b5d9261 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1,5 +1,5 @@
 /* Common subexpression elimination for GNU compiler.
-   Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1989, 1992. 1993 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -984,9 +984,14 @@ insert_regs (x, classp, modified)
     {
       register int regno = REGNO (x);
 
-      if (modified
-         || ! (REGNO_QTY_VALID_P (regno)
-               && qty_mode[reg_qty[regno]] == GET_MODE (x)))
+      /* If REGNO is in the equivalence table already but is of the
+        wrong mode for that equivalence, don't do anything here.  */
+
+      if (REGNO_QTY_VALID_P (regno)
+         && qty_mode[reg_qty[regno]] != GET_MODE (x))
+       return 0;
+
+      if (modified || ! REGNO_QTY_VALID_P (regno))
        {
          if (classp)
            for (classp = classp->first_same_value;
@@ -1491,7 +1496,8 @@ invalidate (x)
        remove_from_table (lookup_for_remove (x, hash, GET_MODE (x)), hash);
       else
        {
-         int in_table = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
+         HOST_WIDE_INT in_table
+           = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
          int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
          int tregno, tendregno;
          register struct table_elt *p, *next;
@@ -3560,15 +3566,23 @@ simplify_binary_operation (code, mode, op0, op1)
              && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT)
            {
              REAL_VALUE_TYPE d;
+             jmp_buf handler;
+             int op1is2, op1ism1;
+
+             if (setjmp (handler))
+               return 0;
+
+             set_float_handler (handler);
              REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
+             op1is2 = REAL_VALUES_EQUAL (d, dconst2);
+             op1ism1 = REAL_VALUES_EQUAL (d, dconstm1);
+             set_float_handler (NULL_PTR);
 
              /* x*2 is x+x and x*(-1) is -x */
-             if (REAL_VALUES_EQUAL (d, dconst2)
-                 && GET_MODE (op0) == mode)
+             if (op1is2 && GET_MODE (op0) == mode)
                return gen_rtx (PLUS, mode, op0, copy_rtx (op0));
 
-             else if (REAL_VALUES_EQUAL (d, dconstm1)
-                      && GET_MODE (op0) == mode)
+             else if (op1ism1 && GET_MODE (op0) == mode)
                return gen_rtx (NEG, mode, op0);
            }
          break;
@@ -3584,7 +3598,8 @@ simplify_binary_operation (code, mode, op0, op1)
          /* A | (~A) -> -1 */
          if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
               || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
-             && ! side_effects_p (op0))
+             && ! side_effects_p (op0)
+             && GET_MODE_CLASS (mode) != MODE_CC)
            return constm1_rtx;
          break;
 
@@ -3594,7 +3609,8 @@ simplify_binary_operation (code, mode, op0, op1)
          if (GET_CODE (op1) == CONST_INT
              && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
            return gen_rtx (NOT, mode, op0);
-         if (op0 == op1 && ! side_effects_p (op0))
+         if (op0 == op1 && ! side_effects_p (op0)
+             && GET_MODE_CLASS (mode) != MODE_CC)
            return const0_rtx;
          break;
 
@@ -3604,12 +3620,14 @@ simplify_binary_operation (code, mode, op0, op1)
          if (GET_CODE (op1) == CONST_INT
              && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
            return op0;
-         if (op0 == op1 && ! side_effects_p (op0))
+         if (op0 == op1 && ! side_effects_p (op0)
+             && GET_MODE_CLASS (mode) != MODE_CC)
            return op0;
          /* A & (~A) -> 0 */
          if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
               || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
-             && ! side_effects_p (op0))
+             && ! side_effects_p (op0)
+             && GET_MODE_CLASS (mode) != MODE_CC)
            return const0_rtx;
          break;
 
@@ -3702,7 +3720,8 @@ simplify_binary_operation (code, mode, op0, op1)
           
        case SMAX:
          if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT
-             && INTVAL (op1) == (unsigned) GET_MODE_MASK (mode) >> 1
+             && (INTVAL (op1)
+                 == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
              && ! side_effects_p (op0))
            return op1;
          else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
@@ -4144,6 +4163,11 @@ simplify_relational_operation (code, mode, op0, op1)
   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
     op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
 
+  /* What to do with MODE_CC isn't clear yet.
+     Let's make sure nothing erroneous is done.  */
+  if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
+    return 0;
+
   /* Unlike the arithmetic operations, we can do the comparison whether
      or not WIDTH is larger than HOST_BITS_PER_WIDE_INT because the
      CONST_INTs are to be understood as being infinite precision as
@@ -5466,8 +5490,10 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
      true for all smaller modes whether or not there is a SUBREG, but
      is not worth testing for with no SUBREG.  */
 
+  /* Note that GET_MODE (op0) may not equal MODE.  */
   if (code == EQ && GET_CODE (op0) == SUBREG
-      && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
+      && (GET_MODE_SIZE (GET_MODE (op0))
+         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
     {
       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
       rtx tem = gen_lowpart_if_possible (inner_mode, op1);
@@ -5478,7 +5504,8 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
     }
 
   if (code == EQ && GET_CODE (op1) == SUBREG
-      && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))))
+      && (GET_MODE_SIZE (GET_MODE (op1))
+         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
     {
       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
       rtx tem = gen_lowpart_if_possible (inner_mode, op0);
@@ -5491,9 +5518,14 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
   /* Similarly, if this is an NE comparison, and either is a SUBREG 
      making a smaller mode, we know the whole thing is also NE.  */
 
+  /* Note that GET_MODE (op0) may not equal MODE;
+     if we test MODE instead, we can get an infinite recursion
+     alternating between two modes each wider than MODE.  */
+
   if (code == NE && GET_CODE (op0) == SUBREG
       && subreg_lowpart_p (op0)
-      && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
+      && (GET_MODE_SIZE (GET_MODE (op0))
+         < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
     {
       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
       rtx tem = gen_lowpart_if_possible (inner_mode, op1);
@@ -5505,7 +5537,8 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
 
   if (code == NE && GET_CODE (op1) == SUBREG
       && subreg_lowpart_p (op1)
-      && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))))
+      && (GET_MODE_SIZE (GET_MODE (op1))
+         < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
     {
       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
       rtx tem = gen_lowpart_if_possible (inner_mode, op0);
@@ -6580,6 +6613,13 @@ cse_insn (insn, in_libcall_block)
              delete_insn (insn);
              insn = new;
            }
+         else
+           /* Otherwise, force rerecognition, since it probably had
+              a different pattern before.
+              This shouldn't really be necessary, since whatever
+              changed the source value above should have done this.
+              Until the right place is found, might as well do this here.  */
+           INSN_CODE (insn) = -1;
 
          /* Now that we've converted this jump to an unconditional jump,
             there is dead code after it.  Delete the dead code until we
This page took 0.043773 seconds and 5 git commands to generate.