rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro.
authorAlexandre Oliva <aoliva@redhat.com>
Sat, 2 Sep 2000 02:54:55 +0000 (02:54 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sat, 2 Sep 2000 02:54:55 +0000 (02:54 +0000)
* rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro.
* gcse.c (hash_string_1): New function.
(hash_expr_1) <ASM_OPERANDS>: Disregard filename and line number.
(expr_equiv_p) <ASM_OPERANDS>: Likewise.
* cse.c (rtx_cost): Don't increase the cost of ASM_OPERANDS.
(canon_hash_string): New function.
(canon_hash) <ASM_OPERANDS>: Disregard filename and line number.
(exp_equiv_p) <ASM_OPERANDS>: Likewise.
(fold_rtx): Use ASM_OPERANDS accessor macros.
* emit-rtl.c (copy_insn_1): Likewise.
* integrate.c (copy_rtx_and_substitute): Likewise.
* stmt.c (expand_asm_operands): Likewise.  Give an
ASM_OPERANDS rtx the mode of the output reg being set from it.

From-SVN: r36110

gcc/ChangeLog
gcc/cse.c
gcc/emit-rtl.c
gcc/gcse.c
gcc/integrate.c
gcc/rtl.h
gcc/stmt.c

index b7b5afcf63f9f6e145ce83fcb6a91b3da94ee57e..16fce73aed3ab78cbb105991947896c59e11481f 100644 (file)
@@ -1,3 +1,19 @@
+2000-09-01  Alexandre Oliva  <aoliva@redhat.com>
+
+       * rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro.
+       * gcse.c (hash_string_1): New function.
+       (hash_expr_1) <ASM_OPERANDS>: Disregard filename and line number.
+       (expr_equiv_p) <ASM_OPERANDS>: Likewise.
+       * cse.c (rtx_cost): Don't increase the cost of ASM_OPERANDS.
+       (canon_hash_string): New function.
+       (canon_hash) <ASM_OPERANDS>: Disregard filename and line number.
+       (exp_equiv_p) <ASM_OPERANDS>: Likewise.
+       (fold_rtx): Use ASM_OPERANDS accessor macros.
+       * emit-rtl.c (copy_insn_1): Likewise.
+       * integrate.c (copy_rtx_and_substitute): Likewise.
+       * stmt.c (expand_asm_operands): Likewise.  Give an
+       ASM_OPERANDS rtx the mode of the output reg being set from it.
+
 2000-09-01  Fred Fish  <fnf@be.com>
 
        * fix-header.c (write_rbrac): Add putc and getc to list of
index c0b72e305745ab526953a41b53cf9286b0769f86..2862ac2ddeec8f4e23fd0fd97c91f1deb4d41557 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -787,12 +787,6 @@ rtx_cost (x, outer_code)
       /* Used in loop.c and combine.c as a marker.  */
       total = 0;
       break;
-    case ASM_OPERANDS:
-      /* We don't want these to be used in substitutions because
-        we have no way of validating the resulting insn.  So assign
-        anything containing an ASM_OPERANDS a very high cost.  */
-      total = 1000;
-      break;
     default:
       total = 2;
     }
@@ -2141,6 +2135,21 @@ use_related_value (x, elt)
   return plus_constant (q->exp, offset);
 }
 \f
+/* Hash a string.  Just add its bytes up.  */
+static inline unsigned
+canon_hash_string (ps)
+     const char *ps;
+{
+  unsigned hash = 0;
+  const unsigned char *p = (const unsigned char *)ps;
+  
+  if (p)
+    while (*p)
+      hash += *p++;
+
+  return hash;
+}
+
 /* Hash an rtx.  We are careful to make sure the value is never negative.
    Equivalent registers hash identically.
    MODE is used in hashing for CONST_INTs only;
@@ -2286,6 +2295,32 @@ canon_hash (x, mode)
          do_not_record = 1;
          return 0;
        }
+      else
+       {
+         /* We don't want to take the filename and line into account.  */
+         hash += (unsigned) code + (unsigned) GET_MODE (x)
+           + canon_hash_string (ASM_OPERANDS_TEMPLATE (x))
+           + canon_hash_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
+           + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
+
+         if (ASM_OPERANDS_INPUT_LENGTH (x))
+           {
+             for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
+               {
+                 hash += (canon_hash (ASM_OPERANDS_INPUT (x, i),
+                                      GET_MODE (ASM_OPERANDS_INPUT (x, i)))
+                          + canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT
+                                               (x, i)));
+               }
+
+             hash += canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
+             x = ASM_OPERANDS_INPUT (x, 0);
+             mode = GET_MODE (x);
+             goto repeat;
+           }
+
+         return hash;
+       }
       break;
 
     default:
