diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2015-05-28 15:24:12 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2015-05-28 15:24:12 +0000 |
commit | fc7a823e1507110aba804cf94415155a8783e698 (patch) | |
tree | fb09192367caa4ff2977684a039b071404d51421 /gcc/ada/gcc-interface/utils2.c | |
parent | 318a4e6de8f20670c9f9e9dde02dc639f161f68c (diff) | |
download | gcc-fc7a823e1507110aba804cf94415155a8783e698.zip gcc-fc7a823e1507110aba804cf94415155a8783e698.tar.gz gcc-fc7a823e1507110aba804cf94415155a8783e698.tar.bz2 |
gigi.h (gnat_stabilize_reference): Adjust.
* gcc-interface/gigi.h (gnat_stabilize_reference): Adjust.
(rewrite_fn): Remove third parameter.
(type_is_padding_self_referential): New inline predicate.
(return_type_with_variable_size_p): Likewise.
* gcc-interface/decl.c (allocatable_size_p): More around.
(cannot_be_superflat_p): Rename into...
(cannot_be_superflat ): ...this.
(initial_value_needs_conversion): New predicate.
(gnat_to_gnu_entity): Invoke type_is_padding_self_referential,
initial_value_needs_conversion and adjust to above renaming.
For a renaming, force the materialization if the inner expression
is compound. Adjust calls to elaborate_reference and build a
compound expression if needed.
(struct er_dat): Add N field.
(elaborate_reference_1): Remove N parameter and adjust.
(elaborate_reference): Add INIT parameter and pass it in the call to
gnat_rewrite_reference. Adjust initial expression.
* gcc-interface/trans.c (Call_to_gnu): Treat renamings the same way as
regular object declarations when it comes to creating a temporary.
Adjust call to gnat_stabilize_reference and build a compound expression
if needed. Invoke return_type_with_variable_size_p.
(gnat_to_gnu): Invoke type_is_padding_self_referential. In case #4,
return a call to a function unmodified if it returns with variable size
and is also the initial expression in an object declaration.
* gcc-interface/utils2.c (build_binary_op) <INIT_EXPR>: Use the RHS'
type if it is a call to a function that returns with variable size.
(build_unary_op): Invoke type_is_padding_self_referential.
(gnat_stabilize_reference_1): Remove N parameter and adjust.
(gnat_stabilize_reference): Add INIT parameter and pass it in the call
to gnat_rewrite_reference.
(gnat_rewrite_reference): Remove N, add INIT parameter and adjust.
<COMPOUND_EXPR>: New case.
From-SVN: r223834
Diffstat (limited to 'gcc/ada/gcc-interface/utils2.c')
-rw-r--r-- | gcc/ada/gcc-interface/utils2.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index edbcc53..cc2c645 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -923,13 +923,10 @@ build_binary_op (enum tree_code op_code, tree result_type, operation_type = left_type; } - /* If we have a call to a function that returns an unconstrained type - with default discriminant on the RHS, use the RHS type (which is - padded) as we cannot compute the size of the actual assignment. */ + /* If we have a call to a function that returns with variable size, use + the RHS type in case we want to use the return slot optimization. */ else if (TREE_CODE (right_operand) == CALL_EXPR - && TYPE_IS_PADDING_P (right_type) - && CONTAINS_PLACEHOLDER_P - (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (right_type))))) + && return_type_with_variable_size_p (right_type)) operation_type = right_type; /* Find the best type to use for copying between aggregate types. */ @@ -1420,10 +1417,7 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand) /* If INNER is a padding type whose field has a self-referential size, convert to that inner type. We know the offset is zero and we need to have that type visible. */ - if (TYPE_IS_PADDING_P (TREE_TYPE (inner)) - && CONTAINS_PLACEHOLDER_P - (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS - (TREE_TYPE (inner)))))) + if (type_is_padding_self_referential (TREE_TYPE (inner))) inner = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (inner))), inner); @@ -2663,7 +2657,7 @@ gnat_protect_expr (tree exp) argument to force evaluation of everything. */ static tree -gnat_stabilize_reference_1 (tree e, void *data, int n) +gnat_stabilize_reference_1 (tree e, void *data) { const bool force = *(bool *)data; enum tree_code code = TREE_CODE (e); @@ -2688,7 +2682,7 @@ gnat_stabilize_reference_1 (tree e, void *data, int n) && TYPE_IS_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (e, 0)))) result = build3 (code, type, - gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data, n), + gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data), TREE_OPERAND (e, 1), TREE_OPERAND (e, 2)); /* If the expression has side-effects, then encase it in a SAVE_EXPR so that it will only be evaluated once. */ @@ -2704,15 +2698,15 @@ gnat_stabilize_reference_1 (tree e, void *data, int n) /* Recursively stabilize each operand. */ result = build2 (code, type, - gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data, n), - gnat_stabilize_reference_1 (TREE_OPERAND (e, 1), data, n)); + gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data), + gnat_stabilize_reference_1 (TREE_OPERAND (e, 1), data)); break; case tcc_unary: /* Recursively stabilize each operand. */ result = build1 (code, type, - gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data, n)); + gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data)); break; default: @@ -2728,21 +2722,22 @@ gnat_stabilize_reference_1 (tree e, void *data, int n) /* This is equivalent to stabilize_reference in tree.c but we know how to handle our own nodes and we take extra arguments. FORCE says whether to - force evaluation of everything. */ + force evaluation of everything in REF. INIT is set to the first arm of + a COMPOUND_EXPR present in REF, if any. */ tree -gnat_stabilize_reference (tree ref, bool force) +gnat_stabilize_reference (tree ref, bool force, tree *init) { - return gnat_rewrite_reference (ref, gnat_stabilize_reference_1, &force); + return + gnat_rewrite_reference (ref, gnat_stabilize_reference_1, &force, init); } /* Rewrite reference REF and call FUNC on each expression within REF in the - process. DATA is passed unmodified to FUNC and N is bumped each time it - is passed to FUNC, so FUNC is guaranteed to see a given N only once per - reference to be rewritten. */ + process. DATA is passed unmodified to FUNC. INIT is set to the first + arm of a COMPOUND_EXPR present in REF, if any. */ tree -gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n) +gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, tree *init) { tree type = TREE_TYPE (ref); enum tree_code code = TREE_CODE (ref); @@ -2764,25 +2759,25 @@ gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n) result = build1 (code, type, gnat_rewrite_reference (TREE_OPERAND (ref, 0), func, data, - n)); + init)); break; case INDIRECT_REF: case UNCONSTRAINED_ARRAY_REF: - result = build1 (code, type, func (TREE_OPERAND (ref, 0), data, n)); + result = build1 (code, type, func (TREE_OPERAND (ref, 0), data)); break; case COMPONENT_REF: result = build3 (COMPONENT_REF, type, gnat_rewrite_reference (TREE_OPERAND (ref, 0), func, - data, n), + data, init), TREE_OPERAND (ref, 1), NULL_TREE); break; case BIT_FIELD_REF: result = build3 (BIT_FIELD_REF, type, gnat_rewrite_reference (TREE_OPERAND (ref, 0), func, - data, n), + data, init), TREE_OPERAND (ref, 1), TREE_OPERAND (ref, 2)); break; @@ -2791,11 +2786,18 @@ gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n) result = build4 (code, type, gnat_rewrite_reference (TREE_OPERAND (ref, 0), func, data, - n + 1), - func (TREE_OPERAND (ref, 1), data, n), + init), + func (TREE_OPERAND (ref, 1), data), TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3)); break; + case COMPOUND_EXPR: + gcc_assert (*init == NULL_TREE); + *init = TREE_OPERAND (ref, 0); + /* We expect only the pattern built in Call_to_gnu. */ + gcc_assert (DECL_P (TREE_OPERAND (ref, 1))); + return TREE_OPERAND (ref, 1); + case CALL_EXPR: { /* This can only be an atomic load. */ @@ -2808,9 +2810,9 @@ gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n) if (TREE_CODE (t) == ADDR_EXPR) t = build1 (ADDR_EXPR, TREE_TYPE (t), gnat_rewrite_reference (TREE_OPERAND (t, 0), func, data, - n)); + init)); else - t = func (t, data, n); + t = func (t, data); t = fold_convert (TREE_TYPE (CALL_EXPR_ARG (ref, 0)), t); result = build_call_expr (TREE_OPERAND (CALL_EXPR_FN (ref), 0), 2, |