tree.h (contains_placeholder_p): Now returns bool.

* tree.h (contains_placeholder_p): Now returns bool.
	(CONTAINS_PLACEHOLDER_P): New macro.
	(type_contains_placeholder_p): New function.
	* tree.c (save_expr): Remove code avoiding folding COMPONENT_REF.
	(contains_placeholder_p): Now returns bool.
	Rework to use CONTAINS_PLACEHOLDER_P macro.
	(type_contains_placeholder_p): New function.
	* fold-const.c (fold, case COMPONENT_REF): Don't fold if
	type_contains_placeholder_p.
	(fold_range_test, fold_mathfn_compare, fold_inf_compare, fold):
	Use CONTAINS_PLACEHOLDER_P macro.
	* builtins.c (fold_builtin): Likewise.
	* calls.c (initialize_argument_information): Likewise.
	* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
	* explow.c (expr_size): Likewise.
	* expr.c (store_constructor, get_inner_reference): Likewise.
	* function.c (assign_parms): Likewise.
	* stor-layout.c (variable_size): Likewise.

From-SVN: r67189
This commit is contained in:
Richard Kenner 2003-05-27 14:44:57 -04:00 committed by Richard Kenner
parent 86982c71d1
commit 7a6cdb44fd
10 changed files with 176 additions and 52 deletions

View File

@ -1,3 +1,24 @@
2003-05027 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* tree.h (contains_placeholder_p): Now returns bool.
(CONTAINS_PLACEHOLDER_P): New macro.
(type_contains_placeholder_p): New function.
* tree.c (save_expr): Remove code avoiding folding COMPONENT_REF.
(contains_placeholder_p): Now returns bool.
Rework to use CONTAINS_PLACEHOLDER_P macro.
(type_contains_placeholder_p): New function.
* fold-const.c (fold, case COMPONENT_REF): Don't fold if
type_contains_placeholder_p.
(fold_range_test, fold_mathfn_compare, fold_inf_compare, fold):
Use CONTAINS_PLACEHOLDER_P macro.
* builtins.c (fold_builtin): Likewise.
* calls.c (initialize_argument_information): Likewise.
* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
* explow.c (expr_size): Likewise.
* expr.c (store_constructor, get_inner_reference): Likewise.
* function.c (assign_parms): Likewise.
* stor-layout.c (variable_size): Likewise.
2003-05-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
* diagnostic.h (output_verbatim, verbatim): Remove printf

View File

