From 81fbee2b63320e51c4c5f30842d9f39455430094 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 6 Jul 2018 09:56:54 -0400
Subject: [PATCH 49/58] FIXME: WIP on removing ctor from bool

---
 gcc/tree-data-ref.c       | 21 ++++++-----
 gcc/tree-data-ref.h       |  2 +-
 gcc/tree-vect-data-refs.c | 90 +++++++++++++++++++++++++++++-----------------
 gcc/tree-vect-loop.c      | 91 ++++++++++++++++++++++++++---------------------
 gcc/tree-vect-stmts.c     | 71 ++++++++++++++++++++++--------------
 gcc/tree-vectorizer.h     |  3 +-
 6 files changed, 168 insertions(+), 110 deletions(-)

diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 5859a50..a6319f83 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -898,7 +898,9 @@ dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
         {
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    fprintf (dump_file, "failed: evolution of base is not affine.\n");
-	  return false;
+	  // FIXME: should this propagate an opt_problem from simple_iv?
+	  return opt_result::failure ("evolution of base is not affine",
+				      NULL);
         }
     }
   else
@@ -924,7 +926,9 @@ dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
         {
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    fprintf (dump_file, "failed: evolution of offset is not affine.\n");
-	  return false;
+	  // FIXME: should this propagate an opt_problem from simple_iv?
+	  return opt_result::failure ("evolution of offset is not affine",
+				      NULL);
         }
     }
 
@@ -1318,7 +1322,7 @@ data_ref_compare_tree (tree t1, tree t2)
 /* Return TRUE it's possible to resolve data dependence DDR by runtime alias
    check.  */
 
-bool
+opt_result
 runtime_alias_check_p (ddr_p ddr, struct loop *loop, bool speed_p)
 {
   if (dump_enabled_p ())
@@ -1336,7 +1340,8 @@ runtime_alias_check_p (ddr_p ddr, struct loop *loop, bool speed_p)
 	dump_printf (MSG_MISSED_OPTIMIZATION,
 		     "runtime alias check not supported when optimizing "
 		     "for size.\n");
-      return false;
+      return opt_result::failure ("runtime alias check not supported when"
+				  " optimizing for size", NULL);
     }
 
   /* FORNOW: We don't support versioning with outer-loop in either
@@ -1346,10 +1351,11 @@ runtime_alias_check_p (ddr_p ddr, struct loop *loop, bool speed_p)
       if (dump_enabled_p ())
 	dump_printf (MSG_MISSED_OPTIMIZATION,
 		     "runtime alias check not supported for outer loop.\n");
-      return false;
+      return opt_result::failure ("runtime alias check not supported for"
+				  " outer loop", NULL);
     }
 
-  return true;
+  return opt_result::success ();
 }
 
 /* Operator == between two dr_with_seg_len objects.
@@ -5074,7 +5080,6 @@ find_data_references_in_stmt (struct loop *nest, gimple *stmt,
   unsigned i;
   auto_vec<data_ref_loc, 2> references;
   data_ref_loc *ref;
-  opt_result ret = opt_result::success ();
   data_reference_p dr;
 
   if (get_references_in_stmt (stmt, &references))
@@ -5089,7 +5094,7 @@ find_data_references_in_stmt (struct loop *nest, gimple *stmt,
       datarefs->safe_push (dr);
     }
 
-  return ret;
+  return opt_result::success ();
 }
 
 /* Stores the data references in STMT to DATAREFS.  If there is an
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index dbb912a..d734708 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -481,7 +481,7 @@ extern bool dr_may_alias_p (const struct data_reference *,
 extern bool dr_equal_offsets_p (struct data_reference *,
                                 struct data_reference *);
 
-extern bool runtime_alias_check_p (ddr_p, struct loop *, bool);
+extern opt_result runtime_alias_check_p (ddr_p, struct loop *, bool);
 extern int data_ref_compare_tree (tree, tree);
 extern void prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *,
 					   poly_uint64);
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 3693b31..80dd4b1 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -155,20 +155,22 @@ vect_get_smallest_scalar_type (gimple *stmt, HOST_WIDE_INT *lhs_size_unit,
    tested at run-time.  Return TRUE if DDR was successfully inserted.
    Return false if versioning is not supported.  */
 
