aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2017-06-13 13:40:24 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2017-06-13 13:40:24 +0200
commit345683a95f5a9a2f6c319764da7e7491e765da86 (patch)
treeccaa86c7ea9c58ffef3b5ae4b86a308be277d376 /gcc/tree-sra.c
parent35a952ba70028b50fbd2fd19f7dc91f2da45371e (diff)
downloadgcc-345683a95f5a9a2f6c319764da7e7491e765da86.zip
gcc-345683a95f5a9a2f6c319764da7e7491e765da86.tar.gz
gcc-345683a95f5a9a2f6c319764da7e7491e765da86.tar.bz2
[PR80803 2/2] Diligent queuing in SRA grp_write prop
2017-06-13 Martin Jambor <mjambor@suse.cz> PR tree-optimization/80803 PR tree-optimization/81063 * tree-sra.c (subtree_mark_written_and_enqueue): Move up in the file. (propagate_subaccesses_across_link): Enqueue subtree whneve necessary instead of relying on the caller. testsuite/ gcc.dg/tree-ssa/pr80803.c: New test. gcc.dg/tree-ssa/pr81063.c: Likewise. From-SVN: r249154
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c100
1 files changed, 59 insertions, 41 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 05bc3d0..c9865c6 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2558,9 +2558,28 @@ create_artificial_child_access (struct access *parent, struct access *model,
}
-/* Propagate all subaccesses of RACC across an assignment link to LACC. Return
- true if any new subaccess was created. Additionally, if RACC is a scalar
- access but LACC is not, change the type of the latter, if possible. */
+/* Beginning with ACCESS, traverse its whole access subtree and mark all
+ sub-trees as written to. If any of them has not been marked so previously
+ and has assignment links leading from it, re-enqueue it. */
+
+static void
+subtree_mark_written_and_enqueue (struct access *access)
+{
+ if (access->grp_write)
+ return;
+ access->grp_write = true;
+ add_access_to_work_queue (access);
+
+ struct access *child;
+ for (child = access->first_child; child; child = child->next_sibling)
+ subtree_mark_written_and_enqueue (child);
+}
+
+/* Propagate subaccesses and grp_write flags of RACC across an assignment link
+ to LACC. Enqueue sub-accesses as necessary so that the write flag is
+ propagated transitively. Return true if anything changed. Additionally, if
+ RACC is a scalar access but LACC is not, change the type of the latter, if
+ possible. */
static bool
propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
@@ -2576,7 +2595,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
gcc_checking_assert (!comes_initialized_p (racc->base));
if (racc->grp_write)
{
- lacc->grp_write = true;
+ subtree_mark_written_and_enqueue (lacc);
ret = true;
}
}
@@ -2585,13 +2604,21 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
|| lacc->grp_unscalarizable_region
|| racc->grp_unscalarizable_region)
{
- ret |= !lacc->grp_write;
- lacc->grp_write = true;
+ if (!lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
return ret;
}
if (is_gimple_reg_type (racc->type))
{
+ if (!lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
if (!lacc->first_child && !racc->first_child)
{
tree t = lacc->base;
@@ -2616,21 +2643,15 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
struct access *new_acc = NULL;
HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
- if (rchild->grp_unscalarizable_region)
- {
- lacc->grp_write = true;
- continue;
- }
-
if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
&new_acc))
{
if (new_acc)
{
- if (!new_acc->grp_write
- && (lacc->grp_write || rchild->grp_write))
+ if (!new_acc->grp_write && rchild->grp_write)
{
- new_acc ->grp_write = true;
+ gcc_assert (!lacc->grp_write);
+ subtree_mark_written_and_enqueue (new_acc);
ret = true;
}
@@ -2640,7 +2661,23 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
ret |= propagate_subaccesses_across_link (new_acc, rchild);
}
else
- lacc->grp_write = true;
+ {
+ if (rchild->grp_write && !lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
+ }
+ continue;
+ }
+
+ if (rchild->grp_unscalarizable_region)
+ {
+ if (rchild->grp_write && !lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
continue;
}
@@ -2648,36 +2685,17 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
lacc->grp_write
|| rchild->grp_write);
- if (new_acc)
- {
- ret = true;
- if (racc->first_child)
- propagate_subaccesses_across_link (new_acc, rchild);
- }
+ gcc_checking_assert (new_acc);
+ if (racc->first_child)
+ propagate_subaccesses_across_link (new_acc, rchild);
+
+ add_access_to_work_queue (lacc);
+ ret = true;
}
return ret;
}
-/* Beginning with ACCESS, traverse its whole access subtree and mark all
- sub-trees as written to. If any of them has not been marked so previously
- and has assignment links leading from it, re-enqueue it. */
-
-static void
-subtree_mark_written_and_enqueue (struct access *access)
-{
- if (access->grp_write)
- return;
- access->grp_write = true;
- add_access_to_work_queue (access);
-
- struct access *child;
- for (child = access->first_child; child; child = child->next_sibling)
- subtree_mark_written_and_enqueue (child);
-}
-
-
-
/* Propagate all subaccesses across assignment links. */
static void