@@ -2315,14 +2350,7 @@ canon_hash (x, mode)
        for (j = 0; j < XVECLEN (x, i); j++)
          hash += canon_hash (XVECEXP (x, i, j), 0);
       else if (fmt[i] == 's')
-       {
-         register const unsigned char *p =
-           (const unsigned char *) XSTR (x, i);
-
-         if (p)
-           while (*p)
-             hash += *p++;
-       }
+       hash += canon_hash_string (XSTR (x, i));
       else if (fmt[i] == 'i')
        {
          register unsigned tem = XINT (x, i);
@@ -2476,6 +2504,35 @@ exp_equiv_p (x, y, validate, equal_values)
                  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
                                  validate, equal_values)));
 
+    case ASM_OPERANDS:
+      /* We don't use the generic code below because we want to
+        disregard filename and line numbers.  */
+
+      /* A volatile asm isn't equivalent to any other.  */
+      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
+       return 0;
+
+      if (GET_MODE (x) != GET_MODE (y)
+         || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
+         || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
+                    ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
+         || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
+         || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
+       return 0;
+
+      if (ASM_OPERANDS_INPUT_LENGTH (x))
+       {
+         for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
+           if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
+                              ASM_OPERANDS_INPUT (y, i),
+                              validate, equal_values)
+               || strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
+                          ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
+             return 0;
+       }
+
+      return 1;
+
     default:
       break;
     }
@@ -3500,9 +3557,9 @@ fold_rtx (x, insn)
       }
 
     case ASM_OPERANDS:
-      for (i = XVECLEN (x, 3) - 1; i >= 0; i--)
-       validate_change (insn, &XVECEXP (x, 3, i),
-                        fold_rtx (XVECEXP (x, 3, i), insn), 0);
+      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
+       validate_change (insn, &ASM_OPERANDS_INPUT (x, i),
+                        fold_rtx (ASM_OPERANDS_INPUT (x, i), insn), 0);
       break;
 
     default:
index 9a3258248bd259512649dc71203a28d15e231817..9eb9639e7d55f18f447e70036ff12d0b54200477 100644 (file)
@@ -3913,10 +3913,10 @@ copy_insn_1 (orig)
     }
   else if (code == ASM_OPERANDS)
     {
-      orig_asm_operands_vector = XVEC (orig, 3);
-      copy_asm_operands_vector = XVEC (copy, 3);
-      orig_asm_constraints_vector = XVEC (orig, 4);
-      copy_asm_constraints_vector = XVEC (copy, 4);
+      orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
+      copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
+      orig_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (orig);
+      copy_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
     }
 
   return copy;
index 680eb4f5c1f9a3966fdeb596b39c798a704e8d8b..c925a5a5d127c0f1a92f3acc29fc4c9c6d5cf17b 100644 (file)
@@ -1333,6 +1333,20 @@ hash_expr (x, mode, do_not_record_p, hash_table_size)
   hash = hash_expr_1 (x, mode, do_not_record_p);
   return hash % hash_table_size;
 }
+/* Hash a string.  Just add its bytes up.  */
+static inline unsigned
+hash_string_1 (ps)
+     const char *ps;
+{
+  unsigned hash = 0;
+  const unsigned char *p = (const unsigned char *)ps;
+  
+  if (p)
+    while (*p)
+      hash += *p++;
+
+  return hash;
+}
 
 /* Subroutine of hash_expr to do the actual work.  */
 
@@ -1433,6 +1447,32 @@ hash_expr_1 (x, mode, do_not_record_p)
          *do_not_record_p = 1;
          return 0;
        }
