summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-live.c
diff options
context:
space:
mode:
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-08 16:47:16 +0000
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-08 16:47:16 +0000
commit3c25489e88a7ea2937c19abff9163d9f7d8ca53a (patch)
tree4dc2b97edd33ddeabf08fbbf07022528b2b4431c /gcc/tree-ssa-live.c
parente0eb04b1d240ef23efb1494e7d7a0b0bff45c24d (diff)
downloadgcc-3c25489e88a7ea2937c19abff9163d9f7d8ca53a.tar.gz
* gengtype.c (write_field_root): Avoid out-of-scope access of newv.
* tree-stdarg.c (execute_optimize_stdarg): Accept clobbers. * tree.h (TREE_CLOBBER_P): New macro. * gimple.h (gimple_clobber_p): New inline function. * gimplify.c (gimplify_bind_expr): Add clobbers for all variables that go out of scope and live in memory. * tree-ssa-operands.c (get_expr_operands): Transfer volatility also for constructors. * cfgexpand.c (decl_to_stack_part): New static variable. (add_stack_var): Allocate it, and remember mapping. (fini_vars_expansion): Deallocate it. (stack_var_conflict_p): Add early outs. (visit_op, visit_conflict, add_scope_conflicts_1, add_scope_conflicts): New static functions. (expand_used_vars_for_block): Don't call add_stack_var_conflict, tidy. (expand_used_vars): Add scope conflicts. (expand_gimple_stmt_1): Expand clobbers to nothing. (expand_debug_expr): Ditto. * tree-pretty-print.c (dump_generic_node): Dump clobbers nicely. * tree-ssa-live.c (remove_unused_locals): Remove clobbers that refer to otherwise unused locals. * tree-sra.c (build_accesses_from_assign): Ignore clobbers. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Clobbers of SSA names aren't necessary. (propagate_necessity): Accept and ignore constructors on the rhs, tidy. * gimple.c (walk_gimple_op): Accept constructors like mem_rhs. * tree-ssa-structalias.c (find_func_aliases): Clobbers don't store any known value. * tree-ssa-sccvn.c (vn_reference_lookup_3): Ditto, in particular they don't zero-initialize something. * tree-ssa-phiopt.c (cond_if_else_store_replacement_1): Ignore clobber RHS, we don't want PHI nodes with those. testsuite/ * gcc.dg/tree-ssa/20031015-1.c: Adjust. * g++.dg/tree-ssa/ehcleanup-1.C: Ditto. * g++.dg/eh/builtin1.C: Rewrite to not use local variables. * g++.dg/eh/builtin2.C: Ditto. * g++.dg/eh/builtin3.C: Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181172 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-live.c')
-rw-r--r--gcc/tree-ssa-live.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 65b3855775a..2a2c13393fe 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -688,6 +688,7 @@ remove_unused_locals (void)
referenced_var_iterator rvi;
bitmap global_unused_vars = NULL;
unsigned srcidx, dstidx, num;
+ bool have_local_clobbers = false;
/* Removing declarations from lexical blocks when not optimizing is
not only a waste of time, it actually causes differences in stack
@@ -720,6 +721,12 @@ remove_unused_locals (void)
if (is_gimple_debug (stmt))
continue;
+ if (gimple_clobber_p (stmt))
+ {
+ have_local_clobbers = true;
+ continue;
+ }
+
if (b)
TREE_USED (b) = true;
@@ -753,6 +760,41 @@ remove_unused_locals (void)
TREE_USED (e->goto_block) = true;
}
+ /* We do a two-pass approach about the out-of-scope clobbers. We want
+ to remove them if they are the only references to a local variable,
+ but we want to retain them when there's any other. So the first pass
+ ignores them, and the second pass (if there were any) tries to remove
+ them. */
+ if (have_local_clobbers)
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree b = gimple_block (stmt);
+
+ if (gimple_clobber_p (stmt))
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ lhs = get_base_address (lhs);
+ if (TREE_CODE (lhs) == SSA_NAME)
+ lhs = SSA_NAME_VAR (lhs);
+ if (DECL_P (lhs) && (!var_ann (lhs) || !is_used_p (lhs)))
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ continue;
+ }
+ if (b)
+ TREE_USED (b) = true;
+ }
+ gsi_next (&gsi);
+ }
+ }
+
cfun->has_local_explicit_reg_vars = false;
/* Remove unmarked local vars from local_decls. */