summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-02 18:25:36 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-02 18:25:36 +0000
commit9f559b20308d34be446d1ec2072ab6aef74ca9f9 (patch)
tree4ee3c2b7dfdc5ebe044adb7a6e509a7d8ffa2e13
parent7d71feb3c0860b4e12ecca400f16364a7a789367 (diff)
downloadgcc-9f559b20308d34be446d1ec2072ab6aef74ca9f9.tar.gz
PR c++/34949
* tree-cfg.c (verify_gimple_assign_single): Allow lhs of gimple_clobber_p to be MEM_REF. * gimplify.c (gimplify_modify_expr): Gimplify *to_p of an assignment from TREE_CLOBBER_P. Allow it to be MEM_REF after gimplification. * asan.c (get_mem_ref_of_assignment): Don't instrument gimple_clobber_p stmts. * tree-ssa-dse.c (dse_optimize_stmt): Allow DSE of gimple_clobber_p stmt if they have MEM_REF lhs and are dead because of another gimple_clobber_p stmt. * tree-ssa-live.c (clear_unused_block_pointer): Treat gimple_clobber_p stmts like debug stmts. (remove_unused_locals): Remove clobbers with MEM_REF lhs that refer to unused VAR_DECLs or uninitialized values. * tree-sra.c (sra_ipa_reset_debug_stmts): Also remove gimple_clobber_p stmts if they refer to removed parameters. (get_repl_default_def_ssa_name, sra_ipa_modify_expr): Fix up formatting. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197369 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/asan.c3
-rw-r--r--gcc/gimplify.c7
-rw-r--r--gcc/tree-cfg.c4
-rw-r--r--gcc/tree-sra.c16
-rw-r--r--gcc/tree-ssa-dse.c11
-rw-r--r--gcc/tree-ssa-live.c16
7 files changed, 66 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index de855d7a954..e6cfd745572 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2013-04-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34949
+ * tree-cfg.c (verify_gimple_assign_single): Allow lhs
+ of gimple_clobber_p to be MEM_REF.
+ * gimplify.c (gimplify_modify_expr): Gimplify *to_p of
+ an assignment from TREE_CLOBBER_P. Allow it to be MEM_REF
+ after gimplification.
+ * asan.c (get_mem_ref_of_assignment): Don't instrument
+ gimple_clobber_p stmts.
+ * tree-ssa-dse.c (dse_optimize_stmt): Allow DSE of
+ gimple_clobber_p stmt if they have MEM_REF lhs and
+ are dead because of another gimple_clobber_p stmt.
+ * tree-ssa-live.c (clear_unused_block_pointer): Treat
+ gimple_clobber_p stmts like debug stmts.
+ (remove_unused_locals): Remove clobbers with MEM_REF lhs
+ that refer to unused VAR_DECLs or uninitialized values.
+ * tree-sra.c (sra_ipa_reset_debug_stmts): Also remove
+ gimple_clobber_p stmts if they refer to removed parameters.
+ (get_repl_default_def_ssa_name, sra_ipa_modify_expr): Fix up
+ formatting.
+
2013-04-02 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*testqi_ext_3): Merge with *testqi_ext_3_rex64
diff --git a/gcc/asan.c b/gcc/asan.c
index 52a2dbc5dfd..36eccf93cbb 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -412,7 +412,8 @@ get_mem_ref_of_assignment (const gimple assignment,
{
gcc_assert (gimple_assign_single_p (assignment));
- if (gimple_store_p (assignment))
+ if (gimple_store_p (assignment)
+ && !gimple_clobber_p (assignment))
{
ref->start = gimple_assign_lhs (assignment);
*ref_is_store = true;
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a6a6565ce04..a93ce7c2ad2 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -4840,7 +4840,12 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
so handle it here. */
if (TREE_CLOBBER_P (*from_p))
{
- gcc_assert (!want_value && TREE_CODE (*to_p) == VAR_DECL);
+ ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+ if (ret == GS_ERROR)
+ return ret;
+ gcc_assert (!want_value
+ && (TREE_CODE (*to_p) == VAR_DECL
+ || TREE_CODE (*to_p) == MEM_REF));
gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
*expr_p = NULL;
return GS_ALL_DONE;
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 6be417b0f25..8a36976cc3b 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3815,9 +3815,9 @@ verify_gimple_assign_single (gimple stmt)
}
if (gimple_clobber_p (stmt)
- && !DECL_P (lhs))
+ && !(DECL_P (lhs) || TREE_CODE (lhs) == MEM_REF))
{
- error ("non-decl LHS in clobber statement");
+ error ("non-decl/MEM_REF LHS in clobber statement");
debug_generic_expr (lhs);
return true;
}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 93446c2151a..78efa255b1d 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2965,8 +2965,8 @@ sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
static tree
get_repl_default_def_ssa_name (struct access *racc)
{
- gcc_checking_assert (!racc->grp_to_be_replaced &&
- !racc->grp_to_be_debug_replaced);
+ gcc_checking_assert (!racc->grp_to_be_replaced
+ && !racc->grp_to_be_debug_replaced);
if (!racc->replacement_decl)
racc->replacement_decl = create_access_replacement (racc);
return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
@@ -4462,8 +4462,8 @@ sra_ipa_modify_expr (tree *expr, bool convert,
{
adj = &adjustments[i];
- if (adj->base == base &&
- (adj->offset == offset || adj->remove_param))
+ if (adj->base == base
+ && (adj->offset == offset || adj->remove_param))
{
cand = adj;
break;
@@ -4676,6 +4676,14 @@ sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
if (name)
FOR_EACH_IMM_USE_STMT (stmt, ui, name)
{
+ if (gimple_clobber_p (stmt))
+ {
+ gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&cgsi, true);
+ release_defs (stmt);
+ continue;
+ }
/* All other users must have been removed by
ipa_sra_modify_function_body. */
gcc_assert (is_gimple_debug (stmt));
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 223682b057a..e0c3b745b1e 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -218,7 +218,10 @@ dse_optimize_stmt (gimple_stmt_iterator *gsi)
if (is_gimple_call (stmt) && gimple_call_fndecl (stmt))
return;
- if (gimple_has_volatile_ops (stmt))
+ /* Don't return early on *this_2(D) ={v} {CLOBBER}. */
+ if (gimple_has_volatile_ops (stmt)
+ && (!gimple_clobber_p (stmt)
+ || TREE_CODE (gimple_assign_lhs (stmt)) != MEM_REF))
return;
if (is_gimple_assign (stmt))
@@ -228,6 +231,12 @@ dse_optimize_stmt (gimple_stmt_iterator *gsi)
if (!dse_possible_dead_store_p (stmt, &use_stmt))
return;
+ /* But only remove *this_2(D) ={v} {CLOBBER} if killed by
+ another clobber stmt. */
+ if (gimple_clobber_p (stmt)
+ && !gimple_clobber_p (use_stmt))
+ return;
+
/* If we have precisely one immediate use at this point and the
stores are to the same memory location or there is a chain of
virtual uses from stmt and the stmt which stores to that same
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 756fa373847..c8b9ce8b016 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -623,8 +623,8 @@ clear_unused_block_pointer_1 (tree *tp, int *, void *)
return NULL_TREE;
}
-/* Set all block pointer in debug stmt to NULL if the block is unused,
- so that they will not be streamed out. */
+/* Set all block pointer in debug or clobber stmt to NULL if the block
+ is unused, so that they will not be streamed out. */
static void
clear_unused_block_pointer (void)
@@ -639,7 +639,7 @@ clear_unused_block_pointer (void)
tree b;
gimple stmt = gsi_stmt (gsi);
- if (!is_gimple_debug (stmt))
+ if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt))
continue;
b = gimple_block (stmt);
if (b && !TREE_USED (b))
@@ -827,7 +827,15 @@ remove_unused_locals (void)
if (gimple_clobber_p (stmt))
{
tree lhs = gimple_assign_lhs (stmt);
- if (TREE_CODE (lhs) == VAR_DECL && !is_used_p (lhs))
+ tree base = get_base_address (lhs);
+ /* Remove clobbers referencing unused vars, or clobbers
+ with MEM_REF lhs referencing uninitialized pointers. */
+ if ((TREE_CODE (base) == VAR_DECL && !is_used_p (base))
+ || (TREE_CODE (lhs) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME
+ && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (lhs, 0))
+ && (TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (lhs, 0)))
+ != PARM_DECL)))
{
unlink_stmt_vdef (stmt);
gsi_remove (&gsi, true);