-static bool
+static opt_result
 vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
 {
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
 
   if ((unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS) == 0)
-    return false;
+    return opt_result::failure ("FIXME", NULL);
 
-  if (!runtime_alias_check_p (ddr, loop,
-			      optimize_loop_nest_for_speed_p (loop)))
-    return false;
+  opt_result res
+    = runtime_alias_check_p (ddr, loop,
+			     optimize_loop_nest_for_speed_p (loop));
+  if (!res)
+    return res;
 
   LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo).safe_push (ddr);
-  return true;
+  return opt_result::success ();
 }
 
 /* Record that loop LOOP_VINFO needs to check that VALUE is nonzero.  */
@@ -280,12 +282,14 @@ vect_analyze_possibly_independent_ddr (data_dependence_relation *ddr,
 
 /* Function vect_analyze_data_ref_dependence.
 
-   Return TRUE if there (might) exist a dependence between a memory-reference
+   FIXME: I needed to change the sense of the returned flag.
+
+   Return FALSE if there (might) exist a dependence between a memory-reference
    DRA and a memory-reference DRB.  When versioning for alias may check a
-   dependence at run-time, return FALSE.  Adjust *MAX_VF according to
+   dependence at run-time, return TRUE.  Adjust *MAX_VF according to
    the data dependence.  */
 
-static bool
+static opt_result
 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 				  loop_vec_info loop_vinfo,
 				  unsigned int *max_vf)
@@ -306,11 +310,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 
   /* Independent data accesses.  */
   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
-    return false;
+    return opt_result::success ();
 
   if (dra == drb
       || (DR_IS_READ (dra) && DR_IS_READ (drb)))
-    return false;
+    return opt_result::success ();
 
   /* We do not have to consider dependences between accesses that belong
      to the same group, unless the stride could be smaller than the
@@ -319,7 +323,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
       && (DR_GROUP_FIRST_ELEMENT (stmtinfo_a)
 	  == DR_GROUP_FIRST_ELEMENT (stmtinfo_b))
       && !STMT_VINFO_STRIDED_P (stmtinfo_a))
-    return false;
+    return opt_result::success ();
 
   /* Even if we have an anti-dependence then, as the vectorized loop covers at
      least two scalar iterations, there is always also a true dependence.
@@ -331,7 +335,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
        || (DR_IS_WRITE (dra) && DR_IS_READ (drb)))
       && !alias_sets_conflict_p (get_alias_set (DR_REF (dra)),
 				 get_alias_set (DR_REF (drb))))
-    return false;
+    return opt_result::success ();
 
   /* Unknown data dependence.  */
   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
@@ -343,7 +347,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 	  if ((unsigned int) loop->safelen < *max_vf)
 	    *max_vf = loop->safelen;
 	  LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
-	  return false;
+	  return opt_result::success ();
 	}
 
       if (STMT_VINFO_GATHER_SCATTER_P (stmtinfo_a)
@@ -361,7 +365,8 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 				 DR_REF (drb));
 	      dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
 	    }
-	  return true;
+	  // FIXME: better message here, capturing the data of interest
+	  return opt_result::failure ("can't determine dependence", NULL);
 	}
 
       if (dump_enabled_p ())
@@ -378,7 +383,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 	}
 
       /* Add to list of ddrs that need to be tested at run-time.  */
-      return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
+      return vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
     }
 
   /* Known data dependence.  */
@@ -391,7 +396,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 	  if ((unsigned int) loop->safelen < *max_vf)
 	    *max_vf = loop->safelen;
 	  LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
-	  return false;
+	  return opt_result::success ();
 	}
 
       if (STMT_VINFO_GATHER_SCATTER_P (stmtinfo_a)
@@ -409,7 +414,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 				 DR_REF (drb));
 	      dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
 	    }