+      else
+       {
+         /* We don't want to take the filename and line into account.  */
+         hash += (unsigned) code + (unsigned) GET_MODE (x)
+           + hash_string_1 (ASM_OPERANDS_TEMPLATE (x))
+           + hash_string_1 (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
+           + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
+
+         if (ASM_OPERANDS_INPUT_LENGTH (x))
+           {
+             for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
+               {
+                 hash += (hash_expr_1 (ASM_OPERANDS_INPUT (x, i),
+                                       GET_MODE (ASM_OPERANDS_INPUT (x, i)),
+                                       do_not_record_p)
+                          + hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT
+                                           (x, i)));
+               }
+
+             hash += hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
+             x = ASM_OPERANDS_INPUT (x, 0);
+             mode = GET_MODE (x);
+             goto repeat;
+           }
+         return hash;
+       }
 
     default:
       break;
@@ -1466,14 +1506,7 @@ hash_expr_1 (x, mode, do_not_record_p)
          }
 
       else if (fmt[i] == 's')
-       {
-         register const unsigned char *p =
-           (const unsigned char *) XSTR (x, i);
-
-         if (p)
-           while (*p)
-             hash += *p++;
-       }
+       hash += hash_string_1 (XSTR (x, i));
       else if (fmt[i] == 'i')
        hash += (unsigned int) XINT (x, i);
       else
@@ -1565,6 +1598,34 @@ expr_equiv_p (x, y)
              || (expr_equiv_p (XEXP (x, 0), XEXP (y, 1))
                  && expr_equiv_p (XEXP (x, 1), XEXP (y, 0))));
 
+    case ASM_OPERANDS:
+      /* We don't use the generic code below because we want to
+        disregard filename and line numbers.  */
+
+      /* A volatile asm isn't equivalent to any other.  */
+      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
+       return 0;
+
+      if (GET_MODE (x) != GET_MODE (y)
+         || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
+         || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
+                    ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
+         || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
+         || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
+       return 0;
+
+      if (ASM_OPERANDS_INPUT_LENGTH (x))
+       {
+         for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
+           if (! expr_equiv_p (ASM_OPERANDS_INPUT (x, i),
+                               ASM_OPERANDS_INPUT (y, i))
+               || strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
+                          ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
+             return 0;
+       }
+
+      return 1;
+
     default:
       break;
     }
index ca5483a969b151a71658ba488df50c57f90ac834..e267f5e88653669d6fbe9b98cd397a0a9cc83107 100644 (file)
@@ -2040,20 +2040,23 @@ copy_rtx_and_substitute (orig, map, for_lhs)
       break;
 
     case ASM_OPERANDS:
-      /* If a single asm insn contains multiple output operands
-        then it contains multiple ASM_OPERANDS rtx's that share operand 3.
-        We must make sure that the copied insn continues to share it.  */
-      if (map->orig_asm_operands_vector == XVEC (orig, 3))
+      /* If a single asm insn contains multiple output operands then
+        it contains multiple ASM_OPERANDS rtx's that share the input
+        and constraint vecs.  We must make sure that the copied insn
+        continues to share it.  */
+      if (map->orig_asm_operands_vector == ASM_OPERANDS_INPUT_VEC (orig))
        {
          copy = rtx_alloc (ASM_OPERANDS);
          copy->volatil = orig->volatil;
-         XSTR (copy, 0) = XSTR (orig, 0);
-         XSTR (copy, 1) = XSTR (orig, 1);
-         XINT (copy, 2) = XINT (orig, 2);
-         XVEC (copy, 3) = map->copy_asm_operands_vector;
-         XVEC (copy, 4) = map->copy_asm_constraints_vector;
-         XSTR (copy, 5) = XSTR (orig, 5);
-         XINT (copy, 6) = XINT (orig, 6);
+         ASM_OPERANDS_TEMPLATE (copy) = ASM_OPERANDS_TEMPLATE (orig);
+         ASM_OPERANDS_OUTPUT_CONSTRAINT (copy)
+           = ASM_OPERANDS_OUTPUT_CONSTRAINT (orig);
+         ASM_OPERANDS_OUTPUT_IDX (copy) = ASM_OPERANDS_OUTPUT_IDX (orig);
+         ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector;
+         ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy)
+           = map->copy_asm_constraints_vector;
+         ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig);
+         ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);
          return copy;
        }
       break;