@ -5242,7 +5242,7 @@ fold_builtin (exp)
/* Optimize pow(x,2.0) = x*x. */
if (REAL_VALUES_EQUAL (c, dconst2)
&& (*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (arg0))
&& ! CONTAINS_PLACEHOLDER_P (arg0))
{
arg0 = save_expr (arg0);
return fold (build (MULT_EXPR, type, arg0, arg0));
@ -5252,7 +5252,7 @@ fold_builtin (exp)
if (flag_unsafe_math_optimizations
&& REAL_VALUES_EQUAL (c, dconstm2)
&& (*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (arg0))
&& ! CONTAINS_PLACEHOLDER_P (arg0))
{
arg0 = save_expr (arg0);
return fold (build (RDIV_EXPR, type,

View File

@ -1146,8 +1146,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
with those made by function.c. */
/* See if this argument should be passed by invisible reference. */
if ((TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
&& contains_placeholder_p (TYPE_SIZE (type)))
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
|| TREE_ADDRESSABLE (type)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
|| FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type),

View File

@ -1986,11 +1986,9 @@ set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
/* If the index has a self-referential type, pass it to a
WITH_RECORD_EXPR; if the component size is, pass our
component to one. */
if (! TREE_CONSTANT (index)
&& contains_placeholder_p (index))
if (CONTAINS_PLACEHOLDER_P (index))
index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, t);
if (! TREE_CONSTANT (unit_size)
&& contains_placeholder_p (unit_size))
if (CONTAINS_PLACEHOLDER_P (unit_size))
unit_size = build (WITH_RECORD_EXPR, sizetype,
unit_size, array);

View File

@ -294,8 +294,7 @@ expr_size (exp)
{
tree size = (*lang_hooks.expr_size) (exp);
if (TREE_CODE (size) != INTEGER_CST
&& contains_placeholder_p (size))
if (CONTAINS_PLACEHOLDER_P (size))
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);

View File

@ -4982,7 +4982,7 @@ store_constructor (exp, target, cleared, size)
{
rtx offset_rtx;
if (contains_placeholder_p (offset))
if (CONTAINS_PLACEHOLDER_P (offset))
offset = build (WITH_RECORD_EXPR, sizetype,
offset, make_tree (TREE_TYPE (exp), target));
@ -5799,7 +5799,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
made during type construction. */
if (this_offset == 0)
break;
else if (contains_placeholder_p (this_offset))
else if (CONTAINS_PLACEHOLDER_P (this_offset))
this_offset = build (WITH_RECORD_EXPR, sizetype, this_offset, exp);
offset = size_binop (PLUS_EXPR, offset, this_offset);
@ -5829,9 +5829,9 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
/* If the index has a self-referential type, pass it to a
WITH_RECORD_EXPR; if the component size is, pass our
component to one. */
if (contains_placeholder_p (index))
if (CONTAINS_PLACEHOLDER_P (index))
index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, exp);
if (contains_placeholder_p (unit_size))
if (CONTAINS_PLACEHOLDER_P (unit_size))
unit_size = build (WITH_RECORD_EXPR, sizetype, unit_size, array);
offset = size_binop (PLUS_EXPR, offset,

View File

@ -3470,7 +3470,7 @@ fold_range_test (exp)
TREE_OPERAND (exp, 1));
else if ((*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (lhs))
&& ! CONTAINS_PLACEHOLDER_P (lhs))
{
tree common = save_expr (lhs);
@ -4768,7 +4768,7 @@ fold_mathfn_compare (fcode, code, type, arg0, arg1)
/* sqrt(x) < y is x >= 0 && x != +Inf, when y is large. */
if ((*lang_hooks.decls.global_bindings_p) () != 0
|| contains_placeholder_p (arg))
|| CONTAINS_PLACEHOLDER_P (arg))
return NULL_TREE;
arg = save_expr (arg);
@ -4788,7 +4788,7 @@ fold_mathfn_compare (fcode, code, type, arg0, arg1)
/* sqrt(x) < c is the same as x >= 0 && x < c*c. */
if ((*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (arg))
&& ! CONTAINS_PLACEHOLDER_P (arg))
{
arg = save_expr (arg);
return fold (build (TRUTH_ANDIF_EXPR, type,
@ -4851,7 +4851,7 @@ fold_inf_compare (code, type, arg0, arg1)
/* x <= +Inf is the same as x == x, i.e. isfinite(x). */
if ((*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (arg0))
&& ! CONTAINS_PLACEHOLDER_P (arg0))
{
arg0 = save_expr (arg0);
return fold (build (EQ_EXPR, type, arg0, arg0));
@ -5119,7 +5119,7 @@ fold (expr)
|| count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
&& (! TREE_SIDE_EFFECTS (arg0)
|| ((*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (arg0))))
&& ! CONTAINS_PLACEHOLDER_P (arg0))))
return
fold_binary_op_with_conditional_arg (code, type, arg1, arg0,
/*cond_first_p=*/0);
@ -5133,7 +5133,7 @@ fold (expr)
|| count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
&& (! TREE_SIDE_EFFECTS (arg1)
|| ((*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (arg1))))
&& ! CONTAINS_PLACEHOLDER_P (arg1))))
return
fold_binary_op_with_conditional_arg (code, type, arg0, arg1,
/*cond_first_p=*/1);
@ -5313,7 +5313,8 @@ fold (expr)
return t;
case COMPONENT_REF:
if (TREE_CODE (arg0) == CONSTRUCTOR)
if (TREE_CODE (arg0) == CONSTRUCTOR
&& ! type_contains_placeholder_p (TREE_TYPE (arg0)))
{
tree m = purpose_member (arg1, CONSTRUCTOR_ELTS (arg0));
if (m)
@ -5883,7 +5884,7 @@ fold (expr)
/* x*2 is x+x */
if (! wins && real_twop (arg1)
&& (*lang_hooks.decls.global_bindings_p) () == 0
&& ! contains_placeholder_p (arg0))
&& ! CONTAINS_PLACEHOLDER_P (arg0))
{
tree arg = save_expr (arg0);
return fold (build (PLUS_EXPR, type, arg, arg));

View File

@ -4494,8 +4494,7 @@ assign_parms (fndecl)
object itself or if the machine requires these objects be passed
that way. */
if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
&& contains_placeholder_p (TYPE_SIZE (passed_type)))
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (passed_type))
|| TREE_ADDRESSABLE (passed_type)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
|| FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,

