diff options
author | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-22 14:28:19 +0000 |
---|---|---|
committer | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-22 14:28:19 +0000 |
commit | dd3041ec706fc47c33787b3ca7d70f3c70d3b871 (patch) | |
tree | 8aa34619b1ef17308331ab6e7e65a2b4e3ba31c7 /gcc/tree-sra.c | |
parent | d056c63a74def58752384d10729653a923182c3c (diff) | |
download | gcc-dd3041ec706fc47c33787b3ca7d70f3c70d3b871.tar.gz |
2014-11-22 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/60770
* tree-sra.c (clobber_subtree): New function.
(sra_modify_constructor_assign): Call it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217967 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 8e4b94c1e95..0d5bcef33ff 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2729,6 +2729,37 @@ init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi, init_subtree_with_zero (child, gsi, insert_after, loc); } +/* Clobber all scalar replacements in an access subtree. ACCESS is the the + root of the subtree to be processed. GSI is the statement iterator used + for inserting statements which are added after the current statement if + INSERT_AFTER is true or before it otherwise. */ + +static void +clobber_subtree (struct access *access, gimple_stmt_iterator *gsi, + bool insert_after, location_t loc) + +{ + struct access *child; + + if (access->grp_to_be_replaced) + { + tree rep = get_access_replacement (access); + tree clobber = build_constructor (access->type, NULL); + TREE_THIS_VOLATILE (clobber) = 1; + gimple stmt = gimple_build_assign (rep, clobber); + + if (insert_after) + gsi_insert_after (gsi, stmt, GSI_NEW_STMT); + else + gsi_insert_before (gsi, stmt, GSI_SAME_STMT); + update_stmt (stmt); + gimple_set_location (stmt, loc); + } + + for (child = access->first_child; child; child = child->next_sibling) + clobber_subtree (child, gsi, insert_after, loc); +} + /* Search for an access representative for the given expression EXPR and return it or NULL if it cannot be found. */ @@ -3041,17 +3072,16 @@ static enum assignment_mod_result sra_modify_constructor_assign (gimple stmt, gimple_stmt_iterator *gsi) { tree lhs = gimple_assign_lhs (stmt); - struct access *acc; - location_t loc; - - acc = get_access_for_expr (lhs); + struct access *acc = get_access_for_expr (lhs); if (!acc) return SRA_AM_NONE; + location_t loc = gimple_location (stmt); if (gimple_clobber_p (stmt)) { - /* Remove clobbers of fully scalarized variables, otherwise - do nothing. */ + /* Clobber the replacement variable. */ + clobber_subtree (acc, gsi, !acc->grp_covered, loc); + /* Remove clobbers of fully scalarized variables, they are dead. */ if (acc->grp_covered) { unlink_stmt_vdef (stmt); @@ -3060,10 +3090,9 @@ sra_modify_constructor_assign (gimple stmt, gimple_stmt_iterator *gsi) return SRA_AM_REMOVED; } else - return SRA_AM_NONE; + return SRA_AM_MODIFIED; } - loc = gimple_location (stmt); if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (stmt))) > 0) { /* I have never seen this code path trigger but if it can happen the |