summaryrefslogtreecommitdiff
path: root/gcc/config/alpha/alpha.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/alpha/alpha.c')
-rw-r--r--gcc/config/alpha/alpha.c196
1 files changed, 119 insertions, 77 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index cad90e1adce..a4d3bf1f150 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -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)