public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Martin Liska <marxin@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc(refs/users/marxin/heads/pgo-reproducibility-test)] SRA: Also propagate accesses from LHS to RHS [PR92706]
Date: Thu, 30 Jan 2020 08:54:00 -0000	[thread overview]
Message-ID: <20200130085423.63690.qmail@sourceware.org> (raw)

https://gcc.gnu.org/g:6693911f069b1ada7c04aa1d00c3653ba694958a

commit 6693911f069b1ada7c04aa1d00c3653ba694958a
Author: Martin Jambor <mjambor@suse.cz>
Date:   Wed Jan 29 13:13:13 2020 +0100

    SRA: Also propagate accesses from LHS to RHS [PR92706]
    
    2020-01-29  Martin Jambor  <mjambor@suse.cz>
    
    	PR tree-optimization/92706
    	* tree-sra.c (struct access): Fields first_link, last_link,
    	next_queued and grp_queued renamed to first_rhs_link, last_rhs_link,
    	next_rhs_queued and grp_rhs_queued respectively, new fields
    	first_lhs_link, last_lhs_link, next_lhs_queued and grp_lhs_queued.
    	(struct assign_link): Field next renamed to next_rhs, new field
    	next_lhs.  Updated comment.
    	(work_queue_head): Renamed to rhs_work_queue_head.
    	(lhs_work_queue_head): New variable.
    	(add_link_to_lhs): New function.
    	(relink_to_new_repr): Also relink LHS lists.
    	(add_access_to_work_queue): Renamed to add_access_to_rhs_work_queue.
    	(add_access_to_lhs_work_queue): New function.
    	(pop_access_from_work_queue): Renamed to
    	pop_access_from_rhs_work_queue.
    	(pop_access_from_lhs_work_queue): New function.
    	(build_accesses_from_assign): Also add links to LHS lists and to LHS
    	work_queue.
    	(child_would_conflict_in_lacc): Renamed to
    	child_would_conflict_in_acc.  Adjusted parameter names.
    	(create_artificial_child_access): New parameter set_grp_read, use it.
    	(subtree_mark_written_and_enqueue): Renamed to
    	subtree_mark_written_and_rhs_enqueue.
    	(propagate_subaccesses_across_link): Renamed to
    	propagate_subaccesses_from_rhs.
    	(propagate_subaccesses_from_lhs): New function.
    	(propagate_all_subaccesses): Also propagate subaccesses from LHSs to
    	RHSs.
    
    	testsuite/
    	* gcc.dg/tree-ssa/pr92706-1.c: New test.

Diff:
---
 gcc/ChangeLog                             |  31 +++
 gcc/testsuite/ChangeLog                   |   5 +
 gcc/testsuite/gcc.dg/tree-ssa/pr92706-1.c |  17 ++
 gcc/tree-sra.c                            | 306 ++++++++++++++++++++++--------
 4 files changed, 284 insertions(+), 75 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61da54d..f8fe5ba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,37 @@
 2020-01-29  Martin Jambor  <mjambor@suse.cz>
 
 	PR tree-optimization/92706
+	* tree-sra.c (struct access): Fields first_link, last_link,
+	next_queued and grp_queued renamed to first_rhs_link, last_rhs_link,
+	next_rhs_queued and grp_rhs_queued respectively, new fields
+	first_lhs_link, last_lhs_link, next_lhs_queued and grp_lhs_queued.
+	(struct assign_link): Field next renamed to next_rhs, new field
+	next_lhs.  Updated comment.
+	(work_queue_head): Renamed to rhs_work_queue_head.
+	(lhs_work_queue_head): New variable.
+	(add_link_to_lhs): New function.
+	(relink_to_new_repr): Also relink LHS lists.
+	(add_access_to_work_queue): Renamed to add_access_to_rhs_work_queue.
+	(add_access_to_lhs_work_queue): New function.
+	(pop_access_from_work_queue): Renamed to
+	pop_access_from_rhs_work_queue.
+	(pop_access_from_lhs_work_queue): New function.
+	(build_accesses_from_assign): Also add links to LHS lists and to LHS
+	work_queue.
+	(child_would_conflict_in_lacc): Renamed to
+	child_would_conflict_in_acc.  Adjusted parameter names.
+	(create_artificial_child_access): New parameter set_grp_read, use it.
+	(subtree_mark_written_and_enqueue): Renamed to
+	subtree_mark_written_and_rhs_enqueue.
+	(propagate_subaccesses_across_link): Renamed to
+	propagate_subaccesses_from_rhs.
+	(propagate_subaccesses_from_lhs): New function.
+	(propagate_all_subaccesses): Also propagate subaccesses from LHSs to
+	RHSs.
+
+2020-01-29  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/92706
 	* tree-sra.c (struct access): Adjust comment of
 	grp_total_scalarization.
 	(find_access_in_subtree): Look for single children spanning an entire
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3875820..33b5a6a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,11 @@
 2020-01-29  Martin Jambor  <mjambor@suse.cz>
 
 	PR tree-optimization/92706
