Commit 777b1fbe by Jakub Jelinek Committed by Jakub Jelinek

alpha.c (va_list_skip_additions, [...]): Tuplify.

	* config/alpha/alpha.c (va_list_skip_additions,
	alpha_stdarg_optimize_hook, alpha_gimplify_va_arg_1): Tuplify.
	(alpha_gimplify_va_arg): Call unshare_expr on second use of
	offset_field.

From-SVN: r139909
parent 833ee764
2008-09-02 Jakub Jelinek <jakub@redhat.com>
* config/alpha/alpha.c (va_list_skip_additions,
alpha_stdarg_optimize_hook, alpha_gimplify_va_arg_1): Tuplify.
(alpha_gimplify_va_arg): Call unshare_expr on second use of
offset_field.
PR tree-optimization/36766
* tree-cfg.c (gimple_purge_all_dead_eh_edges): Do nothing
for already removed basic blocks.
......
......@@ -5803,38 +5803,34 @@ alpha_build_builtin_va_list (void)
/* Helper function for alpha_stdarg_optimize_hook. Skip over casts
and constant additions. */
static tree
static gimple
va_list_skip_additions (tree lhs)
{
tree rhs, stmt;
if (TREE_CODE (lhs) != SSA_NAME)
return lhs;
gimple stmt;
for (;;)
{
enum tree_code code;
stmt = SSA_NAME_DEF_STMT (lhs);
if (TREE_CODE (stmt) == PHI_NODE)
if (gimple_code (stmt) == GIMPLE_PHI)
return stmt;
if (TREE_CODE (stmt) != MODIFY_EXPR
|| TREE_OPERAND (stmt, 0) != lhs)
return lhs;
rhs = TREE_OPERAND (stmt, 1);
if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
rhs = TREE_OPERAND (rhs, 0);
if (!is_gimple_assign (stmt)
|| gimple_assign_lhs (stmt) != lhs)
return NULL;
if (((!CONVERT_EXPR_P (rhs))
&& ((TREE_CODE (rhs) != PLUS_EXPR
&& TREE_CODE (rhs) != POINTER_PLUS_EXPR)
|| TREE_CODE (TREE_OPERAND (rhs, 1)) != INTEGER_CST
|| !host_integerp (TREE_OPERAND (rhs, 1), 1)))
|| TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
return rhs;
if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
return stmt;
code = gimple_assign_rhs_code (stmt);
if (!CONVERT_EXPR_CODE_P (code)
&& ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
|| TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
|| !host_integerp (gimple_assign_rhs2 (stmt), 1)))
return stmt;
lhs = TREE_OPERAND (rhs, 0);
lhs = gimple_assign_rhs1 (stmt);
}
}
......@@ -5859,36 +5855,49 @@ va_list_skip_additions (tree lhs)
static bool
alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
{
tree base, offset, arg1, arg2;
tree base, offset, rhs;
int offset_arg = 1;
gimple base_stmt;
#if 1
/* FIXME tuples. */
(void) si;
(void) stmt;
return false;
#else
if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
!= GIMPLE_SINGLE_RHS)
return false;
rhs = gimple_assign_rhs1 (stmt);
while (handled_component_p (rhs))
rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) != INDIRECT_REF
|| TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
return false;
lhs = va_list_skip_additions (TREE_OPERAND (rhs, 0));
if (lhs == NULL_TREE
|| TREE_CODE (lhs) != POINTER_PLUS_EXPR)
stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
if (stmt == NULL
|| !is_gimple_assign (stmt)
|| gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
return false;
base = TREE_OPERAND (lhs, 0);
base = gimple_assign_rhs1 (stmt);
if (TREE_CODE (base) == SSA_NAME)
base = va_list_skip_additions (base);
{
base_stmt = va_list_skip_additions (base);
if (base_stmt
&& is_gimple_assign (base_stmt)
&& gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
base = gimple_assign_rhs1 (base_stmt);
}
if (TREE_CODE (base) != COMPONENT_REF
|| TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
{
base = TREE_OPERAND (lhs, 0);
base = gimple_assign_rhs2 (stmt);
if (TREE_CODE (base) == SSA_NAME)
base = va_list_skip_additions (base);
{
base_stmt = va_list_skip_additions (base);
if (base_stmt
&& is_gimple_assign (base_stmt)
&& gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
base = gimple_assign_rhs1 (base_stmt);
}
if (TREE_CODE (base) != COMPONENT_REF
|| TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
......@@ -5902,55 +5911,88 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
|| !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
return false;
offset = TREE_OPERAND (lhs, offset_arg);
offset = gimple_op (stmt, 1 + offset_arg);
if (TREE_CODE (offset) == SSA_NAME)
offset = va_list_skip_additions (offset);
if (TREE_CODE (offset) == PHI_NODE)
{
HOST_WIDE_INT sub;
if (PHI_NUM_ARGS (offset) != 2)
goto escapes;
gimple offset_stmt = va_list_skip_additions (offset);
arg1 = va_list_skip_additions (PHI_ARG_DEF (offset, 0));
arg2 = va_list_skip_additions (PHI_ARG_DEF (offset, 1));
if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
if (offset_stmt
&& gimple_code (offset_stmt) == GIMPLE_PHI)
{
tree tem = arg1;
arg1 = arg2;
arg2 = tem;
HOST_WIDE_INT sub;
gimple arg1_stmt, arg2_stmt;
tree arg1, arg2;
enum tree_code code1, code2;
if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
if (gimple_phi_num_args (offset_stmt) != 2)
goto escapes;
}
if (!host_integerp (TREE_OPERAND (arg2, 1), 0))
goto escapes;
sub = tree_low_cst (TREE_OPERAND (arg2, 1), 0);
if (TREE_CODE (arg2) == MINUS_EXPR)
sub = -sub;
if (sub < -48 || sub > -32)
goto escapes;
arg1_stmt
= va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
arg2_stmt
= va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
if (arg1_stmt == NULL
|| !is_gimple_assign (arg1_stmt)
|| arg2_stmt == NULL
|| !is_gimple_assign (arg2_stmt))
goto escapes;
arg2 = va_list_skip_additions (TREE_OPERAND (arg2, 0));
if (arg1 != arg2)
goto escapes;
code1 = gimple_assign_rhs_code (arg1_stmt);
code2 = gimple_assign_rhs_code (arg2_stmt);
if (code1 == COMPONENT_REF
&& (code2 == MINUS_EXPR || code2 == PLUS_EXPR))
/* Do nothing. */;
else if (code2 == COMPONENT_REF
&& (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
{
gimple tem = arg1_stmt;
code2 = code1;
arg1_stmt = arg2_stmt;
arg2_stmt = tem;
}
else
goto escapes;
if (TREE_CODE (arg1) == SSA_NAME)
arg1 = va_list_skip_additions (arg1);
if (!host_integerp (gimple_assign_rhs2 (arg2_stmt), 0))
goto escapes;
if (TREE_CODE (arg1) != COMPONENT_REF
|| TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
|| get_base_address (arg1) != base)
goto escapes;
sub = tree_low_cst (gimple_assign_rhs2 (arg2_stmt), 0);
if (code2 == MINUS_EXPR)
sub = -sub;
if (sub < -48 || sub > -32)
goto escapes;
/* Need floating point regs. */
cfun->va_list_fpr_size |= 2;
arg1 = gimple_assign_rhs1 (arg1_stmt);
arg2 = gimple_assign_rhs1 (arg2_stmt);
if (TREE_CODE (arg2) == SSA_NAME)
{
arg2_stmt = va_list_skip_additions (arg2);
if (arg2_stmt == NULL
|| !is_gimple_assign (arg2_stmt)
|| gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF)
goto escapes;
arg2 = gimple_assign_rhs1 (arg2_stmt);
}
if (arg1 != arg2)
goto escapes;
if (TREE_CODE (arg1) != COMPONENT_REF
|| TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
|| get_base_address (arg1) != base)
goto escapes;
/* Need floating point regs. */
cfun->va_list_fpr_size |= 2;
return false;
}
if (offset_stmt
&& is_gimple_assign (offset_stmt)
&& gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF)
offset = gimple_assign_rhs1 (offset_stmt);
}
else if (TREE_CODE (offset) != COMPONENT_REF
|| TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
|| get_base_address (offset) != base)
if (TREE_CODE (offset) != COMPONENT_REF
|| TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
|| get_base_address (offset) != base)
goto escapes;
else
/* Need general regs. */
......@@ -5960,7 +6002,6 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
escapes:
si->va_list_escapes = true;
return false;
#endif
}
#endif
......@@ -6126,10 +6167,11 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
}
static tree
alpha_gimplify_va_arg_1 (tree type, tree base, gimple_seq offset,
alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
gimple_seq *pre_p)
{
tree type_size, ptr_type, addend, t, addr, internal_post;
tree type_size, ptr_type, addend, t, addr;
gimple_seq internal_post;
/* If the type could not be passed in registers, skip the block
reserved for the registers. */
......@@ -6177,7 +6219,7 @@ alpha_gimplify_va_arg_1 (tree type, tree base, gimple_seq offset,
fold_convert (sizetype, addend));
internal_post = NULL;
gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
append_to_statement_list (internal_post, pre_p);
gimple_seq_add_seq (pre_p, internal_post);
/* Update the offset field. */
type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
......@@ -6230,7 +6272,7 @@ alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
/* Stuff the offset temporary back into its field. */
gimplify_assign (offset_field,
gimplify_assign (unshare_expr (offset_field),
fold_convert (TREE_TYPE (offset_field), offset), pre_p);
if (indirect)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment