alias.c (get_alias_set): Remove handling of PLACEHOLDER_EXPR.

* alias.c (get_alias_set): Remove handling of PLACEHOLDER_EXPR.
	* emit-rtl.c (component_ref_for_mem_expr): Likewise.
	(set_mem_attributes_minus_bitpos): Call SUBSTITUTE_PLACEHOLDER_IN_EXPR.
	* explow.c (expr_size): Likewise.
	* expr.h (placeholder_list, find_placeholder): Deleted.
	* expr.c (store_constructor): Likewise.
	(get_inner_reference): Likewise.  Also don't call find_placeholder.
	(placeholder_list, find_placeholder): Deleted.
	(is_aligning_offset): Don't handle WITH_RECORD_EXPR, PLACEHOLDER_EXPR.
	(expand_expr_real, cases PLACEHOLDER_EXPR, WITH_RECORD_EXPR): Likewise.
	(highest_pow2_factor, case WITH_RECORD_EXPR): Remove.
	* dojump.c (do_jump, case WITH_RECORD_EXPR): Likewise.
	* dwarf2out.c (loc_descriptor_from_tree, case WITH_RECORD_EXPR):
	Likewise.
	* fold-const.c (invert_truthvalue, case WITH_RECORD_EXPR): Likewise.
	(extract_muldiv, case WITH_RECORD_EXPR): Likewise.
	* tree.c (expr_align, case WITH_RECORD_EXPR): Likewise.
	(contains_placeholder_p): Don't handle WITH_RECORD_EXPR.
	Clean up by using first_rtl_op.
	(substitute_in_expr): Use SUBSTITUTE_IN_EXPR for recursive call.
	(substitute_placeholder_in_expr): New function.
	* tree.def (WITH_RECORD_EXPR): Deleted.
	* tree.h (SUBSTITUTE_IN_EXPR, SUBSTITUTE_PLACEHOLDER_IN_EXPR): New.
	(substitute_placeholder_in_expr): New.

	* ada/decl.c (gnat_to_gnu_entity): Use SUBSTITUTE_PLACEHOLDER_IN_EXPR.
	* ada/trans.c (tree_transform, emit_index_check): Likewise.
	* ada/utils.c (build_template): Likewise.
	(max_size, convert): Remove handling of WITH_RECORD_EXPR.
	(maybe_unconstrained_array, unchecked_convert): Likewise.
	* ada/utils2.c (gnat_truthvalue_conversion, build_binary_op): Likewise.
	(build_unary_op): Likewise.
	(compare_arrays, build_allocator): Use SUBSTITUTE_PLACEHOLDER_IN_EXPR.
	(fill_vms_descriptor): Likewise.
	(build_call_alloc_dealloc): Likewise.
	ALIGN is unsigned.
	* ada/gigi.h (build_call_alloc_dealloc): Alignment is unsigned.

From-SVN: r79789
This commit is contained in:
Richard Kenner 2004-03-21 18:09:20 +00:00 committed by Richard Kenner
parent fc5fccdee9
commit 6fce44af56
18 changed files with 260 additions and 391 deletions

View File

@ -1,3 +1,30 @@
2004-03-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* alias.c (get_alias_set): Remove handling of PLACEHOLDER_EXPR.
* emit-rtl.c (component_ref_for_mem_expr): Likewise.
(set_mem_attributes_minus_bitpos): Call SUBSTITUTE_PLACEHOLDER_IN_EXPR.
* explow.c (expr_size): Likewise.
* expr.h (placeholder_list, find_placeholder): Deleted.
* expr.c (store_constructor): Likewise.
(get_inner_reference): Likewise. Also don't call find_placeholder.
(placeholder_list, find_placeholder): Deleted.
(is_aligning_offset): Don't handle WITH_RECORD_EXPR, PLACEHOLDER_EXPR.
(expand_expr_real, cases PLACEHOLDER_EXPR, WITH_RECORD_EXPR): Likewise.
(highest_pow2_factor, case WITH_RECORD_EXPR): Remove.
* dojump.c (do_jump, case WITH_RECORD_EXPR): Likewise.
* dwarf2out.c (loc_descriptor_from_tree, case WITH_RECORD_EXPR):
Likewise.
* fold-const.c (invert_truthvalue, case WITH_RECORD_EXPR): Likewise.
(extract_muldiv, case WITH_RECORD_EXPR): Likewise.
* tree.c (expr_align, case WITH_RECORD_EXPR): Likewise.
(contains_placeholder_p): Don't handle WITH_RECORD_EXPR.
Clean up by using first_rtl_op.
(substitute_in_expr): Use SUBSTITUTE_IN_EXPR for recursive call.
(substitute_placeholder_in_expr): New function.
* tree.def (WITH_RECORD_EXPR): Deleted.
* tree.h (SUBSTITUTE_IN_EXPR, SUBSTITUTE_PLACEHOLDER_IN_EXPR): New.
(substitute_placeholder_in_expr): New.
2004-03-21 Andrew Pinski <pinskia@gcc.gnu.org> 2004-03-21 Andrew Pinski <pinskia@gcc.gnu.org>
* dojump.c (prefer_and_bit_test): Fix which part of * dojump.c (prefer_and_bit_test): Fix which part of

View File

@ -1,3 +1,18 @@
2004-03-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* decl.c (gnat_to_gnu_entity): Use SUBSTITUTE_PLACEHOLDER_IN_EXPR.
* trans.c (tree_transform, emit_index_check): Likewise.
* utils.c (build_template): Likewise.
(max_size, convert): Remove handling of WITH_RECORD_EXPR.
(maybe_unconstrained_array, unchecked_convert): Likewise.
* utils2.c (gnat_truthvalue_conversion, build_binary_op): Likewise.
(build_unary_op): Likewise.
(compare_arrays, build_allocator): Use SUBSTITUTE_PLACEHOLDER_IN_EXPR.
(fill_vms_descriptor): Likewise.
(build_call_alloc_dealloc): Likewise.
ALIGN is unsigned.
* gigi.h (build_call_alloc_dealloc): Alignment is unsigned.
2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk> 2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk>
PR other/14630 PR other/14630

View File