-	  return true;
+	  return opt_result::failure ("FIXME", NULL);
 	}
 
       if (dump_enabled_p ())
@@ -423,7 +428,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
         }
       /* Add to list of ddrs that need to be tested at run-time.  */
-      return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
+      return vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
     }
 
   loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
@@ -431,7 +436,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
   if (DDR_COULD_BE_INDEPENDENT_P (ddr)
       && vect_analyze_possibly_independent_ddr (ddr, loop_vinfo,
 						loop_depth, max_vf))
-    return false;
+    return opt_result::success ();
 
   FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, dist_v)
     {
@@ -477,7 +482,9 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 	      if (dump_enabled_p ())
 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 				 "READ_WRITE dependence in interleaving.\n");
-	      return true;
+	      // FIXME: capture stmts
+	      return opt_result::failure ("READ_WRITE dependence in"
+					  " interleaving", NULL);
 	    }
 
 	  if (loop->safelen < 2)
@@ -488,7 +495,9 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 		  if (dump_enabled_p ())
 		    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 				 "access also has a zero step\n");
-		  return true;
+		  // FIXME: capture stmts
+		  return opt_result::failure ("access also has a zero step",
+					      NULL);
 		}
 	      else if (TREE_CODE (indicator) != INTEGER_CST)
 		vect_check_nonzero_value (loop_vinfo, indicator);
@@ -547,10 +556,12 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
 	  dump_printf (MSG_NOTE,  "\n");
 	}
 
-      return true;
+      // FIXME: capture stmts
+      return opt_result::failure ("possible dependence between data-refs",
+				  NULL);
     }
 
-  return false;
+  return opt_result::success ();
 }
 
 /* Function vect_analyze_data_ref_dependences.
@@ -591,8 +602,12 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo,
     *max_vf = LOOP_VINFO_ORIG_MAX_VECT_FACTOR (loop_vinfo);
   else
     FOR_EACH_VEC_ELT (LOOP_VINFO_DDRS (loop_vinfo), i, ddr)
-      if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf))
-	return false;
+      {
+	opt_result res
+	  = vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf);
+	if (!res)
+	  return res;
+      }
 
   return opt_result::success ();
 }
@@ -1143,7 +1158,11 @@ verify_data_ref_alignment (data_reference_p dr)
 			     DR_REF (dr));
 	  dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
 	}
-      return false;
+      // FIXME: show dr here:
+      return opt_result::failure (DR_IS_READ (dr)
+				  ? "unsupported unaligned load"
+				  : "unsupported unaligned store",
+				  NULL);
     }
 
   if (supportable_dr_alignment != dr_aligned && dump_enabled_p ())
@@ -3561,7 +3580,8 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
 	      if (dump_enabled_p ())
 		dump_printf_loc (MSG_NOTE, vect_location,
 				 "not vectorized: compilation time alias.\n");
-	      return false;
+	      return opt_result::failure ("compilation time alias", stmt_a);
+	      // FIXME: and stmt_b
 	    }
 	}
 
@@ -3592,10 +3612,13 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
 			 "run-time tests exceeds %d "
 			 "(--param vect-max-version-for-alias-checks)\n",
 			 PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
-      return false;
+      return opt_result::failure ("number of versioning for alias "
+				  "run-time tests exceeds %d "
+				  "(--param vect-max-version-for-alias-checks)",
+				  NULL); // FIXME: make it variadic!
     }
 
-  return true;
+  return opt_result::success ();
 }
 
 /* Check whether we can use an internal function for a gather load
@@ -4197,7 +4220,7 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
 		  STMT_VINFO_VECTORIZABLE (stmt_info) = false;
 		  continue;
 		}
-	      return false;
+	      return opt_result::failure ("data ref analysis failed", stmt);
 	    }
         }
 
@@ -4213,7 +4236,7 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
 				   "failed ");
 		  dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
 		}
-	      return false;
+	      return opt_result::failure ("data ref analysis failed", stmt);
 	    }
 	  STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) = true;
 	}
@@ -4235,7 +4258,8 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
 	      STMT_VINFO_VECTORIZABLE (stmt_info) = false;
 	      continue;
 	    }
-	  return false;
+	  return opt_result::failure ("base object not addressable for stmt",
+				      stmt);
 	}
 
       if (is_a <loop_vec_info> (vinfo)
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index f7123c1..a3f1041 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -159,7 +159,7 @@ static void vect_estimate_min_profitable_iters (loop_vec_info, int *, int *);
    statement.  VECTYPE_MAYBE_SET_P is true if STMT_VINFO_VECTYPE
    may already be set for general statements (not just data refs).  */
 
