diff mbox series

[v2,4/16] middle-end: Add dissolve code for when SLP fails and non-SLP loop vectorization is to be tried.

Message ID 20200925142816.GA14929@arm.com
State New
Headers show
Series middle-end Add support for SLP vectorization of complex number instructions. | expand

Commit Message

Tamar Christina Sept. 25, 2020, 2:28 p.m. UTC
Hi All,

This adds the dissolve code to undo the patterns created by the pattern matcher
in case SLP is to be aborted.

As mentioned in the cover letter this has one issue in that the number of copies
can needed can change depending on whether TWO_OPERATORS is needed or not.

Because of this I don't analyze the original statement when it's replaced by a
pattern and attempt to correct it here by analyzing it after dissolve.

This however seems too late and I would need to change the unroll factor, which
seems a bit odd.  Any advice would be appreciated.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Thanks,
Tamar

gcc/ChangeLog:

	* tree-vect-loop.c (vect_dissolve_slp_only_patterns): New
	(vect_dissolve_slp_only_groups): Call vect_dissolve_slp_only_patterns.

--

Comments

Richard Biener Sept. 28, 2020, 12:55 p.m. UTC | #1
On Fri, 25 Sep 2020, Tamar Christina wrote:

> Hi All,
> 
> This adds the dissolve code to undo the patterns created by the pattern matcher
> in case SLP is to be aborted.
> 
> As mentioned in the cover letter this has one issue in that the number of copies
> can needed can change depending on whether TWO_OPERATORS is needed or not.
> 
> Because of this I don't analyze the original statement when it's replaced by a
> pattern and attempt to correct it here by analyzing it after dissolve.
> 
> This however seems too late and I would need to change the unroll factor, which
> seems a bit odd.  Any advice would be appreciated.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Ah, this is what you mean with the need to dissolve.  Yeah ...

@@ -2427,6 +2513,11 @@ again:
   /* Ensure that "ok" is false (with an opt_problem if dumping is 
enabled).  */
   gcc_assert (!ok);

+  /* Dissolve any SLP patterns created by the SLP pattern matcher.  */
+  opt_result dissolved = vect_dissolve_slp_only_patterns (loop_vinfo);
+  if (!dissolved)
+    return dissolved;
+
   /* Try again with SLP forced off but if we didn't do any SLP there is
      no point in re-trying.  */
   if (!slp)

I think this only belongs after

  if (dump_enabled_p ())
    dump_printf_loc (MSG_NOTE, vect_location,
                     "re-trying with SLP disabled\n");

  /* Roll back state appropriately.  No SLP this time.  */
  slp = false;

thus where everything else is "restored".  In fact I wonder if
it cannot be done as part of

  /* Reset SLP type to loop_vect on all stmts.  */
  for (i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; ++i)
    {
      basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i];
...

?  In particular

+       /* Now we have to re-analyze the statement since we skipped it in 
the
+          the initial analysis due to the differences in copies.  */
+       res = vect_analyze_stmt (loop_vinfo, related_stmt_info,
+                                &need_to_vectorize, NULL, NULL, 
&cost_vec);

looks unneeded since we're going to re-analyze all stmts anyway?

The thing is, there's no way to recover the original pattern stmt
in case your SLP pattern stmt was composed of "regular" pattern
stmts (the STMT_VINFO_RELATED_STMT simply gets replaced).  I
wonder if it would be easier to record the SLP pattern stmt
only in SLP_TREE_REPRESENTATIVE but _not_ in SLP_TREE_SCALAR_STMTS
(just leave those alone)?

Richard.


> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> 	* tree-vect-loop.c (vect_dissolve_slp_only_patterns): New
> 	(vect_dissolve_slp_only_groups): Call vect_dissolve_slp_only_patterns.
> 
>
Tamar Christina Nov. 3, 2020, 3:06 p.m. UTC | #2
Hi All,

Here's a respin of this patch with the requested changes.

Thanks,
Tamar

gcc/ChangeLog:

	* tree-vect-loop.c (vect_dissolve_slp_only_patterns): New
	(vect_dissolve_slp_only_groups): Call vect_dissolve_slp_only_patterns.

> -----Original Message-----
> From: Gcc-patches <gcc-patches-bounces@gcc.gnu.org> On Behalf Of Tamar
> Christina
> Sent: Friday, September 25, 2020 3:28 PM
> To: gcc-patches@gcc.gnu.org
> Cc: nd <nd@arm.com>; rguenther@suse.de; ook@ucw.cz
> Subject: [PATCH v2 4/16]middle-end: Add dissolve code for when SLP fails
> and non-SLP loop vectorization is to be tried.
> 
> Hi All,
> 
> This adds the dissolve code to undo the patterns created by the pattern
> matcher in case SLP is to be aborted.
> 
> As mentioned in the cover letter this has one issue in that the number of
> copies can needed can change depending on whether TWO_OPERATORS is
> needed or not.
> 
> Because of this I don't analyze the original statement when it's replaced by a
> pattern and attempt to correct it here by analyzing it after dissolve.
> 
> This however seems too late and I would need to change the unroll factor,
> which seems a bit odd.  Any advice would be appreciated.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> 	* tree-vect-loop.c (vect_dissolve_slp_only_patterns): New
> 	(vect_dissolve_slp_only_groups): Call
> vect_dissolve_slp_only_patterns.
> 
> --
diff mbox series