+	* gcc.dg/tree-ssa/pr92706-1.c: New test.
+
+2020-01-29  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/92706
 	* gcc.dg/tree-ssa/pr92706-2.c: New test.
 	* gcc.dg/guality/pr59776.c: Xfail tests for s2.g.
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr92706-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92706-1.c
new file mode 100644
index 0000000..c36d103
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92706-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-esra-details" } */
+
+struct S { int i[4]; } __attribute__((aligned(128)));
+typedef __int128_t my_int128 __attribute__((may_alias));
+__int128_t load (void *p)
+{
+  struct S v;
+  __builtin_memcpy (&v, p, sizeof (struct S));
+  struct S u;
+  u = v;
+  struct S w;
+  w = u;
+  return *(my_int128 *)&w;
+}
+
+/* { dg-final { scan-tree-dump-not "Created a replacement for u offset: \[^0\]" "esra" } } */
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 2b08498..ea8594d 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -167,11 +167,15 @@ struct access
   struct access *next_sibling;
 
   /* Pointers to the first and last element in the linked list of assign
-     links.  */
-  struct assign_link *first_link, *last_link;
+     links for propagation from LHS to RHS.  */
+  struct assign_link *first_rhs_link, *last_rhs_link;
 
-  /* Pointer to the next access in the work queue.  */
-  struct access *next_queued;
+  /* Pointers to the first and last element in the linked list of assign
+     links for propagation from LHS to RHS.  */
+  struct assign_link *first_lhs_link, *last_lhs_link;
+
+  /* Pointer to the next access in the work queues.  */
+  struct access *next_rhs_queued, *next_lhs_queued;
 
   /* Replacement variable for this access "region."  Never to be accessed
      directly, always only by the means of get_access_replacement() and only
@@ -184,8 +188,11 @@ struct access
   /* Is this particular access write access? */
   unsigned write : 1;
 
-  /* Is this access currently in the work queue?  */
-  unsigned grp_queued : 1;
+  /* Is this access currently in the rhs work queue?  */
+  unsigned grp_rhs_queued : 1;
+
+  /* Is this access currently in the lhs work queue?  */
+  unsigned grp_lhs_queued : 1;
 
   /* Does this group contain a write access?  This flag is propagated down the
      access tree.  */
@@ -262,12 +269,14 @@ typedef struct access *access_p;
 static object_allocator<struct access> access_pool ("SRA accesses");
 
 /* A structure linking lhs and rhs accesses from an aggregate assignment.  They
-   are used to propagate subaccesses from rhs to lhs as long as they don't
-   conflict with what is already there.  */
+   are used to propagate subaccesses from rhs to lhs and vice versa as long as
+   they don't conflict with what is already there.  In the RHS->LHS direction,
+   we also propagate grp_write flag to lazily mark that the access contains any
+   meaningful data.  */
 struct assign_link
 {
   struct access *lacc, *racc;
-  struct assign_link *next;
+  struct assign_link *next_rhs, *next_lhs;
 };
 
 /* Alloc pool for allocating assign link structures.  */
@@ -327,7 +336,7 @@ static struct obstack name_obstack;
 
 /* Head of a linked list of accesses that need to have its subaccesses
    propagated to their assignment counterparts. */
