aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2007-09-07 13:28:35 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2007-09-07 11:28:35 +0000
commit201b2eadc44a3217be14bed57b979dc4b01a5990 (patch)
treea9b189174aab2e413f3eb87f3545535fef231f0c
parentf85138bc84767bdbf1e405461578432629df11a7 (diff)
downloadgcc-201b2eadc44a3217be14bed57b979dc4b01a5990.zip
gcc-201b2eadc44a3217be14bed57b979dc4b01a5990.tar.gz
gcc-201b2eadc44a3217be14bed57b979dc4b01a5990.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/passes.c4
-rw-r--r--gcc/tree-pass.h2
-rw-r--r--gcc/tree-ssa-dse.c134
-rw-r--r--gcc/tree-ssa.c96
5 files changed, 246 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bf2bc14..be49cf5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/passes.c b/gcc/passes.c
index 29ec8e2..1b88414 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index a7de717..19bda7c 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -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;
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 68fa445..4416f7d 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -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 */
+};
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 633e446..9723afb 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -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 */
+};