From: jamborm Date: Thu, 7 Oct 2010 16:15:46 +0000 (+0000) Subject: 2010-10-07 Martin Jambor X-Git-Tag: upstream/4.9.2~26024 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0b9fa291b2e0169029effa3a34f6b6a7c17838d6;p=platform%2Fupstream%2Flinaro-gcc.git 2010-10-07 Martin Jambor * tree-sra.c (struct access): New field grp_assignment_write. (dump_access): Dump grp_assignment_write. (build_accesses_from_assign): Set grp_assignment_write. (sort_and_splice_var_accesses): Aggregate grp_assignment_write. (mark_read_status): Renamed to mark_rw_status, individual values renamed too. (analyze_access_subtree): Changed type of mark_write to mark_read_status. Fixed propagating of mark_read and mark_write. Changed benefit estimate. Updated comment. * testsuite/gcc.dg/tree-ssa/sra-11.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165124 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 017b196..479b616 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2010-10-07 Martin Jambor + + * tree-sra.c (struct access): New field grp_assignment_write. + (dump_access): Dump grp_assignment_write. + (build_accesses_from_assign): Set grp_assignment_write. + (sort_and_splice_var_accesses): Aggregate grp_assignment_write. + (mark_read_status): Renamed to mark_rw_status, individual values + renamed too. + (analyze_access_subtree): Changed type of mark_write to + mark_read_status. Fixed propagating of mark_read and + mark_write. Changed benefit estimate. Updated comment. + 2010-10-07 Tejas Belagod * tree-vect-patterns.c (vect_recog_widen_mult_pattern): Add NULL diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a3380e..12be369 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-10-07 Martin Jambor + + * gcc.dg/tree-ssa/sra-11.c: New test. + 2010-10-07 Tejas Belagod * gcc.dg/vect/pr45847.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-11.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-11.c new file mode 100644 index 0000000..c8a90ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-11.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-esra-details" } */ + +struct S +{ + int i; + int j; + char c[32]; /* this disables total scalarization */ +}; + +extern struct S bar(void); + +int foo1 (int b) +{ + struct S s1; + + s1 = bar (); + return s1.i; +} + +extern struct S *g; + +int foo2 (void) +{ + struct S s2; + + s2 = *g; + return s2.i; +} + +/* { dg-final { scan-tree-dump-times "Created a replacement for s1" 0 "esra"} } */ +/* { dg-final { scan-tree-dump-times "Created a replacement for s2" 1 "esra"} } */ +/* { dg-final { cleanup-tree-dump "esra" } } */ diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 2e6a5cb..06cb6ff 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -189,6 +189,10 @@ struct access statement? This flag is propagated down the access tree. */ unsigned grp_assignment_read : 1; + /* Does this group contain a write access that comes from an assignment + statement? This flag is propagated down the access tree. */ + unsigned grp_assignment_write : 1; + /* Other passes of the analysis use this bit to make function analyze_access_subtree create scalar replacements for this group if possible. */ @@ -364,15 +368,17 @@ dump_access (FILE *f, struct access *access, bool grp) if (grp) fprintf (f, ", grp_write = %d, total_scalarization = %d, " "grp_read = %d, grp_hint = %d, grp_assignment_read = %d," - "grp_covered = %d, grp_unscalarizable_region = %d, " - "grp_unscalarized_data = %d, grp_partial_lhs = %d, " - "grp_to_be_replaced = %d, grp_maybe_modified = %d, " + "grp_assignment_write = %d, grp_covered = %d, " + "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, " + "grp_partial_lhs = %d, grp_to_be_replaced = %d, " + "grp_maybe_modified = %d, " "grp_not_necessarilly_dereferenced = %d\n", access->grp_write, access->total_scalarization, access->grp_read, access->grp_hint, access->grp_assignment_read, - access->grp_covered, access->grp_unscalarizable_region, - access->grp_unscalarized_data, access->grp_partial_lhs, - access->grp_to_be_replaced, access->grp_maybe_modified, + access->grp_assignment_write, access->grp_covered, + access->grp_unscalarizable_region, access->grp_unscalarized_data, + access->grp_partial_lhs, access->grp_to_be_replaced, + access->grp_maybe_modified, access->grp_not_necessarilly_dereferenced); else fprintf (f, ", write = %d, total_scalarization = %d, " @@ -1019,6 +1025,9 @@ build_accesses_from_assign (gimple stmt) racc = build_access_from_expr_1 (rhs, stmt, false); lacc = build_access_from_expr_1 (lhs, stmt, true); + if (lacc) + lacc->grp_assignment_write = 1; + if (racc) { racc->grp_assignment_read = 1; @@ -1581,6 +1590,7 @@ sort_and_splice_var_accesses (tree var) bool grp_write = access->write; bool grp_read = !access->write; bool grp_assignment_read = access->grp_assignment_read; + bool grp_assignment_write = access->grp_assignment_write; bool multiple_reads = false; bool total_scalarization = access->total_scalarization; bool grp_partial_lhs = access->grp_partial_lhs; @@ -1615,6 +1625,7 @@ sort_and_splice_var_accesses (tree var) grp_read = true; } grp_assignment_read |= ac2->grp_assignment_read; + grp_assignment_write |= ac2->grp_assignment_write; grp_partial_lhs |= ac2->grp_partial_lhs; unscalarizable_region |= ac2->grp_unscalarizable_region; total_scalarization |= ac2->total_scalarization; @@ -1634,6 +1645,7 @@ sort_and_splice_var_accesses (tree var) access->grp_write = grp_write; access->grp_read = grp_read; access->grp_assignment_read = grp_assignment_read; + access->grp_assignment_write = grp_assignment_write; access->grp_hint = multiple_reads || total_scalarization; access->grp_partial_lhs = grp_partial_lhs; access->grp_unscalarizable_region = unscalarizable_region; @@ -1822,17 +1834,50 @@ expr_with_var_bounded_array_refs_p (tree expr) return false; } -enum mark_read_status { SRA_MR_NOT_READ, SRA_MR_READ, SRA_MR_ASSIGN_READ}; +enum mark_rw_status { SRA_MRRW_NOTHING, SRA_MRRW_DIRECT, SRA_MRRW_ASSIGN}; /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all sorts of access flags appropriately along the way, notably always set grp_read and grp_assign_read according to MARK_READ and grp_write when - MARK_WRITE is true. */ + MARK_WRITE is true. + + Creating a replacement for a scalar access is considered beneficial if its + grp_hint is set (this means we are either attempting total scalarization or + there is more than one direct read access) or according to the following + table: + + Access written to individually (once or more times) + | + | Parent written to in an assignment statement + | | + | | Access read individually _once_ + | | | + | | | Parent read in an assignment statement + | | | | + | | | | Scalarize Comment +----------------------------------------------------------------------------- + 0 0 0 0 No access for the scalar + 0 0 0 1 No access for the scalar + 0 0 1 0 No Single read - won't help + 0 0 1 1 No The same case + 0 1 0 0 No access for the scalar + 0 1 0 1 No access for the scalar + 0 1 1 0 Yes s = *g; return s.i; + 0 1 1 1 Yes The same case as above + 1 0 0 0 No Won't help + 1 0 0 1 Yes s.i = 1; *g = s; + 1 0 1 0 Yes s.i = 5; g = s.i; + 1 0 1 1 Yes The same case as above + 1 1 0 0 No Won't help. + 1 1 0 1 Yes s.i = 1; *g = s; + 1 1 1 0 Yes s = *g; return s.i; + 1 1 1 1 Yes Any of the above yeses */ static bool analyze_access_subtree (struct access *root, bool allow_replacements, - enum mark_read_status mark_read, bool mark_write) + enum mark_rw_status mark_read, + enum mark_rw_status mark_write) { struct access *child; HOST_WIDE_INT limit = root->offset + root->size; @@ -1840,23 +1885,31 @@ analyze_access_subtree (struct access *root, bool allow_replacements, bool scalar = is_gimple_reg_type (root->type); bool hole = false, sth_created = false; bool direct_read = root->grp_read; + bool direct_write = root->grp_write; - if (mark_read == SRA_MR_ASSIGN_READ) + if (root->grp_assignment_read) + mark_read = SRA_MRRW_ASSIGN; + else if (mark_read == SRA_MRRW_ASSIGN) { root->grp_read = 1; root->grp_assignment_read = 1; } - if (mark_read == SRA_MR_READ) + else if (mark_read == SRA_MRRW_DIRECT) root->grp_read = 1; - else if (root->grp_assignment_read) - mark_read = SRA_MR_ASSIGN_READ; else if (root->grp_read) - mark_read = SRA_MR_READ; + mark_read = SRA_MRRW_DIRECT; - if (mark_write) - root->grp_write = true; + if (root->grp_assignment_write) + mark_write = SRA_MRRW_ASSIGN; + else if (mark_write == SRA_MRRW_ASSIGN) + { + root->grp_write = 1; + root->grp_assignment_write = 1; + } + else if (mark_write == SRA_MRRW_DIRECT) + root->grp_write = 1; else if (root->grp_write) - mark_write = true; + mark_write = SRA_MRRW_DIRECT; if (root->grp_unscalarizable_region) allow_replacements = false; @@ -1881,7 +1934,8 @@ analyze_access_subtree (struct access *root, bool allow_replacements, if (allow_replacements && scalar && !root->first_child && (root->grp_hint - || (root->grp_write && (direct_read || root->grp_assignment_read)))) + || ((direct_write || root->grp_assignment_write) + && (direct_read || root->grp_assignment_read)))) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1920,7 +1974,8 @@ analyze_access_trees (struct access *access) while (access) { - if (analyze_access_subtree (access, true, SRA_MR_NOT_READ, false)) + if (analyze_access_subtree (access, true, + SRA_MRRW_NOTHING, SRA_MRRW_NOTHING)) ret = true; access = access->next_grp; }