summaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-20 17:50:48 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-20 17:50:48 +0000
commit3393215f16466fcf4b25c247e195c5b96761a93a (patch)
tree89d914be5aa639096dbd44d7f9d3e884503d85a0 /gcc/varasm.c
parentcfea3820a45c72304bfb7887b39f032f065045c2 (diff)
downloadgcc-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.c174
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.