diff options
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 91 |
1 files changed, 74 insertions, 17 deletions
@@ -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); } +/* 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: |