diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-20 17:50:48 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-20 17:50:48 +0000 |
commit | 3393215f16466fcf4b25c247e195c5b96761a93a (patch) | |
tree | 89d914be5aa639096dbd44d7f9d3e884503d85a0 /gcc/varasm.c | |
parent | cfea3820a45c72304bfb7887b39f032f065045c2 (diff) | |
download | gcc-3393215f16466fcf4b25c247e195c5b96761a93a.tar.gz |
* real.c (real_hash): New.
* real.h: Declare it.
* cse.c (canon_hash): Use it.
* cselib.c (hash_rtx): Likewise.
* emit-rtl.c (const_double_htab_hash): Likewise.
* rtl.h (CONST_DOUBLE_REAL_VALUE): New.
* varasm.c (struct rtx_const): Reduce vector size; separate
integer and fp vectors.
(HASHBITS): Remove.
(const_hash_1): Rename from const_hash. Use real_hash. Do not
take modulus MAX_HASH_TABLE.
(const_hash): New. Do take modulus MAX_HASH_TABLE.
(output_constant_def): Do not take modulus MAX_HASH_TABLE.
(SYMHASH): Don't use HASHBITS.
(decode_rtx_const): Copy only active bits from REAL_VALUE_TYPE.
Fix CONST_VECTOR thinko wrt fp vectors. Fix kind comparison.
(simplify_subtraction): Fix kind comparison.
(const_hash_rtx): Return unsigned int. Don't use HASHBITS.
Use a union to pun integer array.
* config/rs6000/rs6000.c (rs6000_hash_constant): Use real_hash;
only hash two words of integral CONST_DOUBLE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57356 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 174 |
1 files changed, 110 insertions, 64 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index edd02622b09..702cf82446d 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -136,13 +136,14 @@ static HOST_WIDE_INT const_alias_set; static const char *strip_reg_name PARAMS ((const char *)); static int contains_pointers_p PARAMS ((tree)); static void decode_addr_const PARAMS ((tree, struct addr_const *)); -static int const_hash PARAMS ((tree)); +static unsigned int const_hash PARAMS ((tree)); +static unsigned int const_hash_1 PARAMS ((tree)); static int compare_constant PARAMS ((tree, tree)); static tree copy_constant PARAMS ((tree)); static void output_constant_def_contents PARAMS ((tree, int, int)); static void decode_rtx_const PARAMS ((enum machine_mode, rtx, struct rtx_const *)); -static int const_hash_rtx PARAMS ((enum machine_mode, rtx)); +static unsigned int const_hash_rtx PARAMS ((enum machine_mode, rtx)); static int compare_constant_rtx PARAMS ((enum machine_mode, rtx, struct constant_descriptor_rtx *)); static struct constant_descriptor_rtx * record_constant_rtx @@ -2166,11 +2167,15 @@ struct rtx_const GTY(()) HOST_WIDE_INT low; } GTY ((tag ("0"))) di; - /* The max vector size we have is 8 wide. This should be enough. */ - struct rtx_const_vec { - HOST_WIDE_INT veclo; - HOST_WIDE_INT vechi; - } GTY ((tag ("2"))) vec[16]; + /* The max vector size we have is 8 wide; two variants for + integral and floating point vectors. */ + struct rtx_const_int_vec { + HOST_WIDE_INT high; + HOST_WIDE_INT low; + } GTY ((tag ("2"))) int_vec[8]; + + REAL_VALUE_TYPE GTY ((tag ("3"))) fp_vec[8]; + } GTY ((desc ("%1.kind >= RTX_INT"), descbits ("1"))) un; }; @@ -2193,7 +2198,6 @@ struct constant_descriptor_tree GTY(()) tree value; }; -#define HASHBITS 30 #define MAX_HASH_TABLE 1009 static GTY(()) struct constant_descriptor_tree * const_hash_table[MAX_HASH_TABLE]; @@ -2238,12 +2242,20 @@ const_str_htab_eq (x, y) /* Compute a hash code for a constant expression. */ -static int +static unsigned int const_hash (exp) tree exp; { + return const_hash_1 (exp) % MAX_HASH_TABLE; +} + +static unsigned int +const_hash_1 (exp) + tree exp; +{ const char *p; - int len, hi, i; + unsigned int hi; + int len, i; enum tree_code code = TREE_CODE (exp); /* Either set P and LEN to the address and len of something to hash and @@ -2257,9 +2269,7 @@ const_hash (exp) break; case REAL_CST: - p = (char *) &TREE_REAL_CST (exp); - len = sizeof TREE_REAL_CST (exp); - break; + return real_hash (TREE_REAL_CST_PTR (exp)); case STRING_CST: p = TREE_STRING_POINTER (exp); @@ -2267,8 +2277,8 @@ const_hash (exp) break; case COMPLEX_CST: - return (const_hash (TREE_REALPART (exp)) * 5 - + const_hash (TREE_IMAGPART (exp))); + return (const_hash_1 (TREE_REALPART (exp)) * 5 + + const_hash_1 (TREE_IMAGPART (exp))); case CONSTRUCTOR: if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE) @@ -2285,23 +2295,11 @@ const_hash (exp) { tree link; - /* For record type, include the type in the hashing. - We do not do so for array types - because (1) the sizes of the elements are sufficient - and (2) distinct array types can have the same constructor. - Instead, we include the array size because the constructor could - be shorter. */ - if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE) - hi = ((unsigned long) TREE_TYPE (exp) & ((1 << HASHBITS) - 1)) - % MAX_HASH_TABLE; - else - hi = ((5 + int_size_in_bytes (TREE_TYPE (exp))) - & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE; + hi = 5 + int_size_in_bytes (TREE_TYPE (exp)); for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link)) if (TREE_VALUE (link)) - hi - = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE; + hi = hi * 603 + const_hash_1 (TREE_VALUE (link)); return hi; } @@ -2325,25 +2323,22 @@ const_hash (exp) hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13; else abort (); - - hi &= (1 << HASHBITS) - 1; - hi %= MAX_HASH_TABLE; } return hi; case PLUS_EXPR: case MINUS_EXPR: - return (const_hash (TREE_OPERAND (exp, 0)) * 9 - + const_hash (TREE_OPERAND (exp, 1))); + return (const_hash_1 (TREE_OPERAND (exp, 0)) * 9 + + const_hash_1 (TREE_OPERAND (exp, 1))); case NOP_EXPR: case CONVERT_EXPR: case NON_LVALUE_EXPR: - return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2; + return const_hash_1 (TREE_OPERAND (exp, 0)) * 7 + 2; default: /* A language specific constant. Just hash the code. */ - return (int) code % MAX_HASH_TABLE; + return code; } /* Compute hashing function */ @@ -2351,8 +2346,6 @@ const_hash (exp) for (i = 0; i < len; i++) hi = ((hi * 613) + (unsigned) (p[i])); - hi &= (1 << HASHBITS) - 1; - hi %= MAX_HASH_TABLE; return hi; } @@ -2691,7 +2684,7 @@ output_constant_def (exp, defer) to see if any of them describes EXP. If yes, the descriptor records the label number already assigned. */ - hash = const_hash (exp) % MAX_HASH_TABLE; + hash = const_hash (exp); for (desc = const_hash_table[hash]; desc; desc = desc->next) if (compare_constant (exp, desc->value)) @@ -2910,8 +2903,7 @@ struct pool_constant GTY(()) /* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true. The argument is XSTR (... , 0) */ -#define SYMHASH(LABEL) \ - ((((unsigned long) (LABEL)) & ((1 << HASHBITS) - 1)) % MAX_RTX_HASH_TABLE) +#define SYMHASH(LABEL) (((unsigned long) (LABEL)) % MAX_RTX_HASH_TABLE) /* Initialize constant pool hashing for a new function. */ @@ -2958,8 +2950,29 @@ decode_rtx_const (mode, x, value) value->kind = RTX_DOUBLE; if (GET_MODE (x) != VOIDmode) { + const REAL_VALUE_TYPE *r = CONST_DOUBLE_REAL_VALUE (x); + value->mode = GET_MODE (x); - REAL_VALUE_FROM_CONST_DOUBLE (value->un.du, x); + + /* Copy the REAL_VALUE_TYPE by members so that we don't + copy garbage from the original structure into our + carefully cleaned hashing structure. */ + value->un.du.class = r->class; + value->un.du.sign = r->sign; + switch (r->class) + { + case rvc_zero: + case rvc_inf: + break; + case rvc_normal: + value->un.du.exp = r->exp; + /* FALLTHRU */ + case rvc_nan: + memcpy (value->un.du.sig, r->sig, sizeof (r->sig)); + break; + default: + abort (); + } } else { @@ -2971,28 +2984,59 @@ decode_rtx_const (mode, x, value) case CONST_VECTOR: { int units, i; - rtx elt; units = CONST_VECTOR_NUNITS (x); value->kind = RTX_VECTOR; value->mode = mode; - for (i = 0; i < units; ++i) + if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) { - elt = CONST_VECTOR_ELT (x, i); - if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) + for (i = 0; i < units; ++i) { - value->un.vec[i].veclo = (HOST_WIDE_INT) INTVAL (elt); - value->un.vec[i].vechi = 0; + rtx elt = CONST_VECTOR_ELT (x, i); + if (GET_CODE (elt) == CONST_INT) + { + value->un.int_vec[i].low = INTVAL (elt); + value->un.int_vec[i].high = 0; + } + else + { + value->un.int_vec[i].low = CONST_DOUBLE_LOW (elt); + value->un.int_vec[i].high = CONST_DOUBLE_HIGH (elt); + } } - else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) + } + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) + { + for (i = 0; i < units; ++i) { - value->un.vec[i].veclo = (HOST_WIDE_INT) CONST_DOUBLE_LOW (elt); - value->un.vec[i].vechi = (HOST_WIDE_INT) CONST_DOUBLE_HIGH (elt); + const REAL_VALUE_TYPE *r + = CONST_DOUBLE_REAL_VALUE (CONST_VECTOR_ELT (x, i)); + REAL_VALUE_TYPE *d = &value->un.fp_vec[i]; + + /* Copy the REAL_VALUE_TYPE by members so that we don't + copy garbage from the original structure into our + carefully cleaned hashing structure. */ + d->class = r->class; + d->sign = r->sign; + switch (r->class) + { + case rvc_zero: + case rvc_inf: + break; + case rvc_normal: + d->exp = r->exp; + /* FALLTHRU */ + case rvc_nan: + memcpy (d->sig, r->sig, sizeof (r->sig)); + break; + default: + abort (); + } } - else - abort (); } + else + abort (); } break; @@ -3047,7 +3091,7 @@ decode_rtx_const (mode, x, value) } } - if (value->kind > RTX_VECTOR && value->un.addr.base != 0) + if (value->kind >= RTX_INT && value->un.addr.base != 0) switch (GET_CODE (value->un.addr.base)) { #if 0 @@ -3079,7 +3123,7 @@ simplify_subtraction (x) decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0); decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1); - if (val0.kind > RTX_DOUBLE + if (val0.kind >= RTX_INT && val0.kind == val1.kind && val0.un.addr.base == val1.un.addr.base) return GEN_INT (val0.un.addr.offset - val1.un.addr.offset); @@ -3089,25 +3133,27 @@ simplify_subtraction (x) /* Compute a hash code for a constant RTL expression. */ -static int +static unsigned int const_hash_rtx (mode, x) enum machine_mode mode; rtx x; { - int hi; + union { + struct rtx_const value; + unsigned int data[sizeof(struct rtx_const) / sizeof (unsigned int)]; + } u; + + unsigned int hi; size_t i; - struct rtx_const value; - decode_rtx_const (mode, x, &value); + decode_rtx_const (mode, x, &u.value); /* Compute hashing function */ hi = 0; - for (i = 0; i < sizeof value / sizeof (int); i++) - hi += ((int *) &value)[i]; + for (i = 0; i < ARRAY_SIZE (u.data); i++) + hi = hi * 613 + u.data[i]; - hi &= (1 << HASHBITS) - 1; - hi %= MAX_RTX_HASH_TABLE; - return hi; + return hi % MAX_RTX_HASH_TABLE; } /* Compare a constant rtl object X with a constant-descriptor DESC. |