-static struct access *work_queue_head;
+static struct access *rhs_work_queue_head, *lhs_work_queue_head;
 
 /* Dump contents of ACCESS to file F in a human friendly way.  If GRP is true,
    representative fields are dumped, otherwise those which only describe the
@@ -534,79 +543,155 @@ get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
 }
 
 /* Add LINK to the linked list of assign links of RACC.  */
+
 static void
 add_link_to_rhs (struct access *racc, struct assign_link *link)
 {
   gcc_assert (link->racc == racc);
 
-  if (!racc->first_link)
+  if (!racc->first_rhs_link)
     {
-      gcc_assert (!racc->last_link);
-      racc->first_link = link;
+      gcc_assert (!racc->last_rhs_link);
+      racc->first_rhs_link = link;
     }
   else
-    racc->last_link->next = link;
+    racc->last_rhs_link->next_rhs = link;
 
-  racc->last_link = link;
-  link->next = NULL;
+  racc->last_rhs_link = link;
+  link->next_rhs = NULL;
 }
 
-/* Move all link structures in their linked list in OLD_RACC to the linked list
-   in NEW_RACC.  */
+/* Add LINK to the linked list of lhs assign links of LACC.  */
+
 static void
-relink_to_new_repr (struct access *new_racc, struct access *old_racc)
+add_link_to_lhs (struct access *lacc, struct assign_link *link)
 {
-  if (!old_racc->first_link)
+  gcc_assert (link->lacc == lacc);
+
+  if (!lacc->first_lhs_link)
     {
-      gcc_assert (!old_racc->last_link);
-      return;
+      gcc_assert (!lacc->last_lhs_link);
+      lacc->first_lhs_link = link;
     }
+  else
+    lacc->last_lhs_link->next_lhs = link;
+
+  lacc->last_lhs_link = link;
+  link->next_lhs = NULL;
+}
 
-  if (new_racc->first_link)
+/* Move all link structures in their linked list in OLD_ACC to the linked list
+   in NEW_ACC.  */
+static void
+relink_to_new_repr (struct access *new_acc, struct access *old_acc)
+{
+  if (old_acc->first_rhs_link)
     {
-      gcc_assert (!new_racc->last_link->next);
-      gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
 
-      new_racc->last_link->next = old_racc->first_link;
-      new_racc->last_link = old_racc->last_link;
+      if (new_acc->first_rhs_link)
+	{
+	  gcc_assert (!new_acc->last_rhs_link->next_rhs);
+	  gcc_assert (!old_acc->last_rhs_link
+		      || !old_acc->last_rhs_link->next_rhs);
+
+	  new_acc->last_rhs_link->next_rhs = old_acc->first_rhs_link;
+	  new_acc->last_rhs_link = old_acc->last_rhs_link;
+	}
+      else
+	{
+	  gcc_assert (!new_acc->last_rhs_link);
+
+	  new_acc->first_rhs_link = old_acc->first_rhs_link;
+	  new_acc->last_rhs_link = old_acc->last_rhs_link;
+	}
+      old_acc->first_rhs_link = old_acc->last_rhs_link = NULL;
     }
   else
+    gcc_assert (!old_acc->last_rhs_link);
+
+  if (old_acc->first_lhs_link)
     {
-      gcc_assert (!new_racc->last_link);
 
-      new_racc->first_link = old_racc->first_link;
-      new_racc->last_link = old_racc->last_link;
+      if (new_acc->first_lhs_link)
+	{
+	  gcc_assert (!new_acc->last_lhs_link->next_lhs);
+	  gcc_assert (!old_acc->last_lhs_link
+		      || !old_acc->last_lhs_link->next_lhs);
+
+	  new_acc->last_lhs_link->next_lhs = old_acc->first_lhs_link;
+	  new_acc->last_lhs_link = old_acc->last_lhs_link;
+	}
+      else
+	{
+	  gcc_assert (!new_acc->last_lhs_link);
+
+	  new_acc->first_lhs_link = old_acc->first_lhs_link;
+	  new_acc->last_lhs_link = old_acc->last_lhs_link;
+	}
+      old_acc->first_lhs_link = old_acc->last_lhs_link = NULL;
     }
-  old_racc->first_link = old_racc->last_link = NULL;
+  else
+    gcc_assert (!old_acc->last_lhs_link);
+
 }
 