View File

@ -1390,15 +1390,9 @@ tree
save_expr (expr)
tree expr;
{
tree t = expr;
tree t = fold (expr);
tree inner;
/* Don't fold a COMPONENT_EXPR: if the operand was a CONSTRUCTOR (the
only time it will fold), it can cause problems with PLACEHOLDER_EXPRs
in Ada. Moreover, it isn't at all clear why we fold here at all. */
if (TREE_CODE (t) != COMPONENT_REF)
t = fold (t);
/* If the tree evaluates to a constant, then we don't want to hide that
fact (i.e. this allows further folding, and direct checks for constants).
However, a read-only object that has side effects cannot be bypassed.
@ -1745,7 +1739,7 @@ unsafe_for_reeval (expr)
/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
or offset that depends on a field within a record. */
int
bool
contains_placeholder_p (exp)
tree exp;
{
@ -1770,13 +1764,12 @@ contains_placeholder_p (exp)
position computations since they will be converted into a
WITH_RECORD_EXPR involving the reference, which will assume
here will be valid. */
return contains_placeholder_p (TREE_OPERAND (exp, 0));
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
case 'x':
if (code == TREE_LIST)
return (contains_placeholder_p (TREE_VALUE (exp))
|| (TREE_CHAIN (exp) != 0
&& contains_placeholder_p (TREE_CHAIN (exp))));
return (CONTAINS_PLACEHOLDER_P (TREE_VALUE (exp))
|| CONTAINS_PLACEHOLDER_P (TREE_CHAIN (exp)));
break;
case '1':
@ -1786,16 +1779,16 @@ contains_placeholder_p (exp)
{
case COMPOUND_EXPR:
/* Ignoring the first operand isn't quite right, but works best. */
return contains_placeholder_p (TREE_OPERAND (exp, 1));
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
case RTL_EXPR:
case CONSTRUCTOR:
return 0;
case COND_EXPR:
return (contains_placeholder_p (TREE_OPERAND (exp, 0))
|| contains_placeholder_p (TREE_OPERAND (exp, 1))
|| contains_placeholder_p (TREE_OPERAND (exp, 2)));
return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
case SAVE_EXPR:
/* If we already know this doesn't have a placeholder, don't
@ -1804,15 +1797,14 @@ contains_placeholder_p (exp)
return 0;
SAVE_EXPR_NOPLACEHOLDER (exp) = 1;
result = contains_placeholder_p (TREE_OPERAND (exp, 0));
result = CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
if (result)
SAVE_EXPR_NOPLACEHOLDER (exp) = 0;
return result;
case CALL_EXPR:
return (TREE_OPERAND (exp, 1) != 0
&& contains_placeholder_p (TREE_OPERAND (exp, 1)));
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
default:
break;
@ -1821,10 +1813,10 @@ contains_placeholder_p (exp)
switch (TREE_CODE_LENGTH (code))
{
case 1:
return contains_placeholder_p (TREE_OPERAND (exp, 0));
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
case 2:
return (contains_placeholder_p (TREE_OPERAND (exp, 0))
|| contains_placeholder_p (TREE_OPERAND (exp, 1)));
return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)));
default:
return 0;
}
@ -1835,6 +1827,109 @@ contains_placeholder_p (exp)
return 0;
}
/* Return 1 if any part of the computation of TYPE involves a PLACEHOLDER_EXPR.
This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and field
positions. */
bool
type_contains_placeholder_p (type)
tree type;
{
/* If the size contains a placeholder or the parent type (component type in
the case of arrays) type involves a placeholder, this type does. */
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
|| CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (type))
|| (TREE_TYPE (type) != 0
&& type_contains_placeholder_p (TREE_TYPE (type))))
return 1;
/* Now do type-specific checks. Note that the last part of the check above
greatly limits what we have to do below. */
switch (TREE_CODE (type))
{
case VOID_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
case CHAR_TYPE:
case POINTER_TYPE:
case OFFSET_TYPE:
case REFERENCE_TYPE:
case METHOD_TYPE:
case FILE_TYPE:
case FUNCTION_TYPE:
return 0;
case INTEGER_TYPE:
case REAL_TYPE:
/* Here we just check the bounds. */
return (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (type))
|| CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));
case ARRAY_TYPE:
case SET_TYPE:
/* We're already checked the component type (TREE_TYPE), so just check
the index type. */
return type_contains_placeholder_p (TYPE_DOMAIN (type));
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
{
static tree seen_types = 0;
tree field;
bool ret = 0;
/* We have to be careful here that we don't end up in infinite
recursions due to a field of a type being a pointer to that type
or to a mutually-recursive type. So we store a list of record
types that we've seen and see if this type is in them. To save
memory, we don't use a list for just one type. Here we check
whether we've seen this type before and store it if not. */
if (seen_types == 0)
seen_types = type;
else if (TREE_CODE (seen_types) != TREE_LIST)
{
if (seen_types == type)
return 0;
seen_types = tree_cons (NULL_TREE, type,
build_tree_list (NULL_TREE, seen_types));
}
else
{
if (value_member (type, seen_types) != 0)
return 0;
seen_types = tree_cons (NULL_TREE, type, seen_types);
}
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL
&& (CONTAINS_PLACEHOLDER_P (DECL_FIELD_OFFSET (field))
|| (TREE_CODE (type) == QUAL_UNION_TYPE
&& CONTAINS_PLACEHOLDER_P (DECL_QUALIFIER (field)))
|| type_contains_placeholder_p (TREE_TYPE (field))))
{
ret = true;
break;
}
/* Now remove us from seen_types and return the result. */
if (seen_types == type)
seen_types = 0;
else
seen_types = TREE_CHAIN (seen_types);
return ret;
}
default:
abort ();
}
}
/* Return 1 if EXP contains any expressions that produce cleanups for an
outer scope to deal with. Used by fold. */
@ -1960,9 +2055,9 @@ substitute_in_expr (exp, f, r)
op0 = TREE_OPERAND (exp, 0);
op1 = TREE_OPERAND (exp, 1);
if (contains_placeholder_p (op0))
if (CONTAINS_PLACEHOLDER_P (op0))
op0 = substitute_in_expr (op0, f, r);
if (contains_placeholder_p (op1))
if (CONTAINS_PLACEHOLDER_P (op1))
op1 = substitute_in_expr (op1, f, r);
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
@ -1994,11 +2089,11 @@ substitute_in_expr (exp, f, r)
op1 = TREE_OPERAND (exp, 1);
op2 = TREE_OPERAND (exp, 2);
if (contains_placeholder_p (op0))
if (CONTAINS_PLACEHOLDER_P (op0))
op0 = substitute_in_expr (op0, f, r);
if (contains_placeholder_p (op1))
if (CONTAINS_PLACEHOLDER_P (op1))
op1 = substitute_in_expr (op1, f, r);
if (contains_placeholder_p (op2))
if (CONTAINS_PLACEHOLDER_P (op2))
op2 = substitute_in_expr (op2, f, r);
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)

View File

@ -2523,7 +2523,19 @@ extern int unsafe_for_reeval PARAMS ((tree));
Note that we only allow such expressions within simple arithmetic
or a COND_EXPR. */
extern int contains_placeholder_p PARAMS ((tree));
extern bool contains_placeholder_p PARAMS ((tree));
/* This macro calls the above function but short-circuits the common
case of a constant to save time. Also check for null. */
#define CONTAINS_PLACEHOLDER_P(EXP) \
((EXP) != 0 && ! TREE_CONSTANT (EXP) && contains_placeholder_p (EXP))
/* Return 1 if any part of the computation of TYPE involves a PLACEHOLDER_EXPR.
This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and field
positions. */
extern bool type_contains_placeholder_p PARAMS ((tree));
/* Return 1 if EXP contains any expressions that produce cleanups for an
outer scope to deal with. Used by fold. */