@ -565,12 +565,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type))) && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
{ {
if (gnu_expr != 0 && kind == E_Constant) if (gnu_expr != 0 && kind == E_Constant)
{ gnu_size
gnu_size = TYPE_SIZE (TREE_TYPE (gnu_expr)); = SUBSTITUTE_PLACEHOLDER_IN_EXPR
if (CONTAINS_PLACEHOLDER_P (gnu_size)) (TYPE_SIZE (TREE_TYPE (gnu_expr)), gnu_expr);
gnu_size = build (WITH_RECORD_EXPR, bitsizetype,
gnu_size, gnu_expr);
}
/* We may have no GNU_EXPR because No_Initialization is /* We may have no GNU_EXPR because No_Initialization is
set even though there's an Expression. */ set even though there's an Expression. */

View File

@ -701,7 +701,7 @@ extern tree build_component_ref (tree, tree, tree, int);
GNU_SIZE is the size of the object and ALIGN is the alignment. GNU_SIZE is the size of the object and ALIGN is the alignment.
GNAT_PROC, if present is a procedure to call and GNAT_POOL is the GNAT_PROC, if present is a procedure to call and GNAT_POOL is the
storage pool to use. If not preset, malloc and free will be used. */ storage pool to use. If not preset, malloc and free will be used. */
extern tree build_call_alloc_dealloc (tree, tree, int, Entity_Id, extern tree build_call_alloc_dealloc (tree, tree, unsigned int, Entity_Id,
Entity_Id, Node_Id); Entity_Id, Node_Id);
/* Build a GCC tree to correspond to allocating an object of TYPE whose /* Build a GCC tree to correspond to allocating an object of TYPE whose

View File

@ -1236,8 +1236,8 @@ tree_transform (Node_Id gnat_node)
if (CONTAINS_PLACEHOLDER_P (gnu_result)) if (CONTAINS_PLACEHOLDER_P (gnu_result))
{ {
if (TREE_CODE (gnu_prefix) != TYPE_DECL) if (TREE_CODE (gnu_prefix) != TYPE_DECL)
gnu_result = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_result), gnu_result = substitute_placeholder_in_expr (gnu_result,
gnu_result, gnu_expr); gnu_expr);
else else
gnu_result = max_size (gnu_result, 1); gnu_result = max_size (gnu_result, 1);
} }
@ -1381,9 +1381,8 @@ tree_transform (Node_Id gnat_node)
/* If this has a PLACEHOLDER_EXPR, qualify it by the object /* If this has a PLACEHOLDER_EXPR, qualify it by the object
we are handling. Note that these attributes could not we are handling. Note that these attributes could not
have been used on an unconstrained array type. */ have been used on an unconstrained array type. */
if (CONTAINS_PLACEHOLDER_P (gnu_result)) gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result,
gnu_result = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_result), gnu_prefix);
gnu_result, gnu_prefix);
break; break;
} }
@ -1486,9 +1485,8 @@ tree_transform (Node_Id gnat_node)
/* If this has a PLACEHOLDER_EXPR, qualify it by the object /* If this has a PLACEHOLDER_EXPR, qualify it by the object
we are handling. */ we are handling. */
if (CONTAINS_PLACEHOLDER_P (gnu_result)) gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result,
gnu_result = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_result), gnu_prefix);
gnu_result, gnu_prefix);
break; break;
} }
@ -1496,7 +1494,7 @@ tree_transform (Node_Id gnat_node)
case Attr_Min: case Attr_Min:
case Attr_Max: case Attr_Max:
gnu_lhs = gnat_to_gnu (First (Expressions (gnat_node))); gnu_lhs = gnat_to_gnu (First (Expressions (gnat_node)));
gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node)))); gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node))));
gnu_result_type = get_unpadded_type (Etype (gnat_node)); gnu_result_type = get_unpadded_type (Etype (gnat_node));
gnu_result = build_binary_op (attribute == Attr_Min gnu_result = build_binary_op (attribute == Attr_Min
@ -4622,13 +4620,8 @@ emit_index_check (tree gnu_array_object,
/* If GNU_LOW or GNU_HIGH are a PLACEHOLDER_EXPR, qualify them by /* If GNU_LOW or GNU_HIGH are a PLACEHOLDER_EXPR, qualify them by
the object we are handling. */ the object we are handling. */
if (CONTAINS_PLACEHOLDER_P (gnu_low)) gnu_low = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_low, gnu_array_object);
gnu_low = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_low), gnu_high = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_high, gnu_array_object);
gnu_low, gnu_array_object);
if (CONTAINS_PLACEHOLDER_P (gnu_high))
gnu_high = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_high),
gnu_high, gnu_array_object);
/* There's no good type to use here, so we might as well use /* There's no good type to use here, so we might as well use
integer_type_node. */ integer_type_node. */

View File

