On June 15, 2021 5:09:40 PM GMT+02:00, Martin Jambor <mjam...@suse.cz> wrote: >Hi, > >When SRA transforms an assignment where the RHS is an aggregate decl >that it creates replacements for, the (least efficient) fallback method >of dealing with them is to store all the replacements back into the >original decl and then let the original assignment takes its course. > >That of course should not need to be done for TREE_READONLY bases which >cannot change contents. The SRA code handled this situation only for >DECL_IN_CONSTANT_POOL const decls, this patch modifies the check so >that >it tests for TREE_READONLY and I also looked at all other callers of >generate_subtree_copies and added checks to another one dealing with >the >same exact situation and one which deals with it in a non-assignment >context. > >This behavior also means that SRA has to disqualify any candidate decl >that is read-only and written to. I plan to continue to hunt down at >least some of such occurrences. > >Bootstrapped and tested on x86_64-linux, i686-linux and aarch64-linux >(this time With Ada enabled on all three platforms). OK for trunk?
Ok. Thanks, Richard. >Thanks, > >Martin > > >gcc/ChangeLog: > >2021-06-11 Martin Jambor <mjam...@suse.cz> > > PR tree-optimization/100453 > * tree-sra.c (create_access): Disqualify any const candidates > which are written to. > (sra_modify_expr): Do not store sub-replacements back to a const base. > (handle_unscalarized_data_in_subtree): Likewise. > (sra_modify_assign): Likewise. Earlier, use TREE_READONLy test > instead of constant_decl_p. > >gcc/testsuite/ChangeLog: > >2021-06-11 Martin Jambor <mjam...@suse.cz> > > PR tree-optimization/100453 > * gcc.dg/tree-ssa/pr100453.c: New test. >--- > gcc/testsuite/gcc.dg/tree-ssa/pr100453.c | 18 ++++++++++++++++++ > gcc/tree-sra.c | 21 +++++++++++++++++---- > 2 files changed, 35 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr100453.c > >diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c >b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c >new file mode 100644 >index 00000000000..0cf0ad23815 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr100453.c >@@ -0,0 +1,18 @@ >+/* { dg-do run } */ >+/* { dg-options "-O1" } */ >+ >+struct a { >+ int b : 4; >+} d; >+static int c, e; >+static const struct a f; >+static void g(const struct a h) { >+ for (; c < 1; c++) >+ d = h; >+ e = h.b; >+ c = h.b; >+} >+int main() { >+ g(f); >+ return 0; >+} >diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c >index 8dfc923ed7e..5e86d3fbb9d 100644 >--- a/gcc/tree-sra.c >+++ b/gcc/tree-sra.c >@@ -915,6 +915,12 @@ create_access (tree expr, gimple *stmt, bool >write) >if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID >(base))) > return NULL; > >+ if (write && TREE_READONLY (base)) >+ { >+ disqualify_candidate (base, "Encountered a store to a read-only >decl."); >+ return NULL; >+ } >+ > HOST_WIDE_INT offset, size, max_size; > if (!poffset.is_constant (&offset) > || !psize.is_constant (&size) >@@ -3826,7 +3832,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator >*gsi, bool write) > gsi_insert_after (gsi, ds, GSI_NEW_STMT); > } > >- if (access->first_child) >+ if (access->first_child && !TREE_READONLY (access->base)) > { > HOST_WIDE_INT start_offset, chunk_size; > if (bfr >@@ -3890,6 +3896,13 @@ static void >handle_unscalarized_data_in_subtree (struct >subreplacement_assignment_data *sad) > { > tree src; >+ /* If the RHS is a load from a constant, we do not need to (and must >not) >+ flush replacements to it and can use it directly as if we did. >*/ >+ if (TREE_READONLY (sad->top_racc->base)) >+ { >+ sad->refreshed = SRA_UDH_RIGHT; >+ return; >+ } > if (sad->top_racc->grp_unscalarized_data) > { > src = sad->assignment_rhs; >@@ -4243,8 +4256,8 @@ sra_modify_assign (gimple *stmt, >gimple_stmt_iterator *gsi) > || contains_vce_or_bfcref_p (lhs) > || stmt_ends_bb_p (stmt)) > { >- /* No need to copy into a constant-pool, it comes >pre-initialized. */ >- if (access_has_children_p (racc) && !constant_decl_p >(racc->base)) >+ /* No need to copy into a constant, it comes pre-initialized. >*/ >+ if (access_has_children_p (racc) && !TREE_READONLY (racc->base)) > generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0, > gsi, false, false, loc); > if (access_has_children_p (lacc)) >@@ -4333,7 +4346,7 @@ sra_modify_assign (gimple *stmt, >gimple_stmt_iterator *gsi) > } > /* Restore the aggregate RHS from its components so the > prevailing aggregate copy does the right thing. */ >- if (access_has_children_p (racc)) >+ if (access_has_children_p (racc) && !TREE_READONLY (racc->base)) > generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, >0, > gsi, false, false, loc); > /* Re-load the components of the aggregate copy destination.