-static bool
+static opt_result
 vect_determine_vf_for_stmt_1 (stmt_vec_info stmt_info,
 			      bool vectype_maybe_set_p,
 			      poly_uint64 *vf,
@@ -173,13 +173,14 @@ vect_determine_vf_for_stmt_1 (stmt_vec_info stmt_info,
     {
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_NOTE, vect_location, "skip.\n");
-      return true;
+      return opt_result::success ();
     }
 
   tree stmt_vectype, nunits_vectype;
-  if (!vect_get_vector_types_for_stmt (stmt_info, &stmt_vectype,
-				       &nunits_vectype))
-    return false;
+  opt_result res = vect_get_vector_types_for_stmt (stmt_info, &stmt_vectype,
+						   &nunits_vectype);
+  if (!res)
+    return res;
 
   if (stmt_vectype)
     {
@@ -199,7 +200,7 @@ vect_determine_vf_for_stmt_1 (stmt_vec_info stmt_info,
   if (nunits_vectype)
     vect_update_max_nunits (vf, nunits_vectype);
 
-  return true;
+  return opt_result::success ();
 }
 
 /* Subroutine of vect_determine_vectorization_factor.  Set the vector
@@ -209,7 +210,7 @@ vect_determine_vf_for_stmt_1 (stmt_vec_info stmt_info,
    add them to MASK_PRODUCERS.  Return true on success or false if
    something prevented vectorization.  */
 
-static bool
+static opt_result
 vect_determine_vf_for_stmt (stmt_vec_info stmt_info, poly_uint64 *vf,
 			    vec<stmt_vec_info > *mask_producers)
 {
@@ -218,8 +219,10 @@ vect_determine_vf_for_stmt (stmt_vec_info stmt_info, poly_uint64 *vf,
       dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: ");
       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt_info->stmt, 0);
     }
-  if (!vect_determine_vf_for_stmt_1 (stmt_info, false, vf, mask_producers))
-    return false;
+  opt_result res
+    = vect_determine_vf_for_stmt_1 (stmt_info, false, vf, mask_producers);
+  if (!res)
+    return res;
 
   if (STMT_VINFO_IN_PATTERN_P (stmt_info)
       && STMT_VINFO_RELATED_STMT (stmt_info))
@@ -239,9 +242,10 @@ vect_determine_vf_for_stmt (stmt_vec_info stmt_info, poly_uint64 *vf,
 	      dump_gimple_stmt (MSG_NOTE, TDF_SLIM,
 				def_stmt_info->stmt, 0);
 	    }
-	  if (!vect_determine_vf_for_stmt_1 (def_stmt_info, true,
-					     vf, mask_producers))
-	    return false;
+	  res = vect_determine_vf_for_stmt_1 (def_stmt_info, true,
+					      vf, mask_producers);
+	  if (!res)
+	    return res;
 	}
 
       if (dump_enabled_p ())
@@ -250,11 +254,12 @@ vect_determine_vf_for_stmt (stmt_vec_info stmt_info, poly_uint64 *vf,
 			   "==> examining pattern statement: ");
 	  dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt_info->stmt, 0);
 	}
-      if (!vect_determine_vf_for_stmt_1 (stmt_info, true, vf, mask_producers))
-	return false;
+      res = vect_determine_vf_for_stmt_1 (stmt_info, true, vf, mask_producers);
+      if (!res)
+	return res;
     }
 
