aboutsummaryrefslogtreecommitdiff
path: root/gcc/stmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r--gcc/stmt.c116
1 files changed, 54 insertions, 62 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 7aa29e7..0bcae69 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -2952,12 +2952,14 @@ expand_return (retval)
&& TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
&& GET_CODE (result_rtl) == REG)
{
- int i, bitpos, xbitpos;
- int big_endian_correction = 0;
- int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
+ int i;
+ unsigned HOST_WIDE_INT bitpos, xbitpos;
+ unsigned HOST_WIDE_INT big_endian_correction = 0;
+ unsigned HOST_WIDE_INT bytes
+ = int_size_in_bytes (TREE_TYPE (retval_rhs));
int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
- int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),
- (unsigned int)BITS_PER_WORD);
+ unsigned int bitsize
+ = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)), BITS_PER_WORD);
rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
rtx result_reg, src = NULL_RTX, dst = NULL_RTX;
rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
@@ -4905,8 +4907,8 @@ add_case_node (low, high, label, duplicate)
/* Returns the number of possible values of TYPE.
- Returns -1 if the number is unknown or variable.
- Returns -2 if the number does not fit in a HOST_WIDE_INT.
+ Returns -1 if the number is unknown, variable, or if the number does not
+ fit in a HOST_WIDE_INT.
Sets *SPARENESS to 2 if TYPE is an ENUMERAL_TYPE whose values
do not increase monotonically (there may be duplicates);
to 1 if the values increase monotonically, but not always by 1;
@@ -4917,73 +4919,60 @@ all_cases_count (type, spareness)
tree type;
int *spareness;
{
- HOST_WIDE_INT count;
+ tree t;
+ HOST_WIDE_INT count, minval, lastval;
+
*spareness = 0;
switch (TREE_CODE (type))
{
- tree t;
case BOOLEAN_TYPE:
count = 2;
break;
+
case CHAR_TYPE:
count = 1 << BITS_PER_UNIT;
break;
+
default:
case INTEGER_TYPE:
- if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
- || TYPE_MAX_VALUE (type) == NULL
- || TREE_CODE (TYPE_MAX_VALUE (type)) != INTEGER_CST)
- return -1;
+ if (TYPE_MAX_VALUE (type) != 0
+ && 0 != (t = fold (build (MINUS_EXPR, type, TYPE_MAX_VALUE (type),
+ TYPE_MIN_VALUE (type))))
+ && 0 != (t = fold (build (PLUS_EXPR, type, t,
+ convert (type, integer_zero_node))))
+ && host_integerp (t, 1))
+ count = tree_low_cst (t, 1);
else
- {
- /* count
- = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
- - TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + 1
- but with overflow checking. */
- tree mint = TYPE_MIN_VALUE (type);
- tree maxt = TYPE_MAX_VALUE (type);
- HOST_WIDE_INT lo, hi;
- neg_double(TREE_INT_CST_LOW (mint), TREE_INT_CST_HIGH (mint),
- &lo, &hi);
- add_double(TREE_INT_CST_LOW (maxt), TREE_INT_CST_HIGH (maxt),
- lo, hi, &lo, &hi);
- add_double (lo, hi, 1, 0, &lo, &hi);
- if (hi != 0 || lo < 0)
- return -2;
- count = lo;
- }
+ return -1;
break;
+
case ENUMERAL_TYPE:
+ /* Don't waste time with enumeral types with huge values. */
+ if (! host_integerp (TYPE_MIN_VALUE (type), 0)
+ || TYPE_MAX_VALUE (type) == 0
+ || ! host_integerp (TYPE_MAX_VALUE (type), 0))
+ return -1;
+
+ lastval = minval = tree_low_cst (TYPE_MIN_VALUE (type), 0);
count = 0;
+
for (t = TYPE_VALUES (type); t != NULL_TREE; t = TREE_CHAIN (t))
{
- if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
- || TREE_CODE (TREE_VALUE (t)) != INTEGER_CST
- || (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + count
- != TREE_INT_CST_LOW (TREE_VALUE (t))))
+ HOST_WIDE_INT thisval = tree_low_cst (TREE_VALUE (t), 0);
+
+ if (*spareness == 2 || thisval < lastval)
+ *spareness = 2;
+ else if (thisval != minval + count)
*spareness = 1;
+
count++;
}
- if (*spareness == 1)
- {
- tree prev = TREE_VALUE (TYPE_VALUES (type));
- for (t = TYPE_VALUES (type); t = TREE_CHAIN (t), t != NULL_TREE; )
- {
- if (! tree_int_cst_lt (prev, TREE_VALUE (t)))
- {
- *spareness = 2;
- break;
- }
- prev = TREE_VALUE (t);
- }
-
- }
}
+
return count;
}
-
#define BITARRAY_TEST(ARRAY, INDEX) \
((ARRAY)[(unsigned) (INDEX) / HOST_BITS_PER_CHAR]\
& (1 << ((unsigned) (INDEX) % HOST_BITS_PER_CHAR)))
@@ -5003,21 +4992,22 @@ void
mark_seen_cases (type, cases_seen, count, sparseness)
tree type;
unsigned char *cases_seen;
- long count;
+ HOST_WIDE_INT count;
int sparseness;
{
tree next_node_to_try = NULL_TREE;
- long next_node_offset = 0;
+ HOST_WIDE_INT next_node_offset = 0;
register struct case_node *n, *root = case_stack->data.case_stmt.case_list;
tree val = make_node (INTEGER_CST);
+
TREE_TYPE (val) = type;
if (! root)
; /* Do nothing */
else if (sparseness == 2)
{
tree t;
- HOST_WIDE_INT xlo;
+ unsigned HOST_WIDE_INT xlo;
/* This less efficient loop is only needed to handle
duplicate case values (multiple enum constants
@@ -5053,6 +5043,7 @@ mark_seen_cases (type, cases_seen, count, sparseness)
{
if (root->left)
case_stack->data.case_stmt.case_list = root = case_tree2list (root, 0);
+
for (n = root; n; n = n->right)
{
TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (n->low);
@@ -5063,8 +5054,10 @@ mark_seen_cases (type, cases_seen, count, sparseness)
The element with lowest value has offset 0, the next smallest
element has offset 1, etc. */
- HOST_WIDE_INT xlo, xhi;
+ unsigned HOST_WIDE_INT xlo;
+ HOST_WIDE_INT xhi;
tree t;
+
if (sparseness && TYPE_VALUES (type) != NULL_TREE)
{
/* The TYPE_VALUES will be in increasing order, so
@@ -5107,8 +5100,9 @@ mark_seen_cases (type, cases_seen, count, sparseness)
&xlo, &xhi);
}
- if (xhi == 0 && xlo >= 0 && xlo < count)
+ if (xhi == 0 && xlo < (unsigned HOST_WIDE_INT) count)
BITARRAY_SET (cases_seen, xlo);
+
add_double (TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
1, 0,
&TREE_INT_CST_LOW (val), &TREE_INT_CST_HIGH (val));
@@ -5150,7 +5144,7 @@ check_for_full_enumeration_handling (type)
unsigned char *cases_seen;
/* The allocated size of cases_seen, in chars. */
- long bytes_needed;
+ HOST_WIDE_INT bytes_needed;
if (! warn_switch)
return;
@@ -5164,7 +5158,7 @@ check_for_full_enumeration_handling (type)
aborting, as xmalloc would do. */
&& (cases_seen = (unsigned char *) calloc (bytes_needed, 1)) != NULL)
{
- long i;
+ HOST_WIDE_INT i;
tree v = TYPE_VALUES (type);
/* The time complexity of this code is normally O(N), where
@@ -5174,12 +5168,10 @@ check_for_full_enumeration_handling (type)
mark_seen_cases (type, cases_seen, size, sparseness);
- for (i = 0; v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v))
- {
- if (BITARRAY_TEST(cases_seen, i) == 0)
- warning ("enumeration value `%s' not handled in switch",
- IDENTIFIER_POINTER (TREE_PURPOSE (v)));
- }
+ for (i = 0; v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v))
+ if (BITARRAY_TEST(cases_seen, i) == 0)
+ warning ("enumeration value `%s' not handled in switch",
+ IDENTIFIER_POINTER (TREE_PURPOSE (v)));
free (cases_seen);
}