From d1d9937353ff54e9560ed71f562b57b9a15e65a9 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 5 Jul 2018 15:55:59 -0400
Subject: [PATCH 43/58] FIXME: generalize opt_result to cover
 opt_loop_vec_info, wiring it up in place of the_vect_problem

---
 gcc/opt-problem.h     | 44 ++++++++++++++++++++++++++++++--------------
 gcc/tree-vect-loop.c  | 13 +++++++------
 gcc/tree-vect-stmts.c | 16 ++++++++++++++--
 gcc/tree-vectorizer.c | 49 +++++++++----------------------------------------
 gcc/tree-vectorizer.h | 45 ++++++++++++++++++++++++++++++++-------------
 5 files changed, 92 insertions(+), 75 deletions(-)

diff --git a/gcc/opt-problem.h b/gcc/opt-problem.h
index 0f0ea0c..3417cd7 100644
--- a/gcc/opt-problem.h
+++ b/gcc/opt-problem.h
@@ -59,22 +59,42 @@ class GTY(()) opt_problem
 
 /* FIXME.  */
 
-class opt_result
+template <typename T>
+class opt_wrapper
 {
  public:
-  // No public ctor
+  typedef T wrapped_t;
 
-#if 1
-  /* FIXME: during transition, allow construction from bool.
-     We want to eliminate this, as it doesn't capture the reason.  */
+  operator wrapped_t () const { return m_result; }
+
+  /* No public ctor.  */
+
+  opt_problem *get_problem () const { return m_problem; }
+
+ protected:
+  opt_wrapper (wrapped_t result, opt_problem *problem)
+  : m_result (result), m_problem (problem)
+  {}
+
+  wrapped_t m_result;
+  opt_problem *m_problem;
+};
+
+/* FIXME.  */
+
+class opt_result : public opt_wrapper <bool>
+{
+ public:
+  /* Deprecated ctor.  During transition, allow construction from bool.
+     We want to eliminate this, as it doesn't capture the reason for
+     failures.  */
   opt_result (bool result,
 	      const dump_impl_location_t &impl_location
 		= dump_impl_location_t ())
-    : m_result (result),
-      m_problem (new opt_problem ("UNKNOWN", NULL, impl_location))
+    : opt_wrapper <bool> (result,
+			  new opt_problem ("UNKNOWN", NULL, impl_location))
   {
   }
-#endif
 
   // FIXME: what about discarding the opt_problem in the dtor?
   // it feels more like a shared_ptr
@@ -100,15 +120,11 @@ class opt_result
     return failure (gmsgid, stmt, impl_location); // FIXME: for now
   }
 
-  operator bool () const { return m_result; }
-
  private:
-  opt_result (bool result, opt_problem *problem)
-  : m_result (result), m_problem (problem)
+  opt_result (wrapped_t result, opt_problem *problem)
+  : opt_wrapper (result, problem)
   {}
 
-  bool m_result;
-  opt_problem *m_problem;
 };
 
 #endif /* #ifndef GCC_OPT_PROBLEM_H */
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 6f364b9..23caa86 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2301,11 +2301,10 @@ again:
    for it.  The different analyses will record information in the
    loop_vec_info struct.  If ORIG_LOOP_VINFO is not NULL epilogue must
    be vectorized.  */
-loop_vec_info
+opt_loop_vec_info
 vect_analyze_loop (struct loop *loop, loop_vec_info orig_loop_vinfo,
 		   vec_info_shared *shared)
 {
-  loop_vec_info loop_vinfo;
   auto_vector_sizes vector_sizes;
 
   /* Autodetect first vector size we try.  */
@@ -2322,7 +2321,8 @@ vect_analyze_loop (struct loop *loop, loop_vec_info orig_loop_vinfo,
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_NOTE, vect_location,
 			 "outer-loop already vectorized.\n");
-      return NULL;
+      return opt_loop_vec_info (NULL,
+				"outer-loop already vectorized");
     }
 
   if (!find_loop_nest (loop, &shared->loop_nest))
@@ -2340,13 +2340,14 @@ vect_analyze_loop (struct loop *loop, loop_vec_info orig_loop_vinfo,
   while (1)
     {
       /* Check the CFG characteristics of the loop (nesting, entry/exit).  */
-      loop_vinfo = vect_analyze_loop_form (loop, shared);
+      opt_loop_vec_info loop_vinfo
+	= vect_analyze_loop_form (loop, shared);
       if (!loop_vinfo)
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			     "bad loop form.\n");
-	  return NULL;
+	  return loop_vinfo;
 	}
 
       bool fatal = false;
@@ -2377,7 +2378,7 @@ vect_analyze_loop (struct loop *loop, loop_vec_info orig_loop_vinfo,
       if (fatal
 	  || next_size == vector_sizes.length ()
 	  || known_eq (current_vector_size, 0U))
-	return NULL;
+	return opt_loop_vec_info (NULL, res);
 
       /* Try the next biggest vector size.  */
       current_vector_size = vector_sizes[next_size++];
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 368aa6a..96c48cf 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -9529,7 +9529,14 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node,
 
   if (!ok)
     {
-      push_vect_problem ("not vectorized: relevant stmt not supported", stmt);
+      if (dump_enabled_p ())
+        {
+          dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                           "not vectorized: relevant stmt not ");
+          dump_printf (MSG_MISSED_OPTIMIZATION, "supported: ");
+          dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+        }
+
       return false;
     }
 