-  return true;
+  return opt_result::success ();
 }
 
 /* Function vect_determine_vectorization_factor
@@ -368,9 +373,11 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
 	   gsi_next (&si))
 	{
 	  stmt_info = vinfo_for_stmt (gsi_stmt (si));
-	  if (!vect_determine_vf_for_stmt (stmt_info, &vectorization_factor,
-					   &mask_producers))
-	    return false;
+	  opt_result res
+	    = vect_determine_vf_for_stmt (stmt_info, &vectorization_factor,
+					  &mask_producers);
+	  if (!res)
+	    return res;
         }
     }
 
@@ -387,7 +394,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                          "not vectorized: unsupported data-type\n");
-      return false;
+      return opt_result::failure ("unsupported data-type", NULL);
     }
   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
 
@@ -1190,7 +1197,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
           if (dump_enabled_p ())
             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			     "not vectorized: control flow in loop.\n");
-          return false;
+          return opt_result::failure ("control flow in loop", NULL);
         }
 
       if (empty_block_p (loop->header))
@@ -1198,7 +1205,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			     "not vectorized: empty loop.\n");
-	  return false;
+          return opt_result::failure ("empty loop", NULL);
 	}
     }
   else
@@ -1228,7 +1235,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			     "not vectorized: multiple nested loops.\n");
-	  return false;
+          return opt_result::failure ("multiple nested loops", NULL);
 	}
 
       if (loop->num_nodes != 5)
@@ -1236,7 +1243,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			     "not vectorized: control flow in loop.\n");
-	  return false;
+          return opt_result::failure ("control flow in loop", NULL);
         }
 
       entryedge = loop_preheader_edge (innerloop);
@@ -1247,7 +1254,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			     "not vectorized: unsupported outerloop form.\n");
-	  return false;
+          return opt_result::failure ("unsupported outerloop form", NULL);
 	}
 
       /* Analyze the inner-loop.  */
@@ -1304,7 +1311,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			 "not vectorized: latch block not empty.\n");
-      return false;
+      return opt_result::failure ("latch block not empty", NULL);
     }
 
   /* Make sure the exit is not abnormal.  */
@@ -1314,7 +1321,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			 "not vectorized: abnormal loop exit edge.\n");
-      return false;
+      return opt_result::failure ("abnormal loop exit edge", NULL);
     }
 
   *loop_cond = vect_get_loop_niters (loop, assumptions, number_of_iterations,
@@ -1324,7 +1331,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			 "not vectorized: complicated exit condition.\n");
-      return false;
+      return opt_result::failure ("complicated exit condition", NULL);
     }
 
   if (integer_zerop (*assumptions)
@@ -1335,7 +1342,8 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			 "not vectorized: number of iterations cannot be "
 			 "computed.\n");
-      return false;
+      return opt_result::failure ("number of iterations cannot be computed",
+				  NULL);
     }
 
   if (integer_zerop (*number_of_iterations))
@@ -1343,7 +1351,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			 "not vectorized: number of iterations = 0.\n");
-      return false;
+      return opt_result::failure ("number of iterations = 0", NULL);
     }
 
   return opt_result::success ();
@@ -1559,7 +1567,8 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
 		    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 				     "Unsupported loop-closed phi in "
 				     "outer-loop.\n");