Patch

diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index b1a6e1508c7f00f5f369ec873f927f30d673059e..8231ad6452af6ff111911a7bfb6aab2257df9fc0 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -1956,6 +1956,92 @@  vect_get_datarefs_in_loop (loop_p loop, basic_block *bbs,
   return opt_result::success ();
 }
 
+/* For every SLP only pattern created by the pattern matched rooted in ROOT
+   restore the relevancy of the original statements over those of the pattern
+   and destroy the pattern relationship.  This restores the SLP tree to a state
+   where it can be used when SLP build is cancelled or re-tried.  */
+
+static opt_result
+vect_dissolve_slp_only_patterns (loop_vec_info loop_vinfo,
+				 hash_set<slp_tree> *visited, slp_tree root)
+{
+  if (!root || visited->contains (root))
+    return opt_result::success ();
+
+  unsigned int i;
+  slp_tree node;
+  opt_result res = opt_result::success ();
+  stmt_vec_info stmt_info;
+  stmt_vec_info related_stmt_info;
+  bool need_to_vectorize = false;
+  auto_vec<stmt_info_for_cost> cost_vec;
+
+  visited->add (root);
+
+  FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (root), i, stmt_info)
+    if (STMT_VINFO_SLP_VECT_ONLY (stmt_info)
+        && (related_stmt_info = STMT_VINFO_RELATED_STMT (stmt_info)) != NULL)
+      {
+	if (dump_enabled_p ())
+	  dump_printf_loc (MSG_NOTE, vect_location,
+			   "dissolving relevancy of %G over %G",
+			   STMT_VINFO_STMT (stmt_info),
+			   STMT_VINFO_STMT (related_stmt_info));
+	STMT_VINFO_RELEVANT (stmt_info) = vect_unused_in_scope;
+	STMT_VINFO_RELEVANT (related_stmt_info) = vect_used_in_scope;
+	STMT_VINFO_IN_PATTERN_P (related_stmt_info) = false;
+	STMT_SLP_TYPE (related_stmt_info) = hybrid;
+	/* Now we have to re-analyze the statement since we skipped it in the
+	   the initial analysis due to the differences in copies.  */
+	res = vect_analyze_stmt (loop_vinfo, related_stmt_info,
+				 &need_to_vectorize, NULL, NULL, &cost_vec);
+
+	if (!res)
+	  return res;
+      }
+
+  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (root), i, node)
+    {
+      res = vect_dissolve_slp_only_patterns (loop_vinfo, visited, node);
+      if (!res)
+	return res;
+    }
+
+  return res;
+}
+
+/* Lookup any SLP Only Pattern statements created by the SLP pattern matcher in
+   all slp_instances in LOOP_VINFO and undo the relevancy of statements such
+   that the original SLP tree before the pattern matching is used.  */
+
+static opt_result
+vect_dissolve_slp_only_patterns (loop_vec_info loop_vinfo)
+{
+
+  unsigned int i;
+  opt_result res = opt_result::success ();
+  hash_set<slp_tree> *visited = new hash_set<slp_tree> ();
+
+  DUMP_VECT_SCOPE ("vect_dissolve_slp_only_patterns");
+
+  /* Unmark any SLP only patterns as relevant and restore the STMT_INFO of the
+     related instruction.  */
+  slp_instance instance;
+  FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), i, instance)
+    {
+      res = vect_dissolve_slp_only_patterns (loop_vinfo, visited,
+					     SLP_INSTANCE_TREE (instance));
+      if (!res)
+	{
+	  delete visited;
+	  return res;
+	}
+    }
+
+  delete visited;
+  return res;
+}
+
 /* Look for SLP-only access groups and turn each individual access into its own
    group.  */
 static void
@@ -2427,6 +2513,11 @@  again:
   /* Ensure that "ok" is false (with an opt_problem if dumping is enabled).  */
   gcc_assert (!ok);
 
+  /* Dissolve any SLP patterns created by the SLP pattern matcher.  */
+  opt_result dissolved = vect_dissolve_slp_only_patterns (loop_vinfo);
+  if (!dissolved)
+    return dissolved;
+
   /* Try again with SLP forced off but if we didn't do any SLP there is
      no point in re-trying.  */
   if (!slp)