Default types:
--------------

While the primary exit condition for loops is no longer tied to some
upper limit in the number of executed iterations, similar limits are
still required for vectorization.  One example of this is with prolog
peeling.  The prolog will always have an IV exit associated with the
misalignment of data accesses within the loop.

Historically, the assumption held that the data-type that this counter
should have could be derived from the type of the niters limit for the
original loop, so we could get the type from `TREE_TYPE (niters)'.

Moving forward, we provide a backup type to be used for iteration
counters when the maximum number of iterations to be run is unknown.

We take this to be `size_t', given its role in storing the maximum
size of a theoretically possible object of any type (including array).

Default return values:
----------------------

To avoid having to gate all calls to functions that query a loop's
niters value it is better to "teach" such functions how to handle
uncounted loops and have them return a sensible value that can be
handled upon a function's return.

We therefore prevent functions operating on niters from segfaulting by
adding a default `SCEV_NOT_KNOWN' return value when niters information
absent.

gcc/ChangeLog:

        * tree-vect-loop-manip.cc (vect_gen_prolog_loop_niters): Add
        type default of `size_t'.
        (vect_gen_vector_loop_niters): Likewise.
        (vect_do_peeling): Likewise.
        * tree-vect-loop.cc (vect_min_prec_for_max_niters): Likewise.
        * tree-vect-loop-manip.cc (vect_build_loop_niters): Gracefully
          handle uncounted loops.
        * tree-vect-loop.cc (loop_niters_no_overflow): Likewise.
---
 gcc/tree-vect-loop-manip.cc | 13 ++++++++++---
 gcc/tree-vect-loop.cc       | 10 +++++++++-
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 6af07efe68a..928045540da 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -2511,7 +2511,10 @@ vect_gen_prolog_loop_niters (loop_vec_info loop_vinfo,
 {
   dr_vec_info *dr_info = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
   tree var;
-  tree niters_type = TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo));
+  tree niters_type
+    = LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo) ? size_type_node
+                                                : TREE_TYPE (LOOP_VINFO_NITERS
+                                                             (loop_vinfo));
   gimple_seq stmts = NULL, new_stmts = NULL;
   tree iters, iters_name;
   stmt_vec_info stmt_info = dr_info->stmt;
@@ -2690,6 +2693,8 @@ vect_prepare_for_masked_peels (loop_vec_info loop_vinfo)
 tree
 vect_build_loop_niters (loop_vec_info loop_vinfo, bool *new_var_p)
 {
+  if (LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo))
+    return NULL_TREE;
   tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
   if (TREE_CODE (ni) == INTEGER_CST)
     return ni;
@@ -2784,7 +2789,8 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, 
tree niters,
                             bool niters_no_overflow)
 {
   tree ni_minus_gap, var;
-  tree niters_vector, step_vector, type = TREE_TYPE (niters);
+  tree niters_vector, step_vector;
+  tree type = niters ? TREE_TYPE (niters) : size_type_node;
   poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
 
@@ -3139,7 +3145,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, 
tree nitersm1,
                 tree *advance)
 {
   edge e, guard_e;
-  tree type = TREE_TYPE (niters), guard_cond;
+  tree type = niters ? TREE_TYPE (niters) : size_type_node;
+  tree guard_cond;
   basic_block guard_bb, guard_to;
   profile_probability prob_prolog, prob_vector, prob_epilog;
   int estimated_vf;
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index dfb0960e7d1..b17745cdaa1 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -937,7 +937,11 @@ vect_min_prec_for_max_niters (loop_vec_info loop_vinfo, 
unsigned int factor)
 
   /* Get the maximum number of iterations that is representable
      in the counter type.  */
-  tree ni_type = TREE_TYPE (LOOP_VINFO_NITERSM1 (loop_vinfo));
+  tree ni_type;
+  if (!LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo))
+    ni_type = TREE_TYPE (LOOP_VINFO_NITERSM1 (loop_vinfo));
+  else
+    ni_type = size_type_node;
   widest_int max_ni = wi::to_widest (TYPE_MAX_VALUE (ni_type)) + 1;
 
   /* Get a more refined estimate for the number of iterations.  */
@@ -10490,6 +10494,10 @@ vectorizable_live_operation (vec_info *vinfo, 
stmt_vec_info stmt_info,
 static bool
 loop_niters_no_overflow (loop_vec_info loop_vinfo)
 {
+  /* Unknown case.  */
+  if (LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo))
+    return true;
+
   /* Constant case.  */
   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
     {
-- 
2.43.0

Reply via email to