From 6462bb432fe58e6dba719b88df693f768a05e5a6 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Sat, 2 Sep 2000 02:54:55 +0000 Subject: [PATCH] rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro. * rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro. * gcse.c (hash_string_1): New function. (hash_expr_1) : Disregard filename and line number. (expr_equiv_p) : Likewise. * cse.c (rtx_cost): Don't increase the cost of ASM_OPERANDS. (canon_hash_string): New function. (canon_hash) : Disregard filename and line number. (exp_equiv_p) : 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 | 16 +++++++++ gcc/cse.c | 91 ++++++++++++++++++++++++++++++++++++++++--------- gcc/emit-rtl.c | 8 ++--- gcc/gcse.c | 77 ++++++++++++++++++++++++++++++++++++----- gcc/integrate.c | 32 +++++++++-------- gcc/rtl.h | 2 ++ gcc/stmt.c | 20 ++++++----- 7 files changed, 195 insertions(+), 51 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b7b5afcf63f..16fce73aed3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2000-09-01 Alexandre Oliva + + * rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro. + * gcse.c (hash_string_1): New function. + (hash_expr_1) : Disregard filename and line number. + (expr_equiv_p) : Likewise. + * cse.c (rtx_cost): Don't increase the cost of ASM_OPERANDS. + (canon_hash_string): New function. + (canon_hash) : Disregard filename and line number. + (exp_equiv_p) : 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 * fix-header.c (write_rbrac): Add putc and getc to list of diff --git a/gcc/cse.c b/gcc/cse.c index c0b72e30574..2862ac2ddee 100644 --- 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); } +/* 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: diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 9a3258248bd..9eb9639e7d5 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -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; diff --git a/gcc/gcse.c b/gcc/gcse.c index 680eb4f5c1f..c925a5a5d12 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -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; } diff --git a/gcc/integrate.c b/gcc/integrate.c index ca5483a969b..e267f5e8865 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -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; diff --git a/gcc/rtl.h b/gcc/rtl.h index 44a5e8da6e2..a2f9087f066 100644 --- 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) \ diff --git a/gcc/stmt.c b/gcc/stmt.c index f2763e7396f..46b2317149f 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -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, -- 2.30.2