{
tree tmp_var;
- *save = gimple_build_call (implicit_built_in_decls[BUILT_IN_STACK_SAVE], 0);
+ *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
gimple_call_set_lhs (*save, tmp_var);
*restore
- = gimple_build_call (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
+ = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1, tmp_var);
}
SET_DECL_VALUE_EXPR (decl, t);
DECL_HAS_VALUE_EXPR_P (decl) = 1;
- t = built_in_decls[BUILT_IN_ALLOCA];
- t = build_call_expr (t, 1, DECL_SIZE_UNIT (decl));
+ t = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
+ t = build_call_expr (t, 2, DECL_SIZE_UNIT (decl),
+ size_int (DECL_ALIGN (decl)));
/* The call has been built for a variable-sized object. */
CALL_ALLOCA_FOR_VAR_P (t) = 1;
t = fold_convert (ptr_type, t);
static enum gimplify_status
gimplify_conversion (tree *expr_p)
{
- tree tem;
location_t loc = EXPR_LOCATION (*expr_p);
gcc_assert (CONVERT_EXPR_P (*expr_p));
if (tree_ssa_useless_type_conversion (*expr_p))
*expr_p = TREE_OPERAND (*expr_p, 0);
- /* 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 (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_address
- (EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0),
- 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. */
if (CONVERT_EXPR_P (*expr_p))
to_ptr = build_fold_addr_expr_loc (loc, to);
gimplify_arg (&to_ptr, seq_p, loc);
- t = implicit_built_in_decls[BUILT_IN_MEMCPY];
+ t = builtin_decl_implicit (BUILT_IN_MEMCPY);
gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
to_ptr = build_fold_addr_expr_loc (loc, to);
gimplify_arg (&to_ptr, seq_p, loc);
- t = implicit_built_in_decls[BUILT_IN_MEMSET];
+ t = builtin_decl_implicit (BUILT_IN_MEMSET);
gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
src = build_fold_addr_expr_loc (loc, op1);
dest = build_fold_addr_expr_loc (loc, op0);
- t = implicit_built_in_decls[BUILT_IN_MEMCMP];
+ t = builtin_decl_implicit (BUILT_IN_MEMCMP);
t = build_call_expr_loc (loc, t, 3, dest, src, arg);
expr
case TRUTH_XOR_EXPR:
{
tree orig_type = TREE_TYPE (*expr_p);
+ tree new_type, xop0, xop1;
*expr_p = gimple_boolify (*expr_p);
- if (!useless_type_conversion_p (orig_type, TREE_TYPE (*expr_p)))
+ new_type = TREE_TYPE (*expr_p);
+ if (!useless_type_conversion_p (orig_type, new_type))
{
*expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
ret = GS_OK;
default:
break;
}
-
+ /* Now make sure that operands have compatible type to
+ expression's new_type. */
+ xop0 = TREE_OPERAND (*expr_p, 0);
+ xop1 = TREE_OPERAND (*expr_p, 1);
+ if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
+ TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
+ new_type,
+ xop0);
+ if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
+ TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
+ new_type,
+ xop1);
/* Continue classified as tcc_binary. */
goto expr_2;
}
case FMA_EXPR:
+ case VEC_PERM_EXPR:
/* Classified as tcc_expression. */
goto expr_3;
case POINTER_PLUS_EXPR:
- /* Convert ((type *)A)+offset into &A->field_of_type_and_offset.
- 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_address
- (EXPR_LOCATION (*expr_p),
- TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1),
- TREE_TYPE (*expr_p))))
- {
- *expr_p = tmp;
- ret = GS_OK;
- 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_address
- (EXPR_LOCATION (*expr_p),
- TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 0),
- TREE_OPERAND (*expr_p, 1),
- TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, 0),
- 0)))))
- {
- *expr_p = fold_convert (TREE_TYPE (*expr_p), tmp);
- ret = GS_OK;
- break;
- }
- /* FALLTHRU */
+ {
+ enum gimplify_status r0, r1;
+ r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ recalculate_side_effects (*expr_p);
+ ret = MIN (r0, r1);
+ /* Convert &X + CST to invariant &MEM[&X, CST]. Do this
+ after gimplifying operands - this is similar to how
+ it would be folding all gimplified stmts on creation
+ to have them canonicalized, which is what we eventually
+ should do anyway. */
+ if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
+ && is_gimple_min_invariant (TREE_OPERAND (*expr_p, 0)))
+ {
+ *expr_p = build_fold_addr_expr_with_type_loc
+ (input_location,
+ fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (*expr_p)),
+ TREE_OPERAND (*expr_p, 0),
+ fold_convert (ptr_type_node,
+ TREE_OPERAND (*expr_p, 1))),
+ TREE_TYPE (*expr_p));
+ ret = MIN (ret, GS_OK);
+ }
+ break;
+ }
default:
switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
tree tmp_var;
gimple call;
- x = implicit_built_in_decls[BUILT_IN_RETURN_ADDRESS];
+ x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
call = gimple_build_call (x, 1, integer_zero_node);
tmp_var = create_tmp_var (ptr_type_node, "return_addr");
gimple_call_set_lhs (call, tmp_var);
gimplify_seq_add_stmt (&cleanup, call);
- x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
+ x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
call = gimple_build_call (x, 2,
build_fold_addr_expr (current_function_decl),
tmp_var);
gimplify_seq_add_stmt (&cleanup, call);
tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
- x = implicit_built_in_decls[BUILT_IN_RETURN_ADDRESS];
+ x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
call = gimple_build_call (x, 1, integer_zero_node);
tmp_var = create_tmp_var (ptr_type_node, "return_addr");
gimple_call_set_lhs (call, tmp_var);
gimplify_seq_add_stmt (&body, call);
- x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
+ x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
call = gimple_build_call (x, 2,
build_fold_addr_expr (current_function_decl),
tmp_var);