@@ -9539,7 +9546,12 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node,
       && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type
       && !can_vectorize_live_stmts (stmt, NULL, node, NULL, cost_vec))
     {
-      push_vect_problem ("not vectorized: live stmt not supported", stmt);
+      if (dump_enabled_p ())
+        {
+          dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                           "not vectorized: live stmt not supported: ");
+          dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+        }
 
        return false;
     }
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index cb53d3b..d733674 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -707,24 +707,17 @@ try_vectorize_loop_1 (hash_table<simduid_to_vf> *&simduid_to_vf_htab,
 		 LOCATION_FILE (vect_location.get_location_t ()),
 		 LOCATION_LINE (vect_location.get_location_t ()));
 
-  loop_vec_info loop_vinfo = vect_analyze_loop (loop, orig_loop_vinfo, &shared);
+  opt_loop_vec_info loop_vinfo = vect_analyze_loop (loop, orig_loop_vinfo, &shared);
   loop->aux = loop_vinfo;
 
-  if (the_vect_problem)
-    {
-#if 1
-      opt_report report;
-      if (report.remark (vect_location, 0,
-			"couldn't vectorize loop"))
-	the_vect_problem->report_reason (report);
-#else
-      if (remark (vect_location.get_location_t (), 0,
-		  "couldn't vectorize loop"))
-	the_vect_problem->report_reason ();
-#endif
-      delete the_vect_problem;
-      the_vect_problem = NULL;
-    }
+  if (!loop_vinfo)
+    if (loop_vinfo.get_problem ())
+      {	
+	opt_report report;
+	if (report.remark (vect_location, 0,
+			   "couldn't vectorize loop"))
+	  loop_vinfo.get_problem ()->report_reason (report);
+      }
 
   if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
     {
@@ -1338,27 +1331,3 @@ make_pass_ipa_increase_alignment (gcc::context *ctxt)
 {
   return new pass_ipa_increase_alignment (ctxt);
 }
-
-/* Singleton instance.  */
-
-opt_problem *the_vect_problem;
-
-/* If dumps are enabled emit a "not vectorized" message with the given
-   text relating to STMT, and record a opt_problem instance for later
-   use.  */
-// FIXME: maybe a stack of these?  or not
-
-void
-push_vect_problem (const char *text, gimple *stmt,
-		   const dump_impl_location_t &impl_location)
-{
-  if (!dump_enabled_p ())
-    return;
-
-  the_vect_problem = new opt_problem (text, stmt, impl_location);
-
-  dump_printf_loc (MSG_MISSED_OPTIMIZATION,
-		   dump_location_t (vect_location, impl_location),
-		   "%s", text);
-  dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
-}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 1a28657..aeb4594 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -595,6 +595,35 @@ typedef struct _loop_vec_info : public vec_info {
 #define LOOP_VINFO_ORIG_MAX_VECT_FACTOR(L) \
   (LOOP_VINFO_MAX_VECT_FACTOR (LOOP_VINFO_ORIG_LOOP_INFO (L)))
 
+/* FIXME.  */
+
+class opt_loop_vec_info : public opt_wrapper <loop_vec_info>
+{
+ public:
+#if 1
+  /* Deprecated ctor.  During transition, allow construction from ptr.
+     We want to eliminate this, as it doesn't capture the reason for
+     failures.  */
+  opt_loop_vec_info (loop_vec_info ptr,
+		     const dump_impl_location_t &impl_location
+		       = dump_impl_location_t ())
+    : opt_wrapper <loop_vec_info> (ptr,
+				   new opt_problem ("UNKNOWN", NULL,
+						    impl_location))
+  {
+  }
+#endif
+
+  template <typename T>
+  opt_loop_vec_info (loop_vec_info ptr, opt_wrapper <T> other)
+  : opt_wrapper <loop_vec_info> (ptr,
+				 other.get_problem ())
+  {
+  }
+
+  loop_vec_info operator-> () const { return m_result; }
+};
+
 static inline loop_vec_info
 loop_vec_info_for_loop (struct loop *loop)
 {
@@ -1601,8 +1630,9 @@ extern gimple *vect_force_simple_reduction (loop_vec_info, gimple *,
 extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree,
 				  enum tree_code);
 /* Drive for loop analysis stage.  */
-extern loop_vec_info vect_analyze_loop (struct loop *, loop_vec_info,
-					vec_info_shared *);
+extern opt_loop_vec_info vect_analyze_loop (struct loop *,
+					    loop_vec_info,
+					    vec_info_shared *);
 extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL);
 extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *,
 					 tree *, bool);
@@ -1665,15 +1695,4 @@ unsigned vectorize_loops (void);
 bool vect_stmt_in_region_p (vec_info *, gimple *);
 void vect_free_loop_info_assumptions (struct loop *);
 
-/* Singleton instance.  */
-class opt_problem;
-extern opt_problem *the_vect_problem;
-
-// FIXME: move the dump_impl_location_t inside the wrapper.
-
-extern void push_vect_problem (const char *text, gimple *stmt,
-			       const dump_impl_location_t &impl_location
-			         = dump_impl_location_t ());
-
-
 #endif  /* GCC_TREE_VECTORIZER_H  */
-- 
1.8.5.3

