aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1997-01-18 14:08:26 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1997-01-18 14:08:26 -0500
commita9d07d6e65f690431a892903c89404a9ed291000 (patch)
tree9ec3c5d4da10a2a92e4a2000ca70a645fca039ca /gcc
parent19b38e0407fec8b68a4d5d14bb8ad2340df8d53a (diff)
downloadgcc-a9d07d6e65f690431a892903c89404a9ed291000.zip
gcc-a9d07d6e65f690431a892903c89404a9ed291000.tar.gz
gcc-a9d07d6e65f690431a892903c89404a9ed291000.tar.bz2
(const_hash): Treat NON_LVALUE_EXPR like CONVERT_EXPR.
(compare_constant_1, copy_constant, bc_assemble_integer): Likewise. (const_hash, compare_constant_1): Use switch, not if-then-else. From-SVN: r13507
Diffstat (limited to 'gcc')
-rw-r--r--gcc/varasm.c328
1 files changed, 188 insertions, 140 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index c62fd7e..7595f48 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2344,75 +2344,95 @@ const_hash (exp)
register int len, hi, i;
register enum tree_code code = TREE_CODE (exp);
- if (code == INTEGER_CST)
+ /* Either set P and LEN to the address and len of something to hash and
+ exit the switch or return a value. */
+
+ switch (code)
{
+ case INTEGER_CST:
p = (char *) &TREE_INT_CST_LOW (exp);
len = 2 * sizeof TREE_INT_CST_LOW (exp);
- }
- else if (code == REAL_CST)
- {
+ break;
+
+ case REAL_CST:
p = (char *) &TREE_REAL_CST (exp);
len = sizeof TREE_REAL_CST (exp);
- }
- else if (code == STRING_CST)
- p = TREE_STRING_POINTER (exp), len = TREE_STRING_LENGTH (exp);
- else if (code == COMPLEX_CST)
- return const_hash (TREE_REALPART (exp)) * 5
- + const_hash (TREE_IMAGPART (exp));
- else if (code == CONSTRUCTOR && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
- {
- len = int_size_in_bytes (TREE_TYPE (exp));
- p = (char *) alloca (len);
- get_set_constructor_bytes (exp, (unsigned char *) p, len);
- }
- else if (code == CONSTRUCTOR)
- {
- register 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 = ((HOST_WIDE_INT) 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;
+ break;
- 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;
+ case STRING_CST:
+ p = TREE_STRING_POINTER (exp);
+ len = TREE_STRING_LENGTH (exp);
+ break;
- return hi;
- }
- else if (code == ADDR_EXPR)
- {
- struct addr_const value;
- decode_addr_const (exp, &value);
- if (GET_CODE (value.base) == SYMBOL_REF)
+ case COMPLEX_CST:
+ return (const_hash (TREE_REALPART (exp)) * 5
+ + const_hash (TREE_IMAGPART (exp)));
+
+ case CONSTRUCTOR:
+ if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
{
- /* Don't hash the address of the SYMBOL_REF;
- only use the offset and the symbol name. */
- hi = value.offset;
- p = XSTR (value.base, 0);
- for (i = 0; p[i] != 0; i++)
- hi = ((hi * 613) + (unsigned) (p[i]));
+ len = int_size_in_bytes (TREE_TYPE (exp));
+ p = (char *) alloca (len);
+ get_set_constructor_bytes (exp, (unsigned char *) p, len);
+ break;
}
- else if (GET_CODE (value.base) == LABEL_REF)
- hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13;
+ else
+ {
+ register tree link;
- hi &= (1 << HASHBITS) - 1;
- hi %= MAX_HASH_TABLE;
+ /* 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 = ((HOST_WIDE_INT) 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;
+
+ 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;
+
+ return hi;
+ }
+
+ case ADDR_EXPR:
+ {
+ struct addr_const value;
+
+ decode_addr_const (exp, &value);
+ if (GET_CODE (value.base) == SYMBOL_REF)
+ {
+ /* Don't hash the address of the SYMBOL_REF;
+ only use the offset and the symbol name. */
+ hi = value.offset;
+ p = XSTR (value.base, 0);
+ for (i = 0; p[i] != 0; i++)
+ hi = ((hi * 613) + (unsigned) (p[i]));
+ }
+ else if (GET_CODE (value.base) == LABEL_REF)
+ hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13;
+
+ 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)));
+
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
+ return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
}
- else if (code == PLUS_EXPR || code == MINUS_EXPR)
- return const_hash (TREE_OPERAND (exp, 0)) * 9
- + const_hash (TREE_OPERAND (exp, 1));
- else if (code == NOP_EXPR || code == CONVERT_EXPR)
- return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
/* Compute hashing function */
hi = len;
@@ -2456,122 +2476,146 @@ compare_constant_1 (exp, p)
if (code != (enum tree_code) *p++)
return 0;
- if (code == INTEGER_CST)
+ /* Either set STRP, P and LEN to pointers and length to compare and exit the
+ switch, or return the result of the comparison. */
+
+ switch (code)
{
+ case INTEGER_CST:
/* Integer constants are the same only if the same width of type. */
if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
return 0;
+
strp = (char *) &TREE_INT_CST_LOW (exp);
len = 2 * sizeof TREE_INT_CST_LOW (exp);
- }
- else if (code == REAL_CST)
- {
+ break;
+
+ case REAL_CST:
/* Real constants are the same only if the same width of type. */
if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
return 0;
+
strp = (char *) &TREE_REAL_CST (exp);
len = sizeof TREE_REAL_CST (exp);
- }
- else if (code == STRING_CST)
- {
+ break;
+
+ case STRING_CST:
if (flag_writable_strings)
return 0;
+
strp = TREE_STRING_POINTER (exp);
len = TREE_STRING_LENGTH (exp);
if (bcmp ((char *) &TREE_STRING_LENGTH (exp), p,
sizeof TREE_STRING_LENGTH (exp)))
return 0;
+
p += sizeof TREE_STRING_LENGTH (exp);
- }
- else if (code == COMPLEX_CST)
- {
- p = compare_constant_1 (TREE_REALPART (exp), p);
- if (p == 0) return 0;
- p = compare_constant_1 (TREE_IMAGPART (exp), p);
- return p;
- }
- else if (code == CONSTRUCTOR && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
- {
- int xlen = len = int_size_in_bytes (TREE_TYPE (exp));
- strp = (char *) alloca (len);
- get_set_constructor_bytes (exp, (unsigned char *) strp, len);
- if (bcmp ((char *) &xlen, p, sizeof xlen))
- return 0;
- p += sizeof xlen;
- }
- else if (code == CONSTRUCTOR)
- {
- register tree link;
- int length = list_length (CONSTRUCTOR_ELTS (exp));
- tree type;
+ break;
- if (bcmp ((char *) &length, p, sizeof length))
+ case COMPLEX_CST:
+ p = compare_constant_1 (TREE_REALPART (exp), p);
+ if (p == 0)
return 0;
- p += sizeof length;
- /* For record constructors, insist that the types match.
- For arrays, just verify both constructors are for arrays. */
- if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
- type = TREE_TYPE (exp);
- else
- type = 0;
- if (bcmp ((char *) &type, p, sizeof type))
- return 0;
- p += sizeof type;
+ return compare_constant_1 (TREE_IMAGPART (exp), p);
- /* For arrays, insist that the size in bytes match. */
- if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+ case CONSTRUCTOR:
+ if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
{
- int size = int_size_in_bytes (TREE_TYPE (exp));
- if (bcmp ((char *) &size, p, sizeof size))
+ int xlen = len = int_size_in_bytes (TREE_TYPE (exp));
+
+ strp = (char *) alloca (len);
+ get_set_constructor_bytes (exp, (unsigned char *) strp, len);
+ if (bcmp ((char *) &xlen, p, sizeof xlen))
return 0;
- p += sizeof size;
- }
- for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
+ p += sizeof xlen;
+ break;
+ }
+ else
{
- if (TREE_VALUE (link))
+ register tree link;
+ int length = list_length (CONSTRUCTOR_ELTS (exp));
+ tree type;
+
+ if (bcmp ((char *) &length, p, sizeof length))
+ return 0;
+
+ p += sizeof length;
+
+ /* For record constructors, insist that the types match.
+ For arrays, just verify both constructors are for arrays. */
+ if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
+ type = TREE_TYPE (exp);
+ else
+ type = 0;
+
+ if (bcmp ((char *) &type, p, sizeof type))
+ return 0;
+
+ p += sizeof type;
+
+ /* For arrays, insist that the size in bytes match. */
+ if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
{
- if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
+ int size = int_size_in_bytes (TREE_TYPE (exp));
+ if (bcmp ((char *) &size, p, sizeof size))
return 0;
+
+ p += sizeof size;
}
- else
+
+ for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
{
- tree zero = 0;
+ if (TREE_VALUE (link))
+ {
+ if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
+ return 0;
+ }
+ else
+ {
+ tree zero = 0;
- if (bcmp ((char *) &zero, p, sizeof zero))
- return 0;
- p += sizeof zero;
+ if (bcmp ((char *) &zero, p, sizeof zero))
+ return 0;
+
+ p += sizeof zero;
+ }
}
+
+ return p;
}
- return p;
- }
- else if (code == ADDR_EXPR)
- {
- struct addr_const value;
- decode_addr_const (exp, &value);
- strp = (char *) &value.offset;
- len = sizeof value.offset;
- /* Compare the offset. */
- while (--len >= 0)
- if (*p++ != *strp++)
- return 0;
- /* Compare symbol name. */
- strp = XSTR (value.base, 0);
- len = strlen (strp) + 1;
- }
- else if (code == PLUS_EXPR || code == MINUS_EXPR)
- {
- p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
- if (p == 0) return 0;
- p = compare_constant_1 (TREE_OPERAND (exp, 1), p);
- return p;
- }
- else if (code == NOP_EXPR || code == CONVERT_EXPR)
- {
+ case ADDR_EXPR:
+ {
+ struct addr_const value;
+
+ decode_addr_const (exp, &value);
+ strp = (char *) &value.offset;
+ len = sizeof value.offset;
+ /* Compare the offset. */
+ while (--len >= 0)
+ if (*p++ != *strp++)
+ return 0;
+
+ /* Compare symbol name. */
+ strp = XSTR (value.base, 0);
+ len = strlen (strp) + 1;
+ }
+ break;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
- return p;
+ if (p == 0)
+ return 0;
+
+ return compare_constant_1 (TREE_OPERAND (exp, 1), p);
+
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
+ return compare_constant_1 (TREE_OPERAND (exp, 0), p);
}
/* Compare constant contents. */
@@ -2834,6 +2878,7 @@ copy_constant (exp)
case NOP_EXPR:
case CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
return build1 (TREE_CODE (exp), TREE_TYPE (exp),
copy_constant (TREE_OPERAND (exp, 0)));
@@ -3833,7 +3878,8 @@ bc_assemble_integer (exp, size)
exp = fold (exp);
- while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR)
+ while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
+ || TREE_CODE (exp) == NON_LVALUE_EXPR)
exp = TREE_OPERAND (exp, 0);
if (TREE_CODE (exp) == INTEGER_CST)
{
@@ -3844,11 +3890,13 @@ bc_assemble_integer (exp, size)
{
const_part = TREE_OPERAND (exp, 0);
while (TREE_CODE (const_part) == NOP_EXPR
- || TREE_CODE (const_part) == CONVERT_EXPR)
+ || TREE_CODE (const_part) == CONVERT_EXPR
+ || TREE_CODE (const_part) == NON_LVALUE_EXPR)
const_part = TREE_OPERAND (const_part, 0);
addr_part = TREE_OPERAND (exp, 1);
while (TREE_CODE (addr_part) == NOP_EXPR
- || TREE_CODE (addr_part) == CONVERT_EXPR)
+ || TREE_CODE (addr_part) == CONVERT_EXPR
+ || TREE_CODE (addr_part) == NON_LVALUE_EXPR)
addr_part = TREE_OPERAND (addr_part, 0);
if (TREE_CODE (const_part) != INTEGER_CST)
tmp = const_part, const_part = addr_part, addr_part = tmp;