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> 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 PR tree-optimization/36766
* tree-cfg.c (gimple_purge_all_dead_eh_edges): Do nothing * tree-cfg.c (gimple_purge_all_dead_eh_edges): Do nothing
for already removed basic blocks. for already removed basic blocks.
......
...@@ -5803,38 +5803,34 @@ alpha_build_builtin_va_list (void) ...@@ -5803,38 +5803,34 @@ alpha_build_builtin_va_list (void)
/* Helper function for alpha_stdarg_optimize_hook. Skip over casts /* Helper function for alpha_stdarg_optimize_hook. Skip over casts
and constant additions. */ and constant additions. */
static tree static gimple
va_list_skip_additions (tree lhs) va_list_skip_additions (tree lhs)
{ {
tree rhs, stmt; gimple stmt;
if (TREE_CODE (lhs) != SSA_NAME)
return lhs;
for (;;) for (;;)
{ {
enum tree_code code;
stmt = SSA_NAME_DEF_STMT (lhs); stmt = SSA_NAME_DEF_STMT (lhs);
if (TREE_CODE (stmt) == PHI_NODE) if (gimple_code (stmt) == GIMPLE_PHI)
return stmt; return stmt;
if (TREE_CODE (stmt) != MODIFY_EXPR if (!is_gimple_assign (stmt)
|| TREE_OPERAND (stmt, 0) != lhs) || gimple_assign_lhs (stmt) != lhs)
return lhs; return NULL;
rhs = TREE_OPERAND (stmt, 1);
if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
rhs = TREE_OPERAND (rhs, 0);
if (((!CONVERT_EXPR_P (rhs)) if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
&& ((TREE_CODE (rhs) != PLUS_EXPR return stmt;
&& TREE_CODE (rhs) != POINTER_PLUS_EXPR) code = gimple_assign_rhs_code (stmt);
|| TREE_CODE (TREE_OPERAND (rhs, 1)) != INTEGER_CST if (!CONVERT_EXPR_CODE_P (code)
|| !host_integerp (TREE_OPERAND (rhs, 1), 1))) && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
|| TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME) || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
return rhs; || !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) ...@@ -5859,36 +5855,49 @@ va_list_skip_additions (tree lhs)
static bool static bool
alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt) alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
{ {
tree base, offset, arg1, arg2; tree base, offset, rhs;
int offset_arg = 1; int offset_arg = 1;
gimple base_stmt;
#if 1 if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
/* FIXME tuples. */ != GIMPLE_SINGLE_RHS)
(void) si;
(void) stmt;
return false; return false;
#else
rhs = gimple_assign_rhs1 (stmt);
while (handled_component_p (rhs)) while (handled_component_p (rhs))
rhs = TREE_OPERAND (rhs, 0); rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) != INDIRECT_REF if (TREE_CODE (rhs) != INDIRECT_REF
|| TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME) || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
return false; return false;
lhs = va_list_skip_additions (TREE_OPERAND (rhs, 0)); stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
if (lhs == NULL_TREE if (stmt == NULL
|| TREE_CODE (lhs) != POINTER_PLUS_EXPR) || !is_gimple_assign (stmt)
|| gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
return false; return false;
base = TREE_OPERAND (lhs, 0); base = gimple_assign_rhs1 (stmt);
if (TREE_CODE (base) == SSA_NAME) 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 if (TREE_CODE (base) != COMPONENT_REF
|| TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node)) || 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) 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 if (TREE_CODE (base) != COMPONENT_REF
|| TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node)) || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
...@@ -5902,44 +5911,71 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt) ...@@ -5902,44 +5911,71 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
|| !bitmap_bit_p (si->va_list_vars, DECL_UID (base))) || !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
return false; return false;
offset = TREE_OPERAND (lhs, offset_arg); offset = gimple_op (stmt, 1 + offset_arg);
if (TREE_CODE (offset) == SSA_NAME) if (TREE_CODE (offset) == SSA_NAME)
offset = va_list_skip_additions (offset); {
gimple offset_stmt = va_list_skip_additions (offset);
if (TREE_CODE (offset) == PHI_NODE) if (offset_stmt
&& gimple_code (offset_stmt) == GIMPLE_PHI)
{ {
HOST_WIDE_INT sub; HOST_WIDE_INT sub;
gimple arg1_stmt, arg2_stmt;
tree arg1, arg2;
enum tree_code code1, code2;
if (PHI_NUM_ARGS (offset) != 2) if (gimple_phi_num_args (offset_stmt) != 2)
goto escapes; goto escapes;
arg1 = va_list_skip_additions (PHI_ARG_DEF (offset, 0)); arg1_stmt
arg2 = va_list_skip_additions (PHI_ARG_DEF (offset, 1)); = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR) arg2_stmt
{ = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
tree tem = arg1; if (arg1_stmt == NULL
arg1 = arg2; || !is_gimple_assign (arg1_stmt)
arg2 = tem; || arg2_stmt == NULL
|| !is_gimple_assign (arg2_stmt))
if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
goto escapes; 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;
} }
if (!host_integerp (TREE_OPERAND (arg2, 1), 0)) else
goto escapes;
if (!host_integerp (gimple_assign_rhs2 (arg2_stmt), 0))
goto escapes; goto escapes;
sub = tree_low_cst (TREE_OPERAND (arg2, 1), 0); sub = tree_low_cst (gimple_assign_rhs2 (arg2_stmt), 0);
if (TREE_CODE (arg2) == MINUS_EXPR) if (code2 == MINUS_EXPR)
sub = -sub; sub = -sub;
if (sub < -48 || sub > -32) if (sub < -48 || sub > -32)
goto escapes; goto escapes;
arg2 = va_list_skip_additions (TREE_OPERAND (arg2, 0)); 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) if (arg1 != arg2)
goto escapes; goto escapes;
if (TREE_CODE (arg1) == SSA_NAME)
arg1 = va_list_skip_additions (arg1);
if (TREE_CODE (arg1) != COMPONENT_REF if (TREE_CODE (arg1) != COMPONENT_REF
|| TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
|| get_base_address (arg1) != base) || get_base_address (arg1) != base)
...@@ -5947,8 +5983,14 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt) ...@@ -5947,8 +5983,14 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
/* Need floating point regs. */ /* Need floating point regs. */
cfun->va_list_fpr_size |= 2; 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 if (TREE_CODE (offset) != COMPONENT_REF
|| TREE_OPERAND (offset, 1) != va_list_gpr_counter_field || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
|| get_base_address (offset) != base) || get_base_address (offset) != base)
goto escapes; goto escapes;
...@@ -5960,7 +6002,6 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt) ...@@ -5960,7 +6002,6 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
escapes: escapes:
si->va_list_escapes = true; si->va_list_escapes = true;
return false; return false;
#endif
} }
#endif #endif
...@@ -6126,10 +6167,11 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) ...@@ -6126,10 +6167,11 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
} }
static tree 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) 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 /* If the type could not be passed in registers, skip the block
reserved for the registers. */ reserved for the registers. */
...@@ -6177,7 +6219,7 @@ alpha_gimplify_va_arg_1 (tree type, tree base, gimple_seq offset, ...@@ -6177,7 +6219,7 @@ alpha_gimplify_va_arg_1 (tree type, tree base, gimple_seq offset,
fold_convert (sizetype, addend)); fold_convert (sizetype, addend));
internal_post = NULL; internal_post = NULL;
gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue); 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. */ /* Update the offset field. */
type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type)); 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, ...@@ -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); r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
/* Stuff the offset temporary back into its field. */ /* 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); fold_convert (TREE_TYPE (offset_field), offset), pre_p);
if (indirect) 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