-                  return false;
+                  return opt_result::failure ("Unsupported loop-closed phi in "
+					      "outer-loop", phi);
                 }
 
               /* If PHI is used in the outer loop, we check that its operand
@@ -1570,23 +1579,23 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
 		  gimple *op_def_stmt;
 
                   if (gimple_phi_num_args (phi) != 1)
-                    return false;
+                    return opt_result::failure ("unsupported phi", phi);
 
                   phi_op = PHI_ARG_DEF (phi, 0);
                   if (TREE_CODE (phi_op) != SSA_NAME)
-                    return false;
+		    return opt_result::failure ("unsupported phi", phi);
 
                   op_def_stmt = SSA_NAME_DEF_STMT (phi_op);
 		  if (gimple_nop_p (op_def_stmt)
 		      || !flow_bb_inside_loop_p (loop, gimple_bb (op_def_stmt))
 		      || !vinfo_for_stmt (op_def_stmt))
-                    return false;
+                    return opt_result::failure ("unsupported phi", phi);
 
                   if (STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt))
                         != vect_used_in_outer
                       && STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt))
                            != vect_used_in_outer_by_reduction)
-                    return false;
+		    return opt_result::failure ("unsupported phi", phi);
                 }
 
               continue;
@@ -1602,7 +1611,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
               if (dump_enabled_p ())
 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 				 "not vectorized: scalar dependence cycle.\n");
-              return false;
+              return opt_result::failure ("scalar dependence cycle", phi);
             }
 
           if (STMT_VINFO_RELEVANT_P (stmt_info))
@@ -1670,10 +1679,11 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			 "not vectorized: redundant loop. no profit to "
 			 "vectorize.\n");
-      return false;
+      return opt_result::failure ("redundant loop. no profit to vectorize",
+				  NULL);
     }
 
-  return true;
+  return opt_result::success ();
 }
 
 /* Analyze the cost of the loop described by LOOP_VINFO.  Decide if it
@@ -1941,7 +1951,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, unsigned *n_stmts)
       if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			     "bad data dependence.\n");
-      return false;
+      return ok;
     }
   LOOP_VINFO_MAX_VECT_FACTOR (loop_vinfo) = max_vf;
 
@@ -2097,7 +2107,8 @@ start_over:
 	    dump_printf_loc (MSG_NOTE, vect_location,
 			     "loop has no enough iterations to support"
 			     " peeling for gaps.\n");
-	  return false;
+	  return opt_result::failure ("loop has not enough iterations to"
+				      " support peeling for gaps", NULL);
 	}
     }
 
@@ -2110,7 +2121,7 @@ start_over:
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 			 "Loop costings not worthwhile.\n");
-      return res;
+      return opt_result::failure ("Loop costings not worthwhile", NULL);
     }
 
   /* Decide whether we need to create an epilogue loop to handle
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 619bc22..53a0788 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -476,7 +476,8 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                          "not vectorized: unsupported use in stmt.\n");
-      return false;
+      // FIXME: have this come from vect_is_simple_use?
+      return opt_result::failure ("unsupported use in stmt", stmt);
     }
 
   if (!def_stmt || gimple_nop_p (def_stmt))
@@ -761,20 +762,28 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
 	      i = 1;
 	      if (rhs_code == COND_EXPR && COMPARISON_CLASS_P (op))
 		{
-		  if (!process_use (stmt, TREE_OPERAND (op, 0), loop_vinfo,
-				    relevant, &worklist, false)
-		      || !process_use (stmt, TREE_OPERAND (op, 1), loop_vinfo,
-				       relevant, &worklist, false))
-		    return false;
+		  opt_result res
+		    = process_use (stmt, TREE_OPERAND (op, 0), loop_vinfo,
+				   relevant, &worklist, false);
+		  if (!res)
+		    return res;
+		  res = process_use (stmt, TREE_OPERAND (op, 1), loop_vinfo,
+				     relevant, &worklist, false);
+		  if (!res)
+		    return res;
 		  i = 2;
 		}
 	      for (; i < gimple_num_ops (stmt); i++)
                 {
 		  op = gimple_op (stmt, i);
-                  if (TREE_CODE (op) == SSA_NAME
-		      && !process_use (stmt, op, loop_vinfo, relevant,
-				       &worklist, false))
-                    return false;
+                  if (TREE_CODE (op) == SSA_NAME)
+		    {
+		      opt_result res
+			= process_use (stmt, op, loop_vinfo, relevant,
+				       &worklist, false);
+		      if (!res)
+			return res;
+		    }
                  }
             }
           else if (is_gimple_call (stmt))
@@ -782,9 +791,11 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
               for (i = 0; i < gimple_call_num_args (stmt); i++)
                 {
                   tree arg = gimple_call_arg (stmt, i);
-		  if (!process_use (stmt, arg, loop_vinfo, relevant,
-				    &worklist, false))
-                    return false;
+		  opt_result res
+		    = process_use (stmt, arg, loop_vinfo, relevant,
+				   &worklist, false);
+		  if (!res)
+		    return res;
                 }
             }
         }
@@ -792,9 +803,11 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
         FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
           {
             tree op = USE_FROM_PTR (use_p);
-	    if (!process_use (stmt, op, loop_vinfo, relevant,
-			      &worklist, false))
-              return false;
+	    opt_result res
+	      = process_use (stmt, op, loop_vinfo, relevant,
+			     &worklist, false);
+	    if (!res)
+	      return res;
           }
 
       if (STMT_VINFO_GATHER_SCATTER_P (stmt_vinfo))
@@ -802,9 +815,11 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
 	  gather_scatter_info gs_info;
 	  if (!vect_check_gather_scatter (stmt, loop_vinfo, &gs_info))
 	    gcc_unreachable ();
-	  if (!process_use (stmt, gs_info.offset, loop_vinfo, relevant,
-			    &worklist, true))
-	    return false;
+	  opt_result res
+	    = process_use (stmt, gs_info.offset, loop_vinfo, relevant,
+			   &worklist, true);
+	  if (!res)
+	    return res;
 	}
     } /* while worklist */
 
