}
-/* 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)
gcc_checking_assert (!comes_initialized_p (racc->base));
if (racc->grp_write)
{
- lacc->grp_write = true;
+ subtree_mark_written_and_enqueue (lacc);
ret = true;
}
}
|| 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;
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;
}
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;
}
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