@ -2180,8 +2180,6 @@ max_size (tree exp, int max_p)
gigi_abort (407); gigi_abort (407);
else if (code == COMPOUND_EXPR) else if (code == COMPOUND_EXPR)
return max_size (TREE_OPERAND (exp, 1), max_p); return max_size (TREE_OPERAND (exp, 1), max_p);
else if (code == WITH_RECORD_EXPR)
return exp;
{ {
tree lhs = max_size (TREE_OPERAND (exp, 0), max_p); tree lhs = max_size (TREE_OPERAND (exp, 0), max_p);
@ -2275,12 +2273,9 @@ build_template (tree template_type, tree array_type, tree expr)
max = convert (TREE_TYPE (field), TYPE_MAX_VALUE (bounds)); max = convert (TREE_TYPE (field), TYPE_MAX_VALUE (bounds));
/* If either MIN or MAX involve a PLACEHOLDER_EXPR, we must /* If either MIN or MAX involve a PLACEHOLDER_EXPR, we must
surround them with a WITH_RECORD_EXPR giving EXPR as the substitute it from OBJECT. */
OBJECT. */ min = SUBSTITUTE_PLACEHOLDER_IN_EXPR (min, expr);
if (CONTAINS_PLACEHOLDER_P (min)) max = SUBSTITUTE_PLACEHOLDER_IN_EXPR (max, expr);
min = build (WITH_RECORD_EXPR, TREE_TYPE (min), min, expr);
if (CONTAINS_PLACEHOLDER_P (max))
max = build (WITH_RECORD_EXPR, TREE_TYPE (max), max, expr);
template_elts = tree_cons (TREE_CHAIN (field), max, template_elts = tree_cons (TREE_CHAIN (field), max,
tree_cons (field, min, template_elts)); tree_cons (field, min, template_elts));
@ -2865,12 +2860,6 @@ convert (tree type, tree expr)
else if (AGGREGATE_TYPE_P (type) else if (AGGREGATE_TYPE_P (type)
&& TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype)) && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype))
return build1 (NOP_EXPR, type, expr); return build1 (NOP_EXPR, type, expr);
/* If EXPR is a WITH_RECORD_EXPR, do the conversion inside and then make a
new one. */
else if (TREE_CODE (expr) == WITH_RECORD_EXPR)
return build (WITH_RECORD_EXPR, type,
convert (type, TREE_OPERAND (expr, 0)),
TREE_OPERAND (expr, 1));
/* If the input type has padding, remove it by doing a component reference /* If the input type has padding, remove it by doing a component reference
to the field. If the output type has padding, make a constructor to the field. If the output type has padding, make a constructor
@ -3250,13 +3239,6 @@ maybe_unconstrained_array (tree exp)
(TREE_TYPE (TREE_TYPE (exp))))), (TREE_TYPE (TREE_TYPE (exp))))),
TREE_OPERAND (exp, 0)); TREE_OPERAND (exp, 0));
else if (code == WITH_RECORD_EXPR
&& (TREE_OPERAND (exp, 0)
!= (new = maybe_unconstrained_array
(TREE_OPERAND (exp, 0)))))
return build (WITH_RECORD_EXPR, TREE_TYPE (new), new,
TREE_OPERAND (exp, 1));
case RECORD_TYPE: case RECORD_TYPE:
/* If this is a padded type, convert to the unpadded type and see if /* If this is a padded type, convert to the unpadded type and see if
it contains a template. */ it contains a template. */
@ -3295,13 +3277,6 @@ unchecked_convert (tree type, tree expr, int notrunc_p)
if (etype == type) if (etype == type)
return expr; return expr;
/* If EXPR is a WITH_RECORD_EXPR, do the conversion inside and then make a
new one. */
if (TREE_CODE (expr) == WITH_RECORD_EXPR)
return build (WITH_RECORD_EXPR, type,
unchecked_convert (type, TREE_OPERAND (expr, 0), notrunc_p),
TREE_OPERAND (expr, 1));
/* If both types types are integral just do a normal conversion. /* If both types types are integral just do a normal conversion.
Likewise for a conversion to an unconstrained array. */ Likewise for a conversion to an unconstrained array. */
if ((((INTEGRAL_TYPE_P (type) if ((((INTEGRAL_TYPE_P (type)

View File

@ -90,11 +90,6 @@ gnat_truthvalue_conversion (tree expr)
gnat_truthvalue_conversion (TREE_OPERAND (expr, 1)), gnat_truthvalue_conversion (TREE_OPERAND (expr, 1)),
gnat_truthvalue_conversion (TREE_OPERAND (expr, 2)))); gnat_truthvalue_conversion (TREE_OPERAND (expr, 2))));
case WITH_RECORD_EXPR:
return build (WITH_RECORD_EXPR, type,
gnat_truthvalue_conversion (TREE_OPERAND (expr, 0)),
TREE_OPERAND (expr, 1));
default: default:
return build_binary_op (NE_EXPR, type, expr, return build_binary_op (NE_EXPR, type, expr,
convert (type, integer_zero_node)); convert (type, integer_zero_node));
@ -381,15 +376,10 @@ compare_arrays (tree result_type, tree a1, tree a2)
tree lb = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1))); tree lb = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
comparison = build_binary_op (LT_EXPR, result_type, ub, lb); comparison = build_binary_op (LT_EXPR, result_type, ub, lb);
comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
if (CONTAINS_PLACEHOLDER_P (comparison)) length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
comparison = build (WITH_RECORD_EXPR, result_type,
comparison, a1);
if (CONTAINS_PLACEHOLDER_P (length1))
length1 = build (WITH_RECORD_EXPR, bt, length1, a1);
length_zero_p = 1; length_zero_p = 1;
this_a1_is_null = comparison; this_a1_is_null = comparison;
this_a2_is_null = convert (result_type, integer_one_node); this_a2_is_null = convert (result_type, integer_one_node);
} }
@ -413,10 +403,8 @@ compare_arrays (tree result_type, tree a1, tree a2)
/* Note that we know that UB2 and LB2 are constant and hence /* Note that we know that UB2 and LB2 are constant and hence
cannot contain a PLACEHOLDER_EXPR. */ cannot contain a PLACEHOLDER_EXPR. */
if (CONTAINS_PLACEHOLDER_P (comparison)) comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
comparison = build (WITH_RECORD_EXPR, result_type, comparison, a1); length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
if (CONTAINS_PLACEHOLDER_P (length1))
length1 = build (WITH_RECORD_EXPR, bt, length1, a1);
this_a1_is_null = build_binary_op (LT_EXPR, result_type, ub1, lb1); this_a1_is_null = build_binary_op (LT_EXPR, result_type, ub1, lb1);
this_a2_is_null = convert (result_type, integer_zero_node); this_a2_is_null = convert (result_type, integer_zero_node);
@ -425,10 +413,8 @@ compare_arrays (tree result_type, tree a1, tree a2)
/* Otherwise compare the computed lengths. */ /* Otherwise compare the computed lengths. */
else else
{ {
if (CONTAINS_PLACEHOLDER_P (length1)) length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
length1 = build (WITH_RECORD_EXPR, bt, length1, a1); length2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length2, a2);
if (CONTAINS_PLACEHOLDER_P (length2))
length2 = build (WITH_RECORD_EXPR, bt, length2, a2);
comparison comparison
= build_binary_op (EQ_EXPR, result_type, length1, length2); = build_binary_op (EQ_EXPR, result_type, length1, length2);
@ -606,39 +592,6 @@ build_binary_op (enum tree_code op_code,
tree result; tree result;
int has_side_effects = 0; int has_side_effects = 0;
/* If one (but not both, unless they have the same object) operands are a
WITH_RECORD_EXPR, do the operation and then surround it with the
WITH_RECORD_EXPR. Don't do this for assignment, for an ARRAY_REF, or
for an ARRAY_RANGE_REF because we need to keep track of the
WITH_RECORD_EXPRs on both operands very carefully. */
if (op_code != MODIFY_EXPR && op_code != ARRAY_REF
&& op_code != ARRAY_RANGE_REF
&& TREE_CODE (left_operand) == WITH_RECORD_EXPR
&& (TREE_CODE (right_operand) != WITH_RECORD_EXPR
|| operand_equal_p (TREE_OPERAND (left_operand, 1),
TREE_OPERAND (right_operand, 1), 0)))
{
tree right = right_operand;
if (TREE_CODE (right) == WITH_RECORD_EXPR)
right = TREE_OPERAND (right, 0);
result = build_binary_op (op_code, result_type,
TREE_OPERAND (left_operand, 0), right);
return build (WITH_RECORD_EXPR, TREE_TYPE (result), result,
TREE_OPERAND (left_operand, 1));
}
else if (op_code != MODIFY_EXPR && op_code != ARRAY_REF
&& op_code != ARRAY_RANGE_REF
&& TREE_CODE (left_operand) != WITH_RECORD_EXPR
&& TREE_CODE (right_operand) == WITH_RECORD_EXPR)
{
result = build_binary_op (op_code, result_type, left_operand,
TREE_OPERAND (right_operand, 0));
return build (WITH_RECORD_EXPR, TREE_TYPE (result), result,
TREE_OPERAND (right_operand, 1));
}
if (operation_type != 0 if (operation_type != 0
&& TREE_CODE (operation_type) == RECORD_TYPE && TREE_CODE (operation_type) == RECORD_TYPE
&& TYPE_LEFT_JUSTIFIED_MODULAR_P (operation_type)) && TYPE_LEFT_JUSTIFIED_MODULAR_P (operation_type))
@ -755,7 +708,6 @@ build_binary_op (enum tree_code op_code,
result = TREE_OPERAND (result, 0); result = TREE_OPERAND (result, 0);
else if (TREE_CODE (result) == REALPART_EXPR else if (TREE_CODE (result) == REALPART_EXPR
|| TREE_CODE (result) == IMAGPART_EXPR || TREE_CODE (result) == IMAGPART_EXPR
|| TREE_CODE (result) == WITH_RECORD_EXPR
|| ((TREE_CODE (result) == NOP_EXPR || ((TREE_CODE (result) == NOP_EXPR
|| TREE_CODE (result) == CONVERT_EXPR) || TREE_CODE (result) == CONVERT_EXPR)
&& (((TREE_CODE (restype) && (((TREE_CODE (restype)
@ -1091,17 +1043,6 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
tree result; tree result;
int side_effects = 0; int side_effects = 0;
/* If we have a WITH_RECORD_EXPR as our operand, do the operation first,
then surround it with the WITH_RECORD_EXPR. This allows GCC to do better
expression folding. */
if (TREE_CODE (operand) == WITH_RECORD_EXPR)
{
result = build_unary_op (op_code, result_type,
TREE_OPERAND (operand, 0));
return build (WITH_RECORD_EXPR, TREE_TYPE (result), result,
TREE_OPERAND (operand, 1));
}
if (operation_type != 0 if (operation_type != 0
&& TREE_CODE (operation_type) == RECORD_TYPE && TREE_CODE (operation_type) == RECORD_TYPE
&& TYPE_LEFT_JUSTIFIED_MODULAR_P (operation_type)) && TYPE_LEFT_JUSTIFIED_MODULAR_P (operation_type))
@ -1716,18 +1657,13 @@ build_component_ref (tree record_variable,
object dynamically on the stack frame. */ object dynamically on the stack frame. */
tree tree
build_call_alloc_dealloc (tree gnu_obj, build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
tree gnu_size, Entity_Id gnat_proc, Entity_Id gnat_pool,
int align,
Entity_Id gnat_proc,
Entity_Id gnat_pool,
Node_Id gnat_node) Node_Id gnat_node)
{ {
tree gnu_align = size_int (align / BITS_PER_UNIT); tree gnu_align = size_int (align / BITS_PER_UNIT);
if (CONTAINS_PLACEHOLDER_P (gnu_size)) gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_obj);
gnu_size = build (WITH_RECORD_EXPR, sizetype, gnu_size,
build_unary_op (INDIRECT_REF, NULL_TREE, gnu_obj));
if (Present (gnat_proc)) if (Present (gnat_proc))
{ {
@ -1868,10 +1804,8 @@ build_allocator (tree type,
tree storage; tree storage;
tree template_cons = NULL_TREE; tree template_cons = NULL_TREE;
size = TYPE_SIZE_UNIT (storage_type); size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type),
init);
if (CONTAINS_PLACEHOLDER_P (size))
size = build (WITH_RECORD_EXPR, sizetype, size, init);
/* If the size overflows, pass -1 so the allocator will raise /* If the size overflows, pass -1 so the allocator will raise
storage error. */ storage error. */
@ -1943,7 +1877,7 @@ build_allocator (tree type,
if (init == 0) if (init == 0)
size = max_size (size, 1); size = max_size (size, 1);
else else
size = build (WITH_RECORD_EXPR, sizetype, size, init); size = substitute_placeholder_in_expr (size, init);
} }
/* If the size overflows, pass -1 so the allocator will raise /* If the size overflows, pass -1 so the allocator will raise
@ -2012,15 +1946,12 @@ fill_vms_descriptor (tree expr, Entity_Id gnat_formal)
gnat_mark_addressable (expr); gnat_mark_addressable (expr);
for (field = TYPE_FIELDS (record_type); field; field = TREE_CHAIN (field)) for (field = TYPE_FIELDS (record_type); field; field = TREE_CHAIN (field))
{ const_list
tree init = DECL_INITIAL (field); = tree_cons (field,
convert (TREE_TYPE (field),
if (CONTAINS_PLACEHOLDER_P (init)) SUBSTITUTE_PLACEHOLDER_IN_EXPR
init = build (WITH_RECORD_EXPR, TREE_TYPE (init), init, expr); (DECL_INITIAL (field), expr)),
const_list);
const_list = tree_cons (field, convert (TREE_TYPE (field), init),
const_list);
}
return gnat_build_constructor (record_type, nreverse (const_list)); return gnat_build_constructor (record_type, nreverse (const_list));
} }

View File

@ -481,7 +481,6 @@ get_alias_set (tree t)
if (! TYPE_P (t)) if (! TYPE_P (t))
{ {
tree inner = t; tree inner = t;
tree placeholder_ptr = 0;
/* Remove any nops, then give the language a chance to do /* Remove any nops, then give the language a chance to do
something with this tree before we look at it. */ something with this tree before we look at it. */
@ -491,16 +490,10 @@ get_alias_set (tree t)
return set; return set;
/* First see if the actual object referenced is an INDIRECT_REF from a /* First see if the actual object referenced is an INDIRECT_REF from a
restrict-qualified pointer or a "void *". Replace restrict-qualified pointer or a "void *". */
PLACEHOLDER_EXPRs. */ while (handled_component_p (inner))
while (TREE_CODE (inner) == PLACEHOLDER_EXPR
|| handled_component_p (inner))
{ {
if (TREE_CODE (inner) == PLACEHOLDER_EXPR) inner = TREE_OPERAND (inner, 0);
inner = find_placeholder (inner, &placeholder_ptr);
else
inner = TREE_OPERAND (inner, 0);
STRIP_NOPS (inner); STRIP_NOPS (inner);
} }
@ -546,16 +539,10 @@ get_alias_set (tree t)
} }
/* Otherwise, pick up the outermost object that we could have a pointer /* Otherwise, pick up the outermost object that we could have a pointer
to, processing conversion and PLACEHOLDER_EXPR as above. */ to, processing conversions as above. */
placeholder_ptr = 0; while (handled_component_p (t) && ! can_address_p (t))
while (TREE_CODE (t) == PLACEHOLDER_EXPR
|| (handled_component_p (t) && ! can_address_p (t)))
{ {
if (TREE_CODE (t) == PLACEHOLDER_EXPR) t = TREE_OPERAND (t, 0);
t = find_placeholder (t, &placeholder_ptr);
else
t = TREE_OPERAND (t, 0);
STRIP_NOPS (t); STRIP_NOPS (t);
} }

View File

@ -217,15 +217,6 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label)
do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label); do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
break; break;
case WITH_RECORD_EXPR:
/* Put the object on the placeholder list, recurse through our first
operand, and pop the list. */
placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
placeholder_list);
do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
placeholder_list = TREE_CHAIN (placeholder_list);
break;
#if 0 #if 0
/* This is never less insns than evaluating the PLUS_EXPR followed by /* This is never less insns than evaluating the PLUS_EXPR followed by
a test and can be longer if the test is eliminated. */ a test and can be longer if the test is eliminated. */

View File

@ -8705,7 +8705,6 @@ loc_descriptor_from_tree (tree loc, int addressp)
case ERROR_MARK: case ERROR_MARK:
return 0; return 0;
case WITH_RECORD_EXPR:
case PLACEHOLDER_EXPR: case PLACEHOLDER_EXPR:
/* This case involves extracting fields from an object to determine the /* This case involves extracting fields from an object to determine the
position of other fields. We don't try to encode this here. The position of other fields. We don't try to encode this here. The

View File

@ -1409,19 +1409,13 @@ component_ref_for_mem_expr (tree ref)
inner = component_ref_for_mem_expr (inner); inner = component_ref_for_mem_expr (inner);
else else
{ {
tree placeholder_ptr = 0;
/* Now remove any conversions: they don't change what the underlying /* Now remove any conversions: they don't change what the underlying
object is. Likewise for SAVE_EXPR. Also handle PLACEHOLDER_EXPR. */ object is. Likewise for SAVE_EXPR. */
while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR
|| TREE_CODE (inner) == NON_LVALUE_EXPR || TREE_CODE (inner) == NON_LVALUE_EXPR
|| TREE_CODE (inner) == VIEW_CONVERT_EXPR || TREE_CODE (inner) == VIEW_CONVERT_EXPR
|| TREE_CODE (inner) == SAVE_EXPR || TREE_CODE (inner) == SAVE_EXPR)
|| TREE_CODE (inner) == PLACEHOLDER_EXPR) inner = TREE_OPERAND (inner, 0);
if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
inner = find_placeholder (inner, &placeholder_ptr);
else
inner = TREE_OPERAND (inner, 0);
if (! DECL_P (inner)) if (! DECL_P (inner))
inner = NULL_TREE; inner = NULL_TREE;
@ -1608,20 +1602,14 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
index = fold (build (MINUS_EXPR, TREE_TYPE (index), index = fold (build (MINUS_EXPR, TREE_TYPE (index),
index, low_bound)); index, low_bound));
/* If the index has a self-referential type, pass it to a /* If the index has a self-referential type, instantiate it;
WITH_RECORD_EXPR; if the component size is, pass our likewise for the component size. */
component to one. */ index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, t2);
if (CONTAINS_PLACEHOLDER_P (index)) unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, t2);
if (CONTAINS_PLACEHOLDER_P (unit_size))
unit_size = build (WITH_RECORD_EXPR, sizetype,
unit_size, array);
off_tree off_tree
= fold (build (PLUS_EXPR, sizetype, = fold (build (PLUS_EXPR, sizetype,
fold (build (MULT_EXPR, sizetype, fold (build (MULT_EXPR, sizetype,
index, index, unit_size)),
unit_size)),
off_tree)); off_tree));
t2 = TREE_OPERAND (t2, 0); t2 = TREE_OPERAND (t2, 0);
} }

View File

@ -240,10 +240,7 @@ eliminate_constant_term (rtx x, rtx *constptr)
rtx rtx
expr_size (tree exp) expr_size (tree exp)
{ {
tree size = lang_hooks.expr_size (exp); tree size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lang_hooks.expr_size (exp), exp);
if (CONTAINS_PLACEHOLDER_P (size))
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0); return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
} }

View File

@ -90,9 +90,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
the same indirect address eventually. */ the same indirect address eventually. */
int cse_not_expected; int cse_not_expected;
/* Chain of pending expressions for PLACEHOLDER_EXPR to replace. */
tree placeholder_list = 0;
/* This structure is used by move_by_pieces to describe the move to /* This structure is used by move_by_pieces to describe the move to
be performed. */ be performed. */
struct move_by_pieces struct move_by_pieces
@ -4610,9 +4607,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
{ {
rtx offset_rtx; rtx offset_rtx;
if (CONTAINS_PLACEHOLDER_P (offset)) offset
offset = build (WITH_RECORD_EXPR, sizetype, = SUBSTITUTE_PLACEHOLDER_IN_EXPR (offset,
offset, make_tree (TREE_TYPE (exp), target)); make_tree (TREE_TYPE (exp),
target));
offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0); offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
if (GET_CODE (to_rtx) != MEM) if (GET_CODE (to_rtx) != MEM)
@ -5401,7 +5399,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
enum machine_mode mode = VOIDmode; enum machine_mode mode = VOIDmode;
tree offset = size_zero_node; tree offset = size_zero_node;
tree bit_offset = bitsize_zero_node; tree bit_offset = bitsize_zero_node;
tree placeholder_ptr = 0;
tree tem; tree tem;
/* First get the mode, signedness, and size. We do this from just the /* First get the mode, signedness, and size. We do this from just the
@ -5454,8 +5451,8 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
made during type construction. */ made during type construction. */
if (this_offset == 0) if (this_offset == 0)
break; break;
else if (CONTAINS_PLACEHOLDER_P (this_offset)) else
this_offset = build (WITH_RECORD_EXPR, sizetype, this_offset, exp); this_offset = SUBSTITUTE_PLACEHOLDER_IN_EXPR (this_offset, exp);
offset = size_binop (PLUS_EXPR, offset, this_offset); offset = size_binop (PLUS_EXPR, offset, this_offset);
bit_offset = size_binop (PLUS_EXPR, bit_offset, bit_offset = size_binop (PLUS_EXPR, bit_offset,
@ -5481,35 +5478,16 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
index = fold (build (MINUS_EXPR, TREE_TYPE (index), index = fold (build (MINUS_EXPR, TREE_TYPE (index),
index, low_bound)); index, low_bound));
/* If the index has a self-referential type, pass it to a /* If the index has a self-referential type, instantiate it with
WITH_RECORD_EXPR; if the component size is, pass our the object; likewise fkor the component size. */
component to one. */ index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, exp);
if (CONTAINS_PLACEHOLDER_P (index)) unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, exp);
if (CONTAINS_PLACEHOLDER_P (unit_size))
unit_size = build (WITH_RECORD_EXPR, sizetype, unit_size, array);
offset = size_binop (PLUS_EXPR, offset, offset = size_binop (PLUS_EXPR, offset,
size_binop (MULT_EXPR, size_binop (MULT_EXPR,
convert (sizetype, index), convert (sizetype, index),
unit_size)); unit_size));
} }
else if (TREE_CODE (exp) == PLACEHOLDER_EXPR)
{
tree new = find_placeholder (exp, &placeholder_ptr);
/* If we couldn't find the replacement, return the PLACEHOLDER_EXPR.
We might have been called from tree optimization where we
haven't set up an object yet. */
if (new == 0)
break;
else
exp = new;
continue;
}
/* We can go inside most conversions: all NON_VALUE_EXPRs, all normal /* We can go inside most conversions: all NON_VALUE_EXPRs, all normal
conversions that don't change the mode, and all view conversions conversions that don't change the mode, and all view conversions
except those that need to "step up" the alignment. */ except those that need to "step up" the alignment. */
@ -6033,7 +6011,7 @@ highest_pow2_factor (tree exp)
break; break;
case NON_LVALUE_EXPR: case NOP_EXPR: case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR: case CONVERT_EXPR:
case SAVE_EXPR: case WITH_RECORD_EXPR: case SAVE_EXPR:
return highest_pow2_factor (TREE_OPERAND (exp, 0)); return highest_pow2_factor (TREE_OPERAND (exp, 0));
case COMPOUND_EXPR: case COMPOUND_EXPR:
@ -6069,70 +6047,6 @@ highest_pow2_factor_for_target (tree target, tree exp)
return MAX (factor, target_align); return MAX (factor, target_align);
} }
/* Return an object on the placeholder list that matches EXP, a
PLACEHOLDER_EXPR. An object "matches" if it is of the type of the
PLACEHOLDER_EXPR or a pointer type to it. For further information, see
tree.def. If no such object is found, return 0. If PLIST is nonzero, it
is a location which initially points to a starting location in the
placeholder list (zero means start of the list) and where a pointer into
the placeholder list at which the object is found is placed. */
tree
find_placeholder (tree exp, tree *plist)
{
tree type = TREE_TYPE (exp);
tree placeholder_expr;
for (placeholder_expr
= plist && *plist ? TREE_CHAIN (*plist) : placeholder_list;
placeholder_expr != 0;
placeholder_expr = TREE_CHAIN (placeholder_expr))
{
tree need_type = TYPE_MAIN_VARIANT (type);
tree elt;
/* Find the outermost reference that is of the type we want. If none,
see if any object has a type that is a pointer to the type we
want. */
for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
elt = ((TREE_CODE (elt) == COMPOUND_EXPR
|| TREE_CODE (elt) == COND_EXPR)
? TREE_OPERAND (elt, 1)
: (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
? TREE_OPERAND (elt, 0) : 0))
if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
{
if (plist)
*plist = placeholder_expr;
return elt;
}
for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
elt
= ((TREE_CODE (elt) == COMPOUND_EXPR
|| TREE_CODE (elt) == COND_EXPR)
? TREE_OPERAND (elt, 1)
: (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
? TREE_OPERAND (elt, 0) : 0))
if (POINTER_TYPE_P (TREE_TYPE (elt))
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
== need_type))
{
if (plist)
*plist = placeholder_expr;
return build1 (INDIRECT_REF, need_type, elt);
}
}
return 0;
}
/* Subroutine of expand_expr. Expand the two operands of a binary /* Subroutine of expand_expr. Expand the two operands of a binary
expression EXP0 and EXP1 placing the results in OP0 and OP1. expression EXP0 and EXP1 placing the results in OP0 and OP1.
The value may be stored in TARGET if TARGET is nonzero. The The value may be stored in TARGET if TARGET is nonzero. The
@ -6653,31 +6567,6 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
return temp; return temp;
} }
case PLACEHOLDER_EXPR:
{
tree old_list = placeholder_list;
tree placeholder_expr = 0;
exp = find_placeholder (exp, &placeholder_expr);
if (exp == 0)
abort ();
placeholder_list = TREE_CHAIN (placeholder_expr);
temp = expand_expr (exp, original_target, tmode, modifier);
placeholder_list = old_list;
return temp;
}
case WITH_RECORD_EXPR:
/* Put the object on the placeholder list, expand our first operand,
and pop the list. */
placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
placeholder_list);
target = expand_expr (TREE_OPERAND (exp, 0), original_target, tmode,
modifier);
placeholder_list = TREE_CHAIN (placeholder_list);
return target;
case GOTO_EXPR: case GOTO_EXPR:
if (TREE_CODE (TREE_OPERAND (exp, 0)) == LABEL_DECL) if (TREE_CODE (TREE_OPERAND (exp, 0)) == LABEL_DECL)
expand_goto (TREE_OPERAND (exp, 0)); expand_goto (TREE_OPERAND (exp, 0));
@ -9095,11 +8984,10 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
static int static int
is_aligning_offset (tree offset, tree exp) is_aligning_offset (tree offset, tree exp)
{ {
/* Strip off any conversions and WITH_RECORD_EXPR nodes. */ /* Strip off any conversions. */
while (TREE_CODE (offset) == NON_LVALUE_EXPR while (TREE_CODE (offset) == NON_LVALUE_EXPR
|| TREE_CODE (offset) == NOP_EXPR || TREE_CODE (offset) == NOP_EXPR
|| TREE_CODE (offset) == CONVERT_EXPR || TREE_CODE (offset) == CONVERT_EXPR)
|| TREE_CODE (offset) == WITH_RECORD_EXPR)
offset = TREE_OPERAND (offset, 0); offset = TREE_OPERAND (offset, 0);
/* We must now have a BIT_AND_EXPR with a constant that is one less than /* We must now have a BIT_AND_EXPR with a constant that is one less than
@ -9128,13 +9016,8 @@ is_aligning_offset (tree offset, tree exp)
|| TREE_CODE (offset) == CONVERT_EXPR) || TREE_CODE (offset) == CONVERT_EXPR)
offset = TREE_OPERAND (offset, 0); offset = TREE_OPERAND (offset, 0);
/* This must now be the address either of EXP or of a PLACEHOLDER_EXPR /* This must now be the address of EXP. */
whose type is the same as EXP. */ return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
return (TREE_CODE (offset) == ADDR_EXPR
&& (TREE_OPERAND (offset, 0) == exp
|| (TREE_CODE (TREE_OPERAND (offset, 0)) == PLACEHOLDER_EXPR
&& (TREE_TYPE (TREE_OPERAND (offset, 0))
== TREE_TYPE (exp)))));
} }
/* Return the tree node if an ARG corresponds to a string constant or zero /* Return the tree node if an ARG corresponds to a string constant or zero

View File

@ -505,15 +505,6 @@ extern rtx store_expr (tree, rtx, int);
Useful after calling expand_expr with 1 as sum_ok. */ Useful after calling expand_expr with 1 as sum_ok. */
extern rtx force_operand (rtx, rtx); extern rtx force_operand (rtx, rtx);
/* Return an object on the placeholder list that matches EXP, a
PLACEHOLDER_EXPR. An object "matches" if it is of the type of the
PLACEHOLDER_EXPR or a pointer type to it. For further information, see
tree.def. If no such object is found, abort. If PLIST is nonzero, it is
a location which initially points to a starting location in the
placeholder list (zero means start of the list) and where a pointer into
the placeholder list at which the object is found is placed. */
extern tree find_placeholder (tree, tree *);
/* Generate code for computing expression EXP. /* Generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null. An rtx for the computed value is returned. The value is never null.
In the case of a void EXP, const0_rtx is returned. */ In the case of a void EXP, const0_rtx is returned. */
@ -808,5 +799,3 @@ extern void do_jump_by_parts_greater_rtx (enum machine_mode, int, rtx, rtx,
extern void mark_seen_cases (tree, unsigned char *, HOST_WIDE_INT, int); extern void mark_seen_cases (tree, unsigned char *, HOST_WIDE_INT, int);
extern int vector_mode_valid_p (enum machine_mode); extern int vector_mode_valid_p (enum machine_mode);
extern tree placeholder_list;

View File

@ -2718,11 +2718,6 @@ invert_truthvalue (tree arg)
return build (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0), return build (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
invert_truthvalue (TREE_OPERAND (arg, 1))); invert_truthvalue (TREE_OPERAND (arg, 1)));
case WITH_RECORD_EXPR:
return build (WITH_RECORD_EXPR, type,
invert_truthvalue (TREE_OPERAND (arg, 0)),
TREE_OPERAND (arg, 1));
case NON_LVALUE_EXPR: case NON_LVALUE_EXPR:
return invert_truthvalue (TREE_OPERAND (arg, 0)); return invert_truthvalue (TREE_OPERAND (arg, 0));
@ -4560,12 +4555,6 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
} }
break; break;
case WITH_RECORD_EXPR:
if ((t1 = extract_muldiv (TREE_OPERAND (t, 0), c, code, wide_type)) != 0)
return build (WITH_RECORD_EXPR, TREE_TYPE (t1), t1,
TREE_OPERAND (t, 1));
break;
case LSHIFT_EXPR: case RSHIFT_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR:
/* If the second operand is constant, this is a multiplication /* If the second operand is constant, this is a multiplication
or floor division, by a power of two, so we can treat it that or floor division, by a power of two, so we can treat it that

View File

@ -1211,7 +1211,7 @@ expr_align (tree t)
case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR: case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR:
case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR: case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR:
case WITH_RECORD_EXPR: case CLEANUP_POINT_EXPR: case UNSAVE_EXPR: case CLEANUP_POINT_EXPR: case UNSAVE_EXPR:
/* These don't change the alignment of an object. */ /* These don't change the alignment of an object. */
return expr_align (TREE_OPERAND (t, 0)); return expr_align (TREE_OPERAND (t, 0));
@ -1699,12 +1699,8 @@ contains_placeholder_p (tree exp)
if (!exp) if (!exp)
return 0; return 0;
/* If we have a WITH_RECORD_EXPR, it "cancels" any PLACEHOLDER_EXPR
in it since it is supplying a value for it. */
code = TREE_CODE (exp); code = TREE_CODE (exp);
if (code == WITH_RECORD_EXPR) if (code == PLACEHOLDER_EXPR)
return 0;
else if (code == PLACEHOLDER_EXPR)
return 1; return 1;
switch (TREE_CODE_CLASS (code)) switch (TREE_CODE_CLASS (code))
@ -1731,10 +1727,6 @@ contains_placeholder_p (tree exp)
/* Ignoring the first operand isn't quite right, but works best. */ /* 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: case COND_EXPR:
return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0)) return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)) || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
@ -1753,14 +1745,11 @@ contains_placeholder_p (tree exp)
return result; return result;
case CALL_EXPR:
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
default: default:
break; break;
} }
switch (TREE_CODE_LENGTH (code)) switch (first_rtl_op (code))
{ {
case 1: case 1:
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0)); return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
@ -1954,9 +1943,8 @@ substitute_in_expr (tree exp, tree f, tree r)
/* We handle TREE_LIST and COMPONENT_REF separately. */ /* We handle TREE_LIST and COMPONENT_REF separately. */
if (code == TREE_LIST) if (code == TREE_LIST)
{ {
op0 = (TREE_CHAIN (exp) == 0 op0 = SUBSTITUTE_IN_EXPR (TREE_CHAIN (exp), f, r);
? 0 : substitute_in_expr (TREE_CHAIN (exp), f, r)); op1 = SUBSTITUTE_IN_EXPR (TREE_VALUE (exp), f, r);
op1 = substitute_in_expr (TREE_VALUE (exp), f, r);
if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp)) if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
return exp; return exp;
@ -1979,7 +1967,7 @@ substitute_in_expr (tree exp, tree f, tree r)
if (TREE_CODE (inner) == PLACEHOLDER_EXPR && TREE_TYPE (inner) == 0) if (TREE_CODE (inner) == PLACEHOLDER_EXPR && TREE_TYPE (inner) == 0)
return exp; return exp;
op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r); op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
if (op0 == TREE_OPERAND (exp, 0)) if (op0 == TREE_OPERAND (exp, 0))
return exp; return exp;
@ -2004,7 +1992,7 @@ substitute_in_expr (tree exp, tree f, tree r)
return exp; return exp;
case 1: case 1:
op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r); op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
if (op0 == TREE_OPERAND (exp, 0)) if (op0 == TREE_OPERAND (exp, 0))
return exp; return exp;
@ -2012,8 +2000,8 @@ substitute_in_expr (tree exp, tree f, tree r)
break; break;
case 2: case 2:
op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r); op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
op1 = substitute_in_expr (TREE_OPERAND (exp, 1), f, r); op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)) if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
return exp; return exp;
@ -2022,9 +2010,9 @@ substitute_in_expr (tree exp, tree f, tree r)
break; break;
case 3: case 3:
op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r); op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
op1 = substitute_in_expr (TREE_OPERAND (exp, 1), f, r); op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
op2 = substitute_in_expr (TREE_OPERAND (exp, 2), f, r); op2 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 2), f, r);
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1) if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
&& op2 == TREE_OPERAND (exp, 2)) && op2 == TREE_OPERAND (exp, 2))
@ -2045,6 +2033,121 @@ substitute_in_expr (tree exp, tree f, tree r)
TREE_READONLY (new) = TREE_READONLY (exp); TREE_READONLY (new) = TREE_READONLY (exp);
return new; return new;
} }
/* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement
for it within OBJ, a tree that is an object or a chain of references. */
tree
substitute_placeholder_in_expr (tree exp, tree obj)
{
enum tree_code code = TREE_CODE (exp);
tree op0, op1, op2;
/* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type
in the chain of OBJ. */
if (code == PLACEHOLDER_EXPR)
{
tree need_type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
tree elt;
for (elt = obj; elt != 0;
elt = ((TREE_CODE (elt) == COMPOUND_EXPR
|| TREE_CODE (elt) == COND_EXPR)
? TREE_OPERAND (elt, 1)
: (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
? TREE_OPERAND (elt, 0) : 0))
if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
return elt;
for (elt = obj; elt != 0;
elt = ((TREE_CODE (elt) == COMPOUND_EXPR
|| TREE_CODE (elt) == COND_EXPR)
? TREE_OPERAND (elt, 1)
: (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
|| TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
? TREE_OPERAND (elt, 0) : 0))
if (POINTER_TYPE_P (TREE_TYPE (elt))
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
== need_type))
return fold (build1 (INDIRECT_REF, need_type, elt));
/* If we didn't find it, return the original PLACEHOLDER_EXPR. If it
survives until RTL generation, there will be an error. */
return exp;
}
/* TREE_LIST is special because we need to look at TREE_VALUE
and TREE_CHAIN, not TREE_OPERANDS. */
else if (code == TREE_LIST)
{
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_CHAIN (exp), obj);
op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_VALUE (exp), obj);
if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
return exp;
return tree_cons (TREE_PURPOSE (exp), op1, op0);
}
else
switch (TREE_CODE_CLASS (code))
{
case 'c':
case 'd':
case 'b':
return exp;
case 'x':
case '1':
case '2':
case '<':
case 'e':
case 'r':
case 's':
switch (first_rtl_op (code))
{
case 0:
return exp;
case 1:
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
if (op0 == TREE_OPERAND (exp, 0))
return exp;
else
return fold (build1 (code, TREE_TYPE (exp), op0));
case 2:
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
return exp;
else
return fold (build2 (code, TREE_TYPE (exp), op0, op1));
case 3:
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
op2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 2), obj);
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
&& op2 == TREE_OPERAND (exp, 2))
return exp;
else
return fold (build3 (code, TREE_TYPE (exp), op0, op1, op2));
default:
abort ();
}
break;
default:
abort ();
}
}
/* Stabilize a reference so that we can use it any number of times /* Stabilize a reference so that we can use it any number of times
without causing its operands to be evaluated more than once. without causing its operands to be evaluated more than once.

View File

@ -541,35 +541,22 @@ DEFTREECODE (CLEANUP_POINT_EXPR, "cleanup_point_expr", 'e', 1)
actual size at run-time. In the following, we describe how this actual size at run-time. In the following, we describe how this
calculation is done. calculation is done.
When we wish to evaluate a size or offset, we check whether it When we wish to evaluate a size or offset, we check whether it contains a
contains a PLACEHOLDER_EXPR. If it does, we construct a PLACEHOLDER_EXPR. If it does, we call substitute_placeholder_in_expr
WITH_RECORD_EXPR that contains both the expression we wish to passing both that tree and an expression within which the object may be
evaluate and an expression within which the object may be found. found. The latter expression is the object itself in the simple case of
The latter expression is the object itself in the simple case of an an Ada record with discriminant, but it can be the array in the case of an
Ada record with discriminant, but it can be the array in the case of unconstrained array.
an unconstrained array.
In the latter case, we need the fat pointer, because the bounds of In the latter case, we need the fat pointer, because the bounds of
the array can only be accessed from it. However, we rely here on the the array can only be accessed from it. However, we rely here on the
fact that the expression for the array contains the dereference of fact that the expression for the array contains the dereference of
the fat pointer that obtained the array pointer. the fat pointer that obtained the array pointer. */
Accordingly, when looking for the object to substitute in place of /* Denotes a record to later be substitued before evaluating this expression.
a PLACEHOLDER_EXPR, we look down the first operand of the expression The type of this expression is used to find the record to replace it. */
passed as the second operand to WITH_RECORD_EXPR until we find
something of the desired type or reach a constant. */
/* Denotes a record to later be supplied with a WITH_RECORD_EXPR when
evaluating this expression. The type of this expression is used to
find the record to replace it. */
DEFTREECODE (PLACEHOLDER_EXPR, "placeholder_expr", 'x', 0) DEFTREECODE (PLACEHOLDER_EXPR, "placeholder_expr", 'x', 0)
/* Provide an expression that references a record to be used in place
of a PLACEHOLDER_EXPR. The record to be used is the record within
operand 1 that has the same type as the PLACEHOLDER_EXPR in
operand 0. */
DEFTREECODE (WITH_RECORD_EXPR, "with_record_expr", 'e', 2)
/* Simple arithmetic. */ /* Simple arithmetic. */
DEFTREECODE (PLUS_EXPR, "plus_expr", '2', 2) DEFTREECODE (PLUS_EXPR, "plus_expr", '2', 2)
DEFTREECODE (MINUS_EXPR, "minus_expr", '2', 2) DEFTREECODE (MINUS_EXPR, "minus_expr", '2', 2)

View File

@ -2675,6 +2675,24 @@ extern int has_cleanups (tree);
extern tree substitute_in_expr (tree, tree, tree); extern tree substitute_in_expr (tree, tree, tree);
/* This macro calls the above function but short-circuits the common
case of a constant to save time and also checks for NULL. */
#define SUBSTITUTE_IN_EXPR(EXP, F, R) \
((EXP) == 0 || TREE_CONSTANT (EXP) ? (EXP) : substitute_in_expr (EXP, F, R))
/* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement
for it within OBJ, a tree that is an object or a chain of references. */
extern tree substitute_placeholder_in_expr (tree, tree);
/* This macro calls the above function but short-circuits the common
case of a constant to save time and also checks for NULL. */
#define SUBSTITUTE_PLACEHOLDER_IN_EXPR(EXP, OBJ) \
((EXP) == 0 || TREE_CONSTANT (EXP) ? (EXP) \
: substitute_placeholder_in_expr (EXP, OBJ))
/* variable_size (EXP) is like save_expr (EXP) except that it /* variable_size (EXP) is like save_expr (EXP) except that it
is for the special case of something that is part of a is for the special case of something that is part of a
variable size for a data type. It makes special arrangements variable size for a data type. It makes special arrangements