-/* Add ACCESS to the work queue (which is actually a stack).  */
+/* Add ACCESS to the work to queue for propagation of subaccesses from RHS to
+   LHS (which is actually a stack).  */
 
 static void
-add_access_to_work_queue (struct access *access)
+add_access_to_rhs_work_queue (struct access *access)
 {
-  if (access->first_link && !access->grp_queued)
+  if (access->first_rhs_link && !access->grp_rhs_queued)
     {
-      gcc_assert (!access->next_queued);
-      access->next_queued = work_queue_head;
-      access->grp_queued = 1;
-      work_queue_head = access;
+      gcc_assert (!access->next_rhs_queued);
+      access->next_rhs_queued = rhs_work_queue_head;
+      access->grp_rhs_queued = 1;
+      rhs_work_queue_head = access;
     }
 }
 
-/* Pop an access from the work queue, and return it, assuming there is one.  */
+/* Add ACCESS to the work to queue for propagation of subaccesses from LHS to
+   RHS (which is actually a stack).  */
+
+static void
+add_access_to_lhs_work_queue (struct access *access)
+{
+  if (access->first_lhs_link && !access->grp_lhs_queued)
+    {
+      gcc_assert (!access->next_lhs_queued);
+      access->next_lhs_queued = lhs_work_queue_head;
+      access->grp_lhs_queued = 1;
+      lhs_work_queue_head = access;
+    }
+}
+
+/* Pop an access from the work queue for propagating from RHS to LHS, and
+   return it, assuming there is one.  */
 
 static struct access *
-pop_access_from_work_queue (void)
+pop_access_from_rhs_work_queue (void)
 {
-  struct access *access = work_queue_head;
+  struct access *access = rhs_work_queue_head;
 
-  work_queue_head = access->next_queued;
-  access->next_queued = NULL;
-  access->grp_queued = 0;
+  rhs_work_queue_head = access->next_rhs_queued;
+  access->next_rhs_queued = NULL;
+  access->grp_rhs_queued = 0;
   return access;
 }
 
+/* Pop an access from the work queue for propagating from LHS to RHS, and
+   return it, assuming there is one.  */
+
+static struct access *
+pop_access_from_lhs_work_queue (void)
+{
+  struct access *access = lhs_work_queue_head;
+
+  lhs_work_queue_head = access->next_lhs_queued;
+  access->next_lhs_queued = NULL;
+  access->grp_lhs_queued = 0;
+  return access;
+}
 
 /* Allocate necessary structures.  */
 
@@ -1203,7 +1288,9 @@ build_accesses_from_assign (gimple *stmt)
       link->lacc = lacc;
       link->racc = racc;
       add_link_to_rhs (racc, link);
-      add_access_to_work_queue (racc);
+      add_link_to_lhs (lacc, link);
+      add_access_to_rhs_work_queue (racc);
+      add_access_to_lhs_work_queue (lacc);
 
       /* Let's delay marking the areas as written until propagation of accesses
 	 across link, unless the nature of rhs tells us that its data comes
@@ -2492,17 +2579,17 @@ analyze_access_trees (struct access *access)
   return ret;
 }
 
-/* Return true iff a potential new child of LACC at offset OFFSET and with size
+/* Return true iff a potential new child of ACC at offset OFFSET and with size
    SIZE would conflict with an already existing one.  If exactly such a child
-   already exists in LACC, store a pointer to it in EXACT_MATCH.  */
+   already exists in ACC, store a pointer to it in EXACT_MATCH.  */
 
 static bool