@@ -2212,9 +2215,10 @@ copy_rtx_and_substitute (orig, map, for_lhs)
 
   if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)
     {
-      map->orig_asm_operands_vector = XVEC (orig, 3);
-      map->copy_asm_operands_vector = XVEC (copy, 3);
-      map->copy_asm_constraints_vector = XVEC (copy, 4);
+      map->orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
+      map->copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
+      map->copy_asm_constraints_vector
+       = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
     }
 
   return copy;
index 44a5e8da6e2c00728f21c9915dee00b1d74e9d1d..a2f9087f066dc65066ed584039b9cbd49ac27ec4 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -800,6 +800,8 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
 #define ASM_OPERANDS_INPUT_CONSTRAINT_VEC(RTX) XCVEC ((RTX), 4, ASM_OPERANDS)
 #define ASM_OPERANDS_INPUT(RTX, N) XCVECEXP ((RTX), 3, (N), ASM_OPERANDS)
 #define ASM_OPERANDS_INPUT_LENGTH(RTX) XCVECLEN ((RTX), 3, ASM_OPERANDS)
+#define ASM_OPERANDS_INPUT_CONSTRAINT_EXP(RTX, N) \
+                       XCVECEXP ((RTX), 4, (N), ASM_OPERANDS)
 #define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) \
                        XSTR (XCVECEXP ((RTX), 4, (N), ASM_OPERANDS), 0)
 #define ASM_OPERANDS_INPUT_MODE(RTX, N)  \
index f2763e7396f7bd254495a3799973fabe2f5be907..46b2317149faed7de083bd99c53bc4527c579425 100644 (file)
@@ -1595,7 +1595,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
   argvec = rtvec_alloc (ninputs);
   constraints = rtvec_alloc (ninputs);
 
-  body = gen_rtx_ASM_OPERANDS (VOIDmode, TREE_STRING_POINTER (string),
+  body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode
+                               : GET_MODE (output_rtx[0])),
+                              TREE_STRING_POINTER (string), 
                               empty_string, 0, argvec, constraints,
                               filename, line);
 
@@ -1771,9 +1773,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
            warning ("asm operand %d probably doesn't match constraints", i);
        }
       generating_concat_p = old_generating_concat_p;
-      XVECEXP (body, 3, i) = op;
+      ASM_OPERANDS_INPUT (body, i) = op;
 
-      XVECEXP (body, 4, i)      /* constraints */
+      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, i)
        = gen_rtx_ASM_INPUT (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
                             orig_constraint);
       i++;
@@ -1785,7 +1787,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
   generating_concat_p = 0;
 
   for (i = 0; i < ninputs - ninout; i++)
-    XVECEXP (body, 3, i) = protect_from_queue (XVECEXP (body, 3, i), 0);
+    ASM_OPERANDS_INPUT (body, i)
+      = protect_from_queue (ASM_OPERANDS_INPUT (body, i), 0);
 
   for (i = 0; i < noutputs; i++)
     output_rtx[i] = protect_from_queue (output_rtx[i], 1);
@@ -1795,9 +1798,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
     {
       int j = inout_opnum[i];
 
-      XVECEXP (body, 3, ninputs - ninout + i)      /* argvec */
+      ASM_OPERANDS_INPUT (body, ninputs - ninout + i)
        = output_rtx[j];
-      XVECEXP (body, 4, ninputs - ninout + i)      /* constraints */
+      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, ninputs - ninout + i)
        = gen_rtx_ASM_INPUT (inout_mode[i], digit_strings[j]);
     }
 
@@ -1810,7 +1813,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
 
   if (noutputs == 1 && nclobbers == 0)
     {
-      XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs));
+      ASM_OPERANDS_OUTPUT_CONSTRAINT (body)
+       = TREE_STRING_POINTER (TREE_PURPOSE (outputs));
       insn = emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
     }
 
@@ -1837,7 +1841,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
            = gen_rtx_SET (VOIDmode,
                           output_rtx[i],
                           gen_rtx_ASM_OPERANDS
-                          (VOIDmode,
+                          (GET_MODE (output_rtx[i]),
                            TREE_STRING_POINTER (string),
                            TREE_STRING_POINTER (TREE_PURPOSE (tail)),
                            i, argvec, constraints,