diff options
author | Richard Biener <rguenther@suse.de> | 2014-12-10 09:29:05 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-12-10 09:29:05 +0000 |
commit | 128227683ace7606605d204bd75b851a22043d6d (patch) | |
tree | 9a4757f31af85f3b526ae2e96a7b2978bf95593a /gcc/tree-ssa-dce.c | |
parent | 092444af0474ed194abe53ea7cbd950dd7e2cdbd (diff) | |
download | gcc-128227683ace7606605d204bd75b851a22043d6d.zip gcc-128227683ace7606605d204bd75b851a22043d6d.tar.gz gcc-128227683ace7606605d204bd75b851a22043d6d.tar.bz2 |
re PR tree-optimization/64191 (indirect clobbers messes up dead code elimination in loop calling dtor)
2014-12-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/64191
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Do not
mark clobbers as necessary.
(eliminate_unnecessary_stmts): Keep clobbers live if we can.
* g++.dg/pr64191.C: Make sure we can DCE empty loops with
indirect clobbers.
From-SVN: r218566
Diffstat (limited to 'gcc/tree-ssa-dce.c')
-rw-r--r-- | gcc/tree-ssa-dce.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 1d887c2..7f68770 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -292,8 +292,7 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive) break; case GIMPLE_ASSIGN: - if (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME - && TREE_CLOBBER_P (gimple_assign_rhs1 (stmt))) + if (gimple_clobber_p (stmt)) return; break; @@ -1362,6 +1361,25 @@ eliminate_unnecessary_stmts (void) /* If GSI is not necessary then remove it. */ if (!gimple_plf (stmt, STMT_NECESSARY)) { + /* Keep clobbers that we can keep live live. */ + if (gimple_clobber_p (stmt)) + { + ssa_op_iter iter; + use_operand_p use_p; + bool dead = false; + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) + { + tree name = USE_FROM_PTR (use_p); + if (!SSA_NAME_IS_DEFAULT_DEF (name) + && !bitmap_bit_p (processed, SSA_NAME_VERSION (name))) + { + dead = true; + break; + } + } + if (!dead) + continue; + } if (!is_gimple_debug (stmt)) something_changed = true; remove_dead_stmt (&gsi, bb); |