-child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
+child_would_conflict_in_acc (struct access *acc, HOST_WIDE_INT norm_offset,
 			      HOST_WIDE_INT size, struct access **exact_match)
 {
   struct access *child;
 
-  for (child = lacc->first_child; child; child = child->next_sibling)
+  for (child = acc->first_child; child; child = child->next_sibling)
     {
       if (child->offset == norm_offset && child->size == size)
 	{
@@ -2528,7 +2615,7 @@ child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
 static struct access *
 create_artificial_child_access (struct access *parent, struct access *model,
 				HOST_WIDE_INT new_offset,
-				bool set_grp_write)
+				bool set_grp_read, bool set_grp_write)
 {
   struct access **child;
   tree expr = parent->base;
@@ -2551,8 +2638,8 @@ create_artificial_child_access (struct access *parent, struct access *model,
   access->size = model->size;
   access->type = model->type;
   access->parent = parent;
+  access->grp_read = set_grp_read;
   access->grp_write = set_grp_write;
-  access->grp_read = false;
   access->reverse = model->reverse;
 
   child = &parent->first_child;
@@ -2571,16 +2658,16 @@ create_artificial_child_access (struct access *parent, struct access *model,
    and has assignment links leading from it, re-enqueue it.  */
 
 static void
-subtree_mark_written_and_enqueue (struct access *access)
+subtree_mark_written_and_rhs_enqueue (struct access *access)
 {
   if (access->grp_write)
     return;
   access->grp_write = true;
-  add_access_to_work_queue (access);
+  add_access_to_rhs_work_queue (access);
 
   struct access *child;
   for (child = access->first_child; child; child = child->next_sibling)
-    subtree_mark_written_and_enqueue (child);
+    subtree_mark_written_and_rhs_enqueue (child);
 }
 
 /* Propagate subaccesses and grp_write flags of RACC across an assignment link
@@ -2590,7 +2677,7 @@ subtree_mark_written_and_enqueue (struct access *access)
    possible.  */
 
 static bool
-propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
+propagate_subaccesses_from_rhs (struct access *lacc, struct access *racc)
 {
   struct access *rchild;
   HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
@@ -2603,7 +2690,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
       gcc_checking_assert (!comes_initialized_p (racc->base));
       if (racc->grp_write)
 	{
-	  subtree_mark_written_and_enqueue (lacc);
+	  subtree_mark_written_and_rhs_enqueue (lacc);
 	  ret = true;
 	}
     }
@@ -2615,7 +2702,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
       if (!lacc->grp_write)
 	{
 	  ret = true;
-	  subtree_mark_written_and_enqueue (lacc);
+	  subtree_mark_written_and_rhs_enqueue (lacc);
 	}
       return ret;
     }
@@ -2625,7 +2712,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
       if (!lacc->grp_write)
 	{
 	  ret = true;
-	  subtree_mark_written_and_enqueue (lacc);
+	  subtree_mark_written_and_rhs_enqueue (lacc);
 	}
       if (!lacc->first_child && !racc->first_child)
 	{
@@ -2655,7 +2742,7 @@ 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 (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
+      if (child_would_conflict_in_acc (lacc, norm_offset, rchild->size,
 					&new_acc))
 	{
 	  if (new_acc)
@@ -2663,17 +2750,17 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
 	      if (!new_acc->grp_write && rchild->grp_write)
 		{
 		  gcc_assert (!lacc->grp_write);
-		  subtree_mark_written_and_enqueue (new_acc);
+		  subtree_mark_written_and_rhs_enqueue (new_acc);
 		  ret = true;
 		}
 
 	      rchild->grp_hint = 1;
 	      new_acc->grp_hint |= new_acc->grp_read;
 	      if (rchild->first_child
-		  && propagate_subaccesses_across_link (new_acc, rchild))
+		  && propagate_subaccesses_from_rhs (new_acc, rchild))
 		{
 		  ret = 1;
-		  add_access_to_work_queue (new_acc);
+		  add_access_to_rhs_work_queue (new_acc);
 		}
 	    }
 	  else
@@ -2681,7 +2768,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
 	      if (!lacc->grp_write)
 		{
 		  ret = true;
-		  subtree_mark_written_and_enqueue (lacc);
+		  subtree_mark_written_and_rhs_enqueue (lacc);
 		}
 	    }
 	  continue;
@@ -2692,41 +2779,85 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
 	  if (rchild->grp_write && !lacc->grp_write)
 	    {
 	      ret = true;
-	      subtree_mark_written_and_enqueue (lacc);
+	      subtree_mark_written_and_rhs_enqueue (lacc);
 	    }
 	  continue;
 	}
 
       rchild->grp_hint = 1;
       new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
-						lacc->grp_write
-						|| rchild->grp_write);
+						false, (lacc->grp_write
+							|| rchild->grp_write));
       gcc_checking_assert (new_acc);
       if (racc->first_child)
-	propagate_subaccesses_across_link (new_acc, rchild);
+	propagate_subaccesses_from_rhs (new_acc, rchild);
 
-      add_access_to_work_queue (lacc);
+      add_access_to_rhs_work_queue (lacc);
       ret = true;
     }
 
   return ret;
 }
 