@@ -9493,7 +9508,7 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node,
     {
       dump_printf_loc (MSG_NOTE, vect_location,
 		       "handled only by SLP analysis\n");
-      return true;
+      return opt_result::success ();
     }
 
   ok = true;
@@ -10627,7 +10642,7 @@ vect_gen_while_not (gimple_seq *seq, tree mask_type, tree start_index,
      number of units needed to vectorize STMT_INFO, or NULL_TREE if the
      statement does not help to determine the overall number of units.  */
 
-bool
+opt_result
 vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 				tree *stmt_vectype_out,
 				tree *nunits_vectype_out)
@@ -10650,7 +10665,7 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_NOTE, vect_location,
 			     "defer to SIMD clone analysis.\n");
-	  return true;
+	  return opt_result::success ();
 	}
 
       if (dump_enabled_p ())
@@ -10659,7 +10674,7 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 			   "not vectorized: irregular stmt.");
 	  dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
 	}
-      return false;
+      return opt_result::failure ("irregular stmt", stmt);
     }
 
   if (VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))))
@@ -10670,7 +10685,7 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 			   "not vectorized: vector stmt in loop:");
 	  dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
 	}
-      return false;
+      return opt_result::failure ("vector stmt in loop", stmt);
     }
 
   tree vectype;
@@ -10702,7 +10717,7 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 	      if (dump_enabled_p ())
 		dump_printf_loc (MSG_NOTE, vect_location,
 				 "pure bool operation.\n");
-	      return true;
+	      return opt_result::success ();
 	    }
 	}
 
@@ -10787,7 +10802,9 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 	  dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, nunits_vectype);
 	  dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
 	}
-      return false;
+      // FIXME: capture the types
+      return opt_result::failure ("different sized vector"
+				  " types in statement", NULL);
     }
 
   if (dump_enabled_p ())
@@ -10802,7 +10819,7 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
     }
 
   *nunits_vectype_out = nunits_vectype;
-  return true;
+  return opt_result::success ();
 }
 
 /* Try to determine the correct vector type for STMT_INFO, which is a
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 3ce4236..a7f18bc 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1579,7 +1579,8 @@ extern tree vect_gen_perm_mask_checked (tree, const vec_perm_indices &);
 extern void optimize_mask_stores (struct loop*);
 extern gcall *vect_gen_while (tree, tree, tree);
 extern tree vect_gen_while_not (gimple_seq *, tree, tree, tree);
-extern bool vect_get_vector_types_for_stmt (stmt_vec_info, tree *, tree *);
+extern opt_result vect_get_vector_types_for_stmt (stmt_vec_info, tree *,
+						  tree *);
 extern tree vect_get_mask_type_for_stmt (stmt_vec_info);
 
 /* In tree-vect-data-refs.c.  */
-- 
1.8.5.3

