passes.c (init_optimization_passes): Add simple dce and addressable passes.
* passes.c (init_optimization_passes): Add simple dce and addressable passes. * tree-ssa.c (execute_update_addresses_taken): New function. (pass_update_address_taken): New. * tree-ssa-dse.c (execute_simple_dse): New function. (pass_simple_dse): New. * tree-pass.h (pass_simple_dse, pass_update_address_taken): Declare. From-SVN: r128239
This commit is contained in:
parent
f85138bc84
commit
201b2eadc4
5 changed files with 246 additions and 0 deletions
|
@ -1,3 +1,13 @@
|
|||
2007-09-07 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* passes.c (init_optimization_passes): Add simple dce and addressable
|
||||
passes.
|
||||
* tree-ssa.c (execute_update_addresses_taken): New function.
|
||||
(pass_update_address_taken): New.
|
||||
* tree-ssa-dse.c (execute_simple_dse): New function.
|
||||
(pass_simple_dse): New.
|
||||
* tree-pass.h (pass_simple_dse, pass_update_address_taken): Declare.
|
||||
|
||||
2007-09-07 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR middle-end/33321
|
||||
|
|
|
@ -523,10 +523,14 @@ init_optimization_passes (void)
|
|||
NEXT_PASS (pass_rename_ssa_copies);
|
||||
NEXT_PASS (pass_ccp);
|
||||
NEXT_PASS (pass_forwprop);
|
||||
NEXT_PASS (pass_update_address_taken);
|
||||
NEXT_PASS (pass_simple_dse);
|
||||
NEXT_PASS (pass_sra_early);
|
||||
NEXT_PASS (pass_copy_prop);
|
||||
NEXT_PASS (pass_merge_phi);
|
||||
NEXT_PASS (pass_dce);
|
||||
NEXT_PASS (pass_update_address_taken);
|
||||
NEXT_PASS (pass_simple_dse);
|
||||
NEXT_PASS (pass_tail_recursion);
|
||||
NEXT_PASS (pass_profile);
|
||||
NEXT_PASS (pass_release_ssa_names);
|
||||
|
|
|
@ -306,6 +306,7 @@ extern struct tree_opt_pass pass_forwprop;
|
|||
extern struct tree_opt_pass pass_phiprop;
|
||||
extern struct tree_opt_pass pass_tree_ifcombine;
|
||||
extern struct tree_opt_pass pass_dse;
|
||||
extern struct tree_opt_pass pass_simple_dse;
|
||||
extern struct tree_opt_pass pass_nrv;
|
||||
extern struct tree_opt_pass pass_mark_used_blocks;
|
||||
extern struct tree_opt_pass pass_rename_ssa_copies;
|
||||
|
@ -445,6 +446,7 @@ extern struct tree_opt_pass pass_early_inline;
|
|||
extern struct tree_opt_pass pass_inline_parameters;
|
||||
extern struct tree_opt_pass pass_apply_inline;
|
||||
extern struct tree_opt_pass pass_all_early_optimizations;
|
||||
extern struct tree_opt_pass pass_update_address_taken;
|
||||
|
||||
/* The root of the compilation pass tree, once constructed. */
|
||||
extern struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes;
|
||||
|
|
|
@ -918,3 +918,137 @@ struct tree_opt_pass pass_dse = {
|
|||
| TODO_verify_ssa, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
||||
/* A very simple dead store pass eliminating write only local variables.
|
||||
The pass does not require alias information and thus can be run before
|
||||
inlining to quickly eliminate artifacts of some common C++ constructs. */
|
||||
|
||||
static unsigned int
|
||||
execute_simple_dse (void)
|
||||
{
|
||||
block_stmt_iterator bsi;
|
||||
basic_block bb;
|
||||
bitmap variables_loaded = BITMAP_ALLOC (NULL);
|
||||
unsigned int todo = 0;
|
||||
|
||||
/* Collect into VARIABLES LOADED all variables that are read in function
|
||||
body. */
|
||||
FOR_EACH_BB (bb)
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
if (LOADED_SYMS (bsi_stmt (bsi)))
|
||||
bitmap_ior_into (variables_loaded,
|
||||
LOADED_SYMS (bsi_stmt (bsi)));
|
||||
|
||||
/* Look for statements writting into the write only variables.
|
||||
And try to remove them. */
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
|
||||
{
|
||||
tree stmt = bsi_stmt (bsi), op;
|
||||
bool removed = false;
|
||||
ssa_op_iter iter;
|
||||
|
||||
if (STORED_SYMS (stmt) && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
|
||||
&& TREE_CODE (stmt) != RETURN_EXPR
|
||||
&& !bitmap_intersect_p (STORED_SYMS (stmt), variables_loaded))
|
||||
{
|
||||
unsigned int i;
|
||||
bitmap_iterator bi;
|
||||
bool dead = true;
|
||||
|
||||
|
||||
|
||||
/* See if STMT only stores to write-only variables and
|
||||
verify that there are no volatile operands. tree-ssa-operands
|
||||
sets has_volatile_ops flag for all statements involving
|
||||
reads and writes when aliases are not built to prevent passes
|
||||
from removing them as dead. The flag thus has no use for us
|
||||
and we need to look into all operands. */
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP (STORED_SYMS (stmt), 0, i, bi)
|
||||
{
|
||||
tree var = referenced_var_lookup (i);
|
||||
if (TREE_ADDRESSABLE (var)
|
||||
|| is_global_var (var)
|
||||
|| TREE_THIS_VOLATILE (var))
|
||||
dead = false;
|
||||
}
|
||||
|
||||
if (dead && LOADED_SYMS (stmt))
|
||||
EXECUTE_IF_SET_IN_BITMAP (LOADED_SYMS (stmt), 0, i, bi)
|
||||
if (TREE_THIS_VOLATILE (referenced_var_lookup (i)))
|
||||
dead = false;
|
||||
|
||||
if (dead)
|
||||
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_OPERANDS)
|
||||
if (TREE_THIS_VOLATILE (op))
|
||||
dead = false;
|
||||
|
||||
/* Look for possible occurence var = indirect_ref (...) where
|
||||
indirect_ref itself is volatile. */
|
||||
|
||||
if (dead && TREE_THIS_VOLATILE (GIMPLE_STMT_OPERAND (stmt, 1)))
|
||||
dead = false;
|
||||
|
||||
if (dead)
|
||||
{
|
||||
tree call = get_call_expr_in (stmt);
|
||||
|
||||
/* When LHS of var = call (); is dead, simplify it into
|
||||
call (); saving one operand. */
|
||||
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
|
||||
&& call
|
||||
&& TREE_SIDE_EFFECTS (call))
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "Deleted LHS of call: ");
|
||||
print_generic_stmt (dump_file, stmt, TDF_SLIM);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
push_stmt_changes (bsi_stmt_ptr (bsi));
|
||||
TREE_BLOCK (call) = TREE_BLOCK (stmt);
|
||||
bsi_replace (&bsi, call, false);
|
||||
maybe_clean_or_replace_eh_stmt (stmt, call);
|
||||
mark_symbols_for_renaming (call);
|
||||
pop_stmt_changes (bsi_stmt_ptr (bsi));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, " Deleted dead store '");
|
||||
print_generic_expr (dump_file, stmt, dump_flags);
|
||||
fprintf (dump_file, "'\n");
|
||||
}
|
||||
removed = true;
|
||||
bsi_remove (&bsi, true);
|
||||
todo |= TODO_cleanup_cfg;
|
||||
}
|
||||
todo |= TODO_remove_unused_locals | TODO_ggc_collect;
|
||||
}
|
||||
}
|
||||
if (!removed)
|
||||
bsi_next (&bsi);
|
||||
}
|
||||
BITMAP_FREE (variables_loaded);
|
||||
return todo;
|
||||
}
|
||||
|
||||
struct tree_opt_pass pass_simple_dse =
|
||||
{
|
||||
"sdse", /* name */
|
||||
NULL, /* gate */
|
||||
execute_simple_dse, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
0, /* tv_id */
|
||||
PROP_ssa, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_dump_func, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
|
|
@ -1378,3 +1378,99 @@ struct tree_opt_pass pass_late_warn_uninitialized =
|
|||
0, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
||||
/* Compute TREE_ADDRESSABLE for local variables. */
|
||||
|
||||
static unsigned int
|
||||
execute_update_addresses_taken (void)
|
||||
{
|
||||
tree var;
|
||||
referenced_var_iterator rvi;
|
||||
block_stmt_iterator bsi;
|
||||
basic_block bb;
|
||||
bitmap addresses_taken = BITMAP_ALLOC (NULL);
|
||||
bitmap vars_updated = BITMAP_ALLOC (NULL);
|
||||
bool update_vops;
|
||||
tree phi;
|
||||
|
||||
/* Collect into ADDRESSES_TAKEN all variables whose address is taken within
|
||||
the function body. */
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
stmt_ann_t s_ann = stmt_ann (bsi_stmt (bsi));
|
||||
|
||||
if (s_ann->addresses_taken)
|
||||
bitmap_ior_into (addresses_taken, s_ann->addresses_taken);
|
||||
}
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
unsigned i, phi_num_args = PHI_NUM_ARGS (phi);
|
||||
for (i = 0; i < phi_num_args; i++)
|
||||
{
|
||||
tree op = PHI_ARG_DEF (phi, i), var;
|
||||
if (TREE_CODE (op) == ADDR_EXPR
|
||||
&& (var = get_base_address (TREE_OPERAND (op, 0))) != NULL_TREE
|
||||
&& DECL_P (var))
|
||||
bitmap_set_bit (addresses_taken, DECL_UID (var));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* When possible, clear ADDRESSABLE bit and mark variable for conversion into
|
||||
SSA. */
|
||||
FOR_EACH_REFERENCED_VAR (var, rvi)
|
||||
if (!is_global_var (var)
|
||||
&& TREE_CODE (var) != RESULT_DECL
|
||||
&& TREE_ADDRESSABLE (var)
|
||||
&& !bitmap_bit_p (addresses_taken, DECL_UID (var)))
|
||||
{
|
||||
TREE_ADDRESSABLE (var) = 0;
|
||||
if (is_gimple_reg (var))
|
||||
mark_sym_for_renaming (var);
|
||||
update_vops = true;
|
||||
bitmap_set_bit (vars_updated, DECL_UID (var));
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "No longer having address taken ");
|
||||
print_generic_expr (dump_file, var, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Operand caches needs to be recomputed for operands referencing the updated
|
||||
variables. */
|
||||
if (update_vops)
|
||||
FOR_EACH_BB (bb)
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
tree stmt = bsi_stmt (bsi);
|
||||
|
||||
if ((LOADED_SYMS (stmt)
|
||||
&& bitmap_intersect_p (LOADED_SYMS (stmt), vars_updated))
|
||||
|| (STORED_SYMS (stmt)
|
||||
&& bitmap_intersect_p (STORED_SYMS (stmt), vars_updated)))
|
||||
update_stmt (stmt);
|
||||
}
|
||||
BITMAP_FREE (addresses_taken);
|
||||
BITMAP_FREE (vars_updated);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tree_opt_pass pass_update_address_taken =
|
||||
{
|
||||
"addressables", /* name */
|
||||
NULL, /* gate */
|
||||
execute_update_addresses_taken, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
0, /* tv_id */
|
||||
PROP_ssa, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_update_ssa, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue