[tuples] Tuplify pass_stdarg
Jakub Jelinek
jakub@redhat.com
Tue Jun 10 12:56:00 GMT 2008
Hi!
This patch tuplifies the stdarg pass. Bootstrapped/regtested on
x86_64-linux (as an example of struct va_list) and regtested on i686-linux
(an example of char * va_list). I've left out the alpha bits, because
apparently config/alpha/* isn't tuplified yet at all (and I don't have
access to alpha-linux).
Ok for tuples?
2008-06-10 Jakub Jelinek <jakub@redhat.com>
* tree-stdarg.c (va_list_counter_bump): Convert to tuples.
(check_all_va_list_escapes): Likewise.
(execute_optimize_stdarg): Likewise.
(find_va_list_reference): Adjust for data being walk_stmt_info
pointer.
(check_va_list_escapes): Don't handle p+ or conversion here.
(gate_optimize_stdarg): Reenable.
* target.h (struct target): Pass gimple as second
argument to stdarg_optimize_hook instead of lhs/rhs pair.
* config/alpha/alpha.c (alpha_stdarg_optimize_hook): Adjust
arguments.
--- gcc/tree-stdarg.c.jj 2008-06-09 09:59:29.000000000 +0200
+++ gcc/tree-stdarg.c 2008-06-10 11:42:35.000000000 +0200
@@ -31,8 +31,6 @@ along with GCC; see the file COPYING3.
#include "tree-pass.h"
#include "tree-stdarg.h"
-/* FIXME tuples. */
-#if 0
/* A simple pass that attempts to optimize stdarg functions on architectures
that need to save register arguments to stack on entry to stdarg functions.
If the function doesn't use any va_start macros, no registers need to
@@ -114,7 +112,8 @@ static unsigned HOST_WIDE_INT
va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
bool gpr_p)
{
- tree stmt, lhs, orig_lhs;
+ tree lhs, orig_lhs;
+ gimple stmt;
unsigned HOST_WIDE_INT ret = 0, val, counter_val;
unsigned int max_size;
@@ -146,38 +145,31 @@ va_list_counter_bump (struct stdarg_info
stmt = SSA_NAME_DEF_STMT (lhs);
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (stmt, 0) != lhs)
+ if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs)
return (unsigned HOST_WIDE_INT) -1;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
-
- if (TREE_CODE (rhs) == SSA_NAME)
+ if ((get_gimple_rhs_class (gimple_subcode (stmt)) == GIMPLE_SINGLE_RHS
+ || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt)))
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
{
- lhs = rhs;
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
- if (CONVERT_EXPR_P (rhs)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ if ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+ || gimple_subcode (stmt) == PLUS_EXPR)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && host_integerp (gimple_assign_rhs2 (stmt), 1))
{
- lhs = TREE_OPERAND (rhs, 0);
+ ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
- if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- || TREE_CODE (rhs) == PLUS_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
- && host_integerp (TREE_OPERAND (rhs, 1), 1))
- {
- ret += tree_low_cst (TREE_OPERAND (rhs, 1), 1);
- lhs = TREE_OPERAND (rhs, 0);
- continue;
- }
+ if (get_gimple_rhs_class (gimple_subcode (stmt)) != GIMPLE_SINGLE_RHS)
+ return (unsigned HOST_WIDE_INT) -1;
+ rhs = gimple_assign_rhs1 (stmt);
if (TREE_CODE (counter) != TREE_CODE (rhs))
return (unsigned HOST_WIDE_INT) -1;
@@ -208,31 +200,21 @@ va_list_counter_bump (struct stdarg_info
stmt = SSA_NAME_DEF_STMT (lhs);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
-
- if (TREE_CODE (rhs) == SSA_NAME)
- {
- lhs = rhs;
- continue;
- }
-
- if (CONVERT_EXPR_P (rhs)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ if ((get_gimple_rhs_class (gimple_subcode (stmt)) == GIMPLE_SINGLE_RHS
+ || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt)))
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
{
- lhs = TREE_OPERAND (rhs, 0);
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
- if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- || TREE_CODE (rhs) == PLUS_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
- && host_integerp (TREE_OPERAND (rhs, 1), 1))
+ if ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+ || gimple_subcode (stmt) == PLUS_EXPR)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && host_integerp (gimple_assign_rhs2 (stmt), 1))
{
- val -= tree_low_cst (TREE_OPERAND (rhs, 1), 1);
- lhs = TREE_OPERAND (rhs, 0);
+ val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
@@ -249,7 +231,7 @@ static tree
find_va_list_reference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
void *data)
{
- bitmap va_list_vars = (bitmap) data;
+ bitmap va_list_vars = (bitmap) ((struct walk_stmt_info *) data)->info;
tree var = *tp;
if (TREE_CODE (var) == SSA_NAME)
@@ -444,12 +426,6 @@ check_va_list_escapes (struct stdarg_inf
if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
return;
- if (((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- || TREE_CODE (rhs) == PLUS_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
- || CONVERT_EXPR_P (rhs))
- rhs = TREE_OPERAND (rhs, 0);
-
if (TREE_CODE (rhs) != SSA_NAME
|| ! bitmap_bit_p (si->va_list_escape_vars,
DECL_UID (SSA_NAME_VAR (rhs))))
@@ -506,11 +482,12 @@ check_all_va_list_escapes (struct stdarg
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i), use;
+ gimple stmt = gsi_stmt (i);
+ tree use;
ssa_op_iter iter;
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
@@ -519,16 +496,12 @@ check_all_va_list_escapes (struct stdarg
DECL_UID (SSA_NAME_VAR (use))))
continue;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
+ tree rhs = gimple_assign_rhs1 (stmt);
/* x = *ap_temp; */
- if (TREE_CODE (rhs) == INDIRECT_REF
+ if (gimple_assign_rhs_code (stmt) == INDIRECT_REF
&& TREE_OPERAND (rhs, 0) == use
&& TYPE_SIZE_UNIT (TREE_TYPE (rhs))
&& host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
@@ -552,13 +525,16 @@ check_all_va_list_escapes (struct stdarg
other_ap_temp = (some_type *) ap_temp;
ap = ap_temp;
statements. */
- if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
- || CONVERT_EXPR_P (rhs))
- rhs = TREE_OPERAND (rhs, 0);
-
- if (rhs == use)
+ if (rhs == use
+ && ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+ && (TREE_CODE (gimple_assign_rhs2 (stmt))
+ == INTEGER_CST))
+ || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt))
+ || (get_gimple_rhs_class (gimple_subcode (stmt))
+ == GIMPLE_SINGLE_RHS)))
{
+ tree lhs = gimple_assign_lhs (stmt);
+
if (TREE_CODE (lhs) == SSA_NAME
&& bitmap_bit_p (si->va_list_escape_vars,
DECL_UID (SSA_NAME_VAR (lhs))))
@@ -574,7 +550,7 @@ check_all_va_list_escapes (struct stdarg
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("va_list escapes in ", dump_file);
- print_generic_expr (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fputc ('\n', dump_file);
}
return true;
@@ -584,7 +560,7 @@ check_all_va_list_escapes (struct stdarg
return false;
}
-#endif
+
/* Return true if this optimization pass should be done.
It makes only sense for stdarg functions. */
@@ -592,13 +568,8 @@ check_all_va_list_escapes (struct stdarg
static bool
gate_optimize_stdarg (void)
{
- /* FIXME tuples */
-#if 0
/* This optimization is only for stdarg functions. */
return cfun->stdarg != 0;
-#else
- return 0;
-#endif
}
@@ -607,12 +578,11 @@ gate_optimize_stdarg (void)
static unsigned int
execute_optimize_stdarg (void)
{
- /* FIXME tuples */
-#if 0
basic_block bb;
bool va_list_escapes = false;
bool va_list_simple_ptr;
struct stdarg_info si;
+ struct walk_stmt_info wi;
const char *funcname = NULL;
cfun->va_list_gpr_size = 0;
@@ -631,18 +601,17 @@ execute_optimize_stdarg (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
- tree call = get_call_expr_in (stmt), callee;
- tree ap;
+ gimple stmt = gsi_stmt (i);
+ tree callee, ap;
- if (!call)
+ if (!is_gimple_call (stmt))
continue;
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (stmt);
if (!callee
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
continue;
@@ -662,7 +631,7 @@ execute_optimize_stdarg (void)
}
si.va_start_count++;
- ap = CALL_EXPR_ARG (call, 0);
+ ap = gimple_call_arg (stmt, 0);
if (TREE_CODE (ap) != ADDR_EXPR)
{
@@ -738,10 +707,12 @@ execute_optimize_stdarg (void)
cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
calculate_dominance_info (CDI_DOMINATORS);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = si.va_list_vars;
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
si.compute_sizes = -1;
si.bb = bb;
@@ -752,12 +723,13 @@ execute_optimize_stdarg (void)
any real data movement. */
if (va_list_simple_ptr)
{
- tree phi, lhs, rhs;
+ tree lhs, rhs;
use_operand_p uop;
ssa_op_iter soi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
{
+ gimple phi = gsi_stmt (i);
lhs = PHI_RESULT (phi);
if (!is_gimple_reg (lhs))
@@ -773,14 +745,12 @@ execute_optimize_stdarg (void)
else
check_va_list_escapes (&si, lhs, rhs);
- if (si.va_list_escapes
- || walk_tree (&phi, find_va_list_reference,
- si.va_list_vars, NULL))
+ if (si.va_list_escapes)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("va_list escapes in ", dump_file);
- print_generic_expr (dump_file, phi, dump_flags);
+ print_gimple_stmt (dump_file, phi, 0, dump_flags);
fputc ('\n', dump_file);
}
va_list_escapes = true;
@@ -789,18 +759,16 @@ execute_optimize_stdarg (void)
}
}
- for (i = bsi_start (bb);
- !bsi_end_p (i) && !va_list_escapes;
- bsi_next (&i))
+ for (i = gsi_start_bb (bb);
+ !gsi_end_p (i) && !va_list_escapes;
+ gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
- tree call;
+ gimple stmt = gsi_stmt (i);
/* Don't look at __builtin_va_{start,end}, they are ok. */
- call = get_call_expr_in (stmt);
- if (call)
+ if (is_gimple_call (stmt))
{
- tree callee = get_callee_fndecl (call);
+ tree callee = gimple_call_fndecl (stmt);
if (callee
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
@@ -809,44 +777,54 @@ execute_optimize_stdarg (void)
continue;
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
if (va_list_simple_ptr)
{
- /* Check for tem = ap. */
- if (va_list_ptr_read (&si, rhs, lhs))
- continue;
+ if (get_gimple_rhs_class (gimple_subcode (stmt))
+ == GIMPLE_SINGLE_RHS)
+ {
+ /* Check for tem = ap. */
+ if (va_list_ptr_read (&si, rhs, lhs))
+ continue;
- /* Check for the last insn in:
- tem1 = ap;
- tem2 = tem1 + CST;
- ap = tem2;
- sequence. */
- else if (va_list_ptr_write (&si, lhs, rhs))
- continue;
+ /* Check for the last insn in:
+ tem1 = ap;
+ tem2 = tem1 + CST;
+ ap = tem2;
+ sequence. */
+ else if (va_list_ptr_write (&si, lhs, rhs))
+ continue;
+ }
- else
+ if ((gimple_subcode (stmt) == POINTER_PLUS_EXPR
+ && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
+ || IS_CONVERT_EXPR_CODE_P (gimple_subcode (stmt))
+ || (get_gimple_rhs_class (gimple_subcode (stmt))
+ == GIMPLE_SINGLE_RHS))
check_va_list_escapes (&si, lhs, rhs);
}
else
{
- /* Check for ap[0].field = temp. */
- if (va_list_counter_struct_op (&si, lhs, rhs, true))
- continue;
+ if (get_gimple_rhs_class (gimple_subcode (stmt))
+ == GIMPLE_SINGLE_RHS)
+ {
+ /* Check for ap[0].field = temp. */
+ if (va_list_counter_struct_op (&si, lhs, rhs, true))
+ continue;
- /* Check for temp = ap[0].field. */
- else if (va_list_counter_struct_op (&si, rhs, lhs, false))
- continue;
+ /* Check for temp = ap[0].field. */
+ else if (va_list_counter_struct_op (&si, rhs, lhs,
+ false))
+ continue;
+ }
/* Do any architecture specific checking. */
- else if (targetm.stdarg_optimize_hook
- && targetm.stdarg_optimize_hook (&si, lhs, rhs))
+ if (targetm.stdarg_optimize_hook
+ && targetm.stdarg_optimize_hook (&si, stmt))
continue;
}
}
@@ -858,13 +836,12 @@ execute_optimize_stdarg (void)
fully), or some unexpected use of va_list. None of these should
happen in a gimplified VA_ARG_EXPR. */
if (si.va_list_escapes
- || walk_tree (&stmt, find_va_list_reference,
- si.va_list_vars, NULL))
+ || walk_gimple_op (stmt, find_va_list_reference, &wi))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("va_list escapes in ", dump_file);
- print_generic_expr (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fputc ('\n', dump_file);
}
va_list_escapes = true;
@@ -906,9 +883,6 @@ finish:
fputs (" FPR units.\n", dump_file);
}
return 0;
-#else
- gcc_unreachable ();
-#endif
}
--- gcc/target.h.jj 2008-06-09 09:59:29.000000000 +0200
+++ gcc/target.h 2008-06-10 10:37:01.000000000 +0200
@@ -745,10 +745,9 @@ struct gcc_target
void (* dwarf_handle_frame_unspec) (const char *, rtx, int);
/* Perform architecture specific checking of statements gimplified
- from VA_ARG_EXPR. LHS is left hand side of MODIFY_EXPR, RHS
- is right hand side. Returns true if the statements doesn't need
- to be checked for va_list references. */
- bool (* stdarg_optimize_hook) (struct stdarg_info *ai, const_tree lhs, const_tree rhs);
+ from VA_ARG_EXPR. STMT is the statement. Returns true if the statement
+ doesn't need to be checked for va_list references. */
+ bool (* stdarg_optimize_hook) (struct stdarg_info *ai, const_gimple stmt);
/* This target hook allows the operating system to override the DECL
that represents the external variable that contains the stack
--- gcc/config/alpha/alpha.c.jj 2008-06-09 09:59:11.000000000 +0200
+++ gcc/config/alpha/alpha.c 2008-06-10 10:47:59.000000000 +0200
@@ -5856,11 +5856,17 @@ va_list_skip_additions (tree lhs)
current statement. */
static bool
-alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree rhs)
+alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
{
tree base, offset, arg1, arg2;
int offset_arg = 1;
+#if 1
+ /* FIXME tuples. */
+ (void) si;
+ (void) stmt;
+ return false;
+#else
while (handled_component_p (rhs))
rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) != INDIRECT_REF
@@ -5953,6 +5959,7 @@ alpha_stdarg_optimize_hook (struct stdar
escapes:
si->va_list_escapes = true;
return false;
+#endif
}
#endif
Jakub
More information about the Gcc-patches
mailing list