{
tree init = DECL_INITIAL (decl);
- if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
+ || (!TREE_STATIC (decl)
+ && flag_stack_check == GENERIC_STACK_CHECK
+ && compare_tree_int (DECL_SIZE_UNIT (decl),
+ STACK_CHECK_MAX_VAR_SIZE) > 0))
gimplify_vla_decl (decl, seq_p);
if (init && init != error_mark_node)
/* Attempt to avoid NOP_EXPR by producing reference to a subtype.
For example this fold (subclass *)&A into &A->subclass avoiding
a need for statement. */
- if (TREE_CODE (*expr_p) == NOP_EXPR
+ if (CONVERT_EXPR_P (*expr_p)
&& POINTER_TYPE_P (TREE_TYPE (*expr_p))
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))
- && (tem = maybe_fold_offset_to_reference
+ && (tem = maybe_fold_offset_to_address
(TREE_OPERAND (*expr_p, 0),
- integer_zero_node, TREE_TYPE (TREE_TYPE (*expr_p)))))
- {
- tree ptr_type = build_pointer_type (TREE_TYPE (tem));
- if (useless_type_conversion_p (TREE_TYPE (*expr_p), ptr_type))
- *expr_p = build_fold_addr_expr_with_type (tem, ptr_type);
- }
+ integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE)
+ *expr_p = tem;
/* If we still have a conversion at the toplevel,
then canonicalize some constructs. */
canonicalize_addr_expr (expr_p);
}
+ /* If we have a conversion to a non-register type force the
+ use of a VIEW_CONVERT_EXPR instead. */
+ if (!is_gimple_reg_type (TREE_TYPE (*expr_p)))
+ *expr_p = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
+ TREE_OPERAND (*expr_p, 0));
+
return GS_OK;
}
fndecl = get_callee_fndecl (*expr_p);
if (fndecl && DECL_BUILT_IN (fndecl))
{
- tree new = fold_call_expr (*expr_p, !want_value);
+ tree new_tree = fold_call_expr (*expr_p, !want_value);
- if (new && new != *expr_p)
+ if (new_tree && new_tree != *expr_p)
{
/* There was a transformation of this call which computes the
same value, but in a more efficient way. Return and try
again. */
- *expr_p = new;
+ *expr_p = new_tree;
return GS_OK;
}
/* Try this again in case gimplification exposed something. */
if (ret != GS_ERROR)
{
- tree new = fold_call_expr (*expr_p, !want_value);
+ tree new_tree = fold_call_expr (*expr_p, !want_value);
- if (new && new != *expr_p)
+ if (new_tree && new_tree != *expr_p)
{
/* There was a transformation of this call which computes the
same value, but in a more efficient way. Return and try
again. */
- *expr_p = new;
+ *expr_p = new_tree;
return GS_OK;
}
}
if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
cleared = true;
/* If there are "lots" of zeros, then block clear the object first. */
- else if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
+ else if (num_type_elements - num_nonzero_elements
+ > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
&& num_nonzero_elements < num_type_elements/4)
cleared = true;
/* ??? This bit ought not be needed. For any element not present
if (size > 0 && !can_move_by_pieces (size, align))
{
- tree new;
+ tree new_tree;
if (notify_temp_creation)
return GS_ERROR;
- new = create_tmp_var_raw (type, "C");
+ new_tree = create_tmp_var_raw (type, "C");
- gimple_add_tmp_var (new);
- TREE_STATIC (new) = 1;
- TREE_READONLY (new) = 1;
- DECL_INITIAL (new) = ctor;
- if (align > DECL_ALIGN (new))
+ gimple_add_tmp_var (new_tree);
+ TREE_STATIC (new_tree) = 1;
+ TREE_READONLY (new_tree) = 1;
+ DECL_INITIAL (new_tree) = ctor;
+ if (align > DECL_ALIGN (new_tree))
{
- DECL_ALIGN (new) = align;
- DECL_USER_ALIGN (new) = 1;
+ DECL_ALIGN (new_tree) = align;
+ DECL_USER_ALIGN (new_tree) = 1;
}
- walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL);
+ walk_tree (&DECL_INITIAL (new_tree), force_labels_r, NULL, NULL);
- TREE_OPERAND (*expr_p, 1) = new;
+ TREE_OPERAND (*expr_p, 1) = new_tree;
/* This is no longer an assignment of a CONSTRUCTOR, but
we still may have processing to do on the LHS. So
/* If we're assigning from a constant constructor, move the
constructor expression to the RHS of the MODIFY_EXPR. */
if (DECL_INITIAL (*from_p)
- && TYPE_READONLY (TREE_TYPE (*from_p))
+ && TREE_READONLY (*from_p)
&& !TREE_THIS_VOLATILE (*from_p)
&& TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
{
/* Mark the RHS addressable. */
ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
is_gimple_addressable, fb_either);
- if (ret != GS_ERROR)
- {
- op0 = TREE_OPERAND (expr, 0);
+ if (ret == GS_ERROR)
+ break;
- /* For various reasons, the gimplification of the expression
- may have made a new INDIRECT_REF. */
- if (TREE_CODE (op0) == INDIRECT_REF)
- goto do_indirect_ref;
+ /* We cannot rely on making the RHS addressable if it is
+ a temporary created by gimplification. In this case create a
+ new temporary that is initialized by a copy (which will
+ become a store after we mark it addressable).
+ This mostly happens if the frontend passed us something that
+ it could not mark addressable yet, like a fortran
+ pass-by-reference parameter (int) floatvar. */
+ if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0)))
+ TREE_OPERAND (expr, 0)
+ = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
- /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
- recompute_tree_invariant_for_addr_expr (expr);
+ op0 = TREE_OPERAND (expr, 0);
- mark_addressable (TREE_OPERAND (expr, 0));
- }
+ /* For various reasons, the gimplification of the expression
+ may have made a new INDIRECT_REF. */
+ if (TREE_CODE (op0) == INDIRECT_REF)
+ goto do_indirect_ref;
+
+ /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
+ recompute_tree_invariant_for_addr_expr (expr);
+
+ mark_addressable (TREE_OPERAND (expr, 0));
break;
}
mark_addressable (TREE_VALUE (link));
if (tret == GS_ERROR)
{
+ if (EXPR_HAS_LOCATION (TREE_VALUE (link)))
+ input_location = EXPR_LOCATION (TREE_VALUE (link));
error ("memory input %d is not directly addressable", i);
ret = tret;
}
}
else
{
- gimple try;
+ gimple gtry;
gimple_seq seq;
enum gimple_try_flags kind;
kind = GIMPLE_TRY_FINALLY;
seq = gsi_split_seq_after (iter);
- try = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
+ gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
/* Do not use gsi_replace here, as it may scan operands.
We want to do a simple structural modification only. */
- *gsi_stmt_ptr (&iter) = try;
+ *gsi_stmt_ptr (&iter) = gtry;
iter = gsi_start (seq);
}
}
The second is gimple immediate saving a need for extra statement.
*/
if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
- && (tmp = maybe_fold_offset_to_reference
+ && (tmp = maybe_fold_offset_to_address
(TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1),
- TREE_TYPE (TREE_TYPE (*expr_p)))))
- {
- tree ptr_type = build_pointer_type (TREE_TYPE (tmp));
- if (useless_type_conversion_p (TREE_TYPE (*expr_p), ptr_type))
- {
- *expr_p = build_fold_addr_expr_with_type (tmp, ptr_type);
- break;
- }
- }
+ TREE_TYPE (*expr_p))))
+ {
+ *expr_p = tmp;
+ break;
+ }
/* Convert (void *)&a + 4 into (void *)&a[1]. */
if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == NOP_EXPR
&& TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p,
0),0)))
- && (tmp = maybe_fold_offset_to_reference
+ && (tmp = maybe_fold_offset_to_address
(TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 0),
TREE_OPERAND (*expr_p, 1),
- TREE_TYPE (TREE_TYPE
- (TREE_OPERAND (TREE_OPERAND (*expr_p, 0),
- 0))))))
+ TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, 0),
+ 0)))))
{
- tmp = build_fold_addr_expr (tmp);
*expr_p = fold_convert (TREE_TYPE (*expr_p), tmp);
break;
}