aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2000-10-20 20:57:21 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2000-10-20 16:57:21 -0400
commit235783d1f06a6107df508d57e1fd462220583afa (patch)
tree0a6fc6a8a2eadc64eb528baac5aba3b8271e3eed /gcc
parent948068e2ed9b6f34dc92cff5b6e846406f4b3a7e (diff)
downloadgcc-235783d1f06a6107df508d57e1fd462220583afa.zip
gcc-235783d1f06a6107df508d57e1fd462220583afa.tar.gz
gcc-235783d1f06a6107df508d57e1fd462220583afa.tar.bz2
expr.c (expand_expr, [...]): Set RTX_UNCHANGING_P on returned MEM.
* expr.c (expand_expr, case SAVE_EXPR): Set RTX_UNCHANGING_P on returned MEM. (expand_expr_unaligned, case ARRAY_REF): Check that index is a constant before comparing it; use tree_low_cst. * tree.c (save_expr): Set TREE_READONLY. (substitute_expr): Return inside of NON_LVALUE_EXPR. (build, build1): Set TREE_READONLY if all operands are. (build_index_type): If upper bound is a negative number, lower bound is zero and sizetype is unsigned, use upper bound of one and lower of zero. From-SVN: r36979
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/expr.c9
-rw-r--r--gcc/tree.c59
3 files changed, 64 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3fdb62f..1701c62 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+Fri Oct 20 17:05:49 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_expr, case SAVE_EXPR): Set RTX_UNCHANGING_P on
+ returned MEM.
+ (expand_expr_unaligned, case ARRAY_REF): Check that index is
+ a constant before comparing it; use tree_low_cst.
+ * tree.c (save_expr): Set TREE_READONLY.
+ (substitute_expr): Return inside of NON_LVALUE_EXPR.
+ (build, build1): Set TREE_READONLY if all operands are.
+ (build_index_type): If upper bound is a negative number, lower
+ bound is zero and sizetype is unsigned, use upper bound of one and
+ lower of zero.
+
2000-10-20 David Edelsohn <edelsohn@gnu.org>
* gcc.c (process_command, main): Use "because" instead of
diff --git a/gcc/expr.c b/gcc/expr.c
index 84e574d..cc3ec34 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6222,7 +6222,11 @@ expand_expr (exp, target, tmode, modifier)
if (mode == VOIDmode)
temp = const0_rtx;
else
- temp = assign_temp (type, 3, 0, 0);
+ {
+ temp = assign_temp (type, 3, 0, 0);
+ if (GET_CODE (temp) == MEM)
+ RTX_UNCHANGING_P (temp) = 1;
+ }
SAVE_EXPR_RTL (exp) = temp;
if (!optimize && GET_CODE (temp) == REG)
@@ -8683,6 +8687,7 @@ expand_expr_unaligned (exp, palign)
that was declared const. */
if (TREE_CODE (array) == CONSTRUCTOR && ! TREE_SIDE_EFFECTS (array)
+ && host_integerp (index, 0)
&& 0 > compare_tree_int (index,
list_length (CONSTRUCTOR_ELTS
(TREE_OPERAND (exp, 0)))))
@@ -8690,7 +8695,7 @@ expand_expr_unaligned (exp, palign)
tree elem;
for (elem = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)),
- i = TREE_INT_CST_LOW (index);
+ i = tree_low_cst (index, 0);
elem != 0 && i != 0; i--, elem = TREE_CHAIN (elem))
;
diff --git a/gcc/tree.c b/gcc/tree.c
index 7bd7a41..f4aae66 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1727,6 +1727,7 @@ save_expr (expr)
value was computed on both sides of the jump. So make sure it isn't
eliminated as dead. */
TREE_SIDE_EFFECTS (t) = 1;
+ TREE_READONLY (t) = 1;
return t;
}
@@ -2173,6 +2174,9 @@ substitute_in_expr (exp, f, r)
if (op0 == TREE_OPERAND (exp, 0))
return exp;
+ if (code == NON_LVALUE_EXPR)
+ return op0;
+
new = fold (build1 (code, TREE_TYPE (exp), op0));
break;
@@ -2488,10 +2492,10 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
length = TREE_CODE_LENGTH (code);
TREE_TYPE (t) = tt;
- /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_RAISED for
- the result based on those same flags for the arguments. But, if
- the arguments aren't really even `tree' expressions, we shouldn't
- be trying to do this. */
+ /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the
+ result based on those same flags for the arguments. But if the
+ arguments aren't really even `tree' expressions, we shouldn't be trying
+ to do this. */
fro = first_rtl_op (code);
if (length == 2)
@@ -2499,38 +2503,45 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
/* This is equivalent to the loop below, but faster. */
register tree arg0 = va_arg (p, tree);
register tree arg1 = va_arg (p, tree);
+
TREE_OPERAND (t, 0) = arg0;
TREE_OPERAND (t, 1) = arg1;
+ TREE_READONLY (t) = 1;
if (arg0 && fro > 0)
{
if (TREE_SIDE_EFFECTS (arg0))
TREE_SIDE_EFFECTS (t) = 1;
+ if (!TREE_READONLY (arg0))
+ TREE_READONLY (t) = 0;
}
+
if (arg1 && fro > 1)
{
if (TREE_SIDE_EFFECTS (arg1))
TREE_SIDE_EFFECTS (t) = 1;
+ if (!TREE_READONLY (arg1))
+ TREE_READONLY (t) = 0;
}
}
else if (length == 1)
{
register tree arg0 = va_arg (p, tree);
- /* Call build1 for this! */
+ /* The only one-operand cases we handle here are those with side-effects.
+ Others are handled with build1. So don't bother checked if the
+ arg has side-effects since we'll already have set it.
+
+ ??? This really should use build1 too. */
if (TREE_CODE_CLASS (code) != 's')
abort ();
TREE_OPERAND (t, 0) = arg0;
- if (fro > 0)
- {
- if (arg0 && TREE_SIDE_EFFECTS (arg0))
- TREE_SIDE_EFFECTS (t) = 1;
- }
}
else
{
for (i = 0; i < length; i++)
{
register tree operand = va_arg (p, tree);
+
TREE_OPERAND (t, i) = operand;
if (operand && fro > i)
{
@@ -2578,11 +2589,15 @@ build1 (code, type, node)
#endif
TREE_SET_CODE (t, code);
+
TREE_TYPE (t) = type;
TREE_COMPLEXITY (t) = 0;
TREE_OPERAND (t, 0) = node;
- if (node && first_rtl_op (code) != 0 && TREE_SIDE_EFFECTS (node))
- TREE_SIDE_EFFECTS (t) = 1;
+ if (node && first_rtl_op (code) != 0)
+ {
+ TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
+ TREE_READONLY (t) = TREE_READONLY (node);
+ }
switch (code)
{
@@ -2597,6 +2612,7 @@ build1 (code, type, node)
/* All of these have side-effects, no matter what their
operands are. */
TREE_SIDE_EFFECTS (t) = 1;
+ TREE_READONLY (t) = 0;
break;
default:
@@ -3802,12 +3818,25 @@ build_index_type (maxval)
tree maxval;
{
register tree itype = make_node (INTEGER_TYPE);
+ int no_hash = 0;
TREE_TYPE (itype) = sizetype;
TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
- TYPE_MIN_VALUE (itype) = size_zero_node;
- TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
+ /* If sizetype is unsigned and the upper bound is negative, use a
+ lower bound of one and an upper bound of zero. */
+ if (TREE_UNSIGNED (sizetype) && TREE_CODE (maxval) == INTEGER_CST
+ && tree_int_cst_sgn (maxval) < 0)
+ {
+ TYPE_MIN_VALUE (itype) = size_one_node;
+ TYPE_MAX_VALUE (itype) = size_zero_node;
+ no_hash = 1;
+ }
+ else
+ {
+ TYPE_MIN_VALUE (itype) = size_zero_node;
+ TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
+ }
TYPE_MODE (itype) = TYPE_MODE (sizetype);
TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
@@ -3815,7 +3844,7 @@ build_index_type (maxval)
TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype);
- if (host_integerp (maxval, 1))
+ if (!no_hash && host_integerp (maxval, 1))
return type_hash_canon (tree_low_cst (maxval, 1), itype);
else
return itype;