+/* Propagate subaccesses of LACC across an assignment link to RACC if they
+   should inhibit total scalarization of the corresponding area.  No flags are
+   being propagated in the process.  Return true if anything changed.  */
+
+static bool
+propagate_subaccesses_from_lhs (struct access *lacc, struct access *racc)
+{
+  if (is_gimple_reg_type (racc->type)
+      || lacc->grp_unscalarizable_region
+      || racc->grp_unscalarizable_region)
+    return false;
+
+  /* TODO: Do we want set some new racc flag to stop potential total
+     scalarization if lacc is a scalar access (and none fo the two have
+     children)?  */
+
+  bool ret = false;
+  HOST_WIDE_INT norm_delta = racc->offset - lacc->offset;
+  for (struct access *lchild = lacc->first_child;
+       lchild;
+       lchild = lchild->next_sibling)
+    {
+      struct access *matching_acc = NULL;
+      HOST_WIDE_INT norm_offset = lchild->offset + norm_delta;
+
+      if (lchild->grp_unscalarizable_region
+	  || child_would_conflict_in_acc (racc, norm_offset, lchild->size,
+					  &matching_acc))
+	{
+	  if (matching_acc
+	      && propagate_subaccesses_from_lhs (lchild, matching_acc))
+	    add_access_to_lhs_work_queue (matching_acc);
+	  continue;
+	}
+
+      struct access *new_acc
+	=  create_artificial_child_access (racc, lchild, norm_offset,
+					   true, false);
+      propagate_subaccesses_from_lhs (lchild, new_acc);
+      ret = true;
+    }
+  return ret;
+}
+
 /* Propagate all subaccesses across assignment links.  */
 
 static void
 propagate_all_subaccesses (void)
 {
-  while (work_queue_head)
+  while (rhs_work_queue_head)
     {
-      struct access *racc = pop_access_from_work_queue ();
+      struct access *racc = pop_access_from_rhs_work_queue ();
       struct assign_link *link;
 
       if (racc->group_representative)
 	racc= racc->group_representative;
-      gcc_assert (racc->first_link);
+      gcc_assert (racc->first_rhs_link);
 
-      for (link = racc->first_link; link; link = link->next)
+      for (link = racc->first_rhs_link; link; link = link->next_rhs)
 	{
 	  struct access *lacc = link->lacc;
 
@@ -2739,22 +2870,47 @@ propagate_all_subaccesses (void)
 	    {
 	      if (!lacc->grp_write)
 		{
-		  subtree_mark_written_and_enqueue (lacc);
+		  subtree_mark_written_and_rhs_enqueue (lacc);
 		  reque_parents = true;
 		}
 	    }
-	  else if (propagate_subaccesses_across_link (lacc, racc))
+	  else if (propagate_subaccesses_from_rhs (lacc, racc))
 	    reque_parents = true;
 
 	  if (reque_parents)
 	    do
 	      {
-		add_access_to_work_queue (lacc);
+		add_access_to_rhs_work_queue (lacc);
 		lacc = lacc->parent;
 	      }
 	    while (lacc);
 	}
     }
+
+  while (lhs_work_queue_head)
+    {
+      struct access *lacc = pop_access_from_lhs_work_queue ();
+      struct assign_link *link;
+
+      if (lacc->group_representative)
+	lacc = lacc->group_representative;
+      gcc_assert (lacc->first_lhs_link);
+
+      if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
+	continue;
+
+      for (link = lacc->first_lhs_link; link; link = link->next_lhs)
+	{
+	  struct access *racc = link->racc;
+
+	  if (racc->group_representative)
+	    racc = racc->group_representative;
+	  if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
+	    continue;
+	  if (propagate_subaccesses_from_lhs (lacc, racc))
+	    add_access_to_lhs_work_queue (racc);
+	}
+    }
 }
 
 /* Return true if the forest beginning with ROOT does not contain


                 reply	other threads:[~2020-01-30  8:54 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200130085423.63690.qmail@sourceware.org \
    --to=marxin@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).