Because bbs of loop_vec_info need to be allocated via old-fashion
XCNEWVEC, in order to receive result from dfs_enumerate_from(),
so have to make bb_vec_info align with loop_vec_info, use
basic_block * instead of vec<basic_block>. Another reason is that
some loop vect related codes assume that bbs is a pointer, such
as using LOOP_VINFO_BBS() to directly free the bbs area.

While encapsulating bbs into array_slice might make changed code
more wordy. So still choose basic_block * as its type. Updated the
patch by removing bbs_as_vector.

Feng.
----
gcc/
        * tree-vect-loop.cc (_loop_vec_info::_loop_vec_info): Move
        initialization of bbs to explicit construction code.  Adjust the
        definition of nbbs.
        (update_epilogue_loop_vinfo): Update nbbs for epilog vinfo.
        * tree-vect-pattern.cc (vect_determine_precisions): Make
        loop_vec_info and bb_vec_info share same code.
        (vect_pattern_recog): Remove duplicated vect_pattern_recog_1 loop.
        * tree-vect-slp.cc (vect_get_and_check_slp_defs): Access to bbs[0]
        via base vec_info class.
        (_bb_vec_info::_bb_vec_info): Initialize bbs and nbbs using data
        fields of input auto_vec<> bbs.
        (vect_slp_region): Use access to nbbs to replace original
        bbs.length().
        (vect_schedule_slp_node): Access to bbs[0] via base vec_info class.
        * tree-vectorizer.cc (vec_info::vec_info): Add initialization of
        bbs and nbbs.
        (vec_info::insert_seq_on_entry): Access to bbs[0] via base vec_info
        class.
        * tree-vectorizer.h (vec_info): Add new fields bbs and nbbs.
        (LOOP_VINFO_NBBS): New macro.
        (BB_VINFO_BBS): Rename BB_VINFO_BB to BB_VINFO_BBS.
        (BB_VINFO_NBBS): New macro.
        (_loop_vec_info): Remove field bbs.
        (_bb_vec_info): Rename field bbs.
---
 gcc/tree-vect-loop.cc     |   7 +-
 gcc/tree-vect-patterns.cc | 142 +++++++++++---------------------------
 gcc/tree-vect-slp.cc      |  23 +++---
 gcc/tree-vectorizer.cc    |   7 +-
 gcc/tree-vectorizer.h     |  19 +++--
 5 files changed, 70 insertions(+), 128 deletions(-)

diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 3b94bb13a8b..04a9ac64df7 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -1028,7 +1028,6 @@ bb_in_loop_p (const_basic_block bb, const void *data)
 _loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared)
   : vec_info (vec_info::loop, shared),
     loop (loop_in),
-    bbs (XCNEWVEC (basic_block, loop->num_nodes)),
     num_itersm1 (NULL_TREE),
     num_iters (NULL_TREE),
     num_iters_unchanged (NULL_TREE),
@@ -1079,8 +1078,9 @@ _loop_vec_info::_loop_vec_info (class loop *loop_in, 
vec_info_shared *shared)
      case of the loop forms we allow, a dfs order of the BBs would the same
      as reversed postorder traversal, so we are safe.  */

-  unsigned int nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
-                                         bbs, loop->num_nodes, loop);
+  bbs = XCNEWVEC (basic_block, loop->num_nodes);
+  nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p, bbs,
+                            loop->num_nodes, loop);
   gcc_assert (nbbs == loop->num_nodes);

   for (unsigned int i = 0; i < nbbs; i++)
@@ -11667,6 +11667,7 @@ update_epilogue_loop_vinfo (class loop *epilogue, tree 
advance)

   free (LOOP_VINFO_BBS (epilogue_vinfo));
   LOOP_VINFO_BBS (epilogue_vinfo) = epilogue_bbs;
+  LOOP_VINFO_NBBS (epilogue_vinfo) = epilogue->num_nodes;

   /* Advance data_reference's with the number of iterations of the previous
      loop and its prologue.  */
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 8929e5aa7f3..88e7e34d78d 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -6925,81 +6925,41 @@ vect_determine_stmt_precisions (vec_info *vinfo, 
stmt_vec_info stmt_info)
 void
 vect_determine_precisions (vec_info *vinfo)
 {
+  basic_block *bbs = vinfo->bbs;
+  unsigned int nbbs = vinfo->nbbs;
+
   DUMP_VECT_SCOPE ("vect_determine_precisions");

-  if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
+  for (unsigned int i = 0; i < nbbs; i++)
     {
-      class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-      basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
-      unsigned int nbbs = loop->num_nodes;
-
-      for (unsigned int i = 0; i < nbbs; i++)
+      basic_block bb = bbs[i];
+      for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         basic_block bb = bbs[i];
-         for (auto gsi = gsi_start_phis (bb);
-              !gsi_end_p (gsi); gsi_next (&gsi))
-           {
-             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
-             if (stmt_info)
-               vect_determine_mask_precision (vinfo, stmt_info);
-           }
-         for (auto si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
-           if (!is_gimple_debug (gsi_stmt (si)))
-             vect_determine_mask_precision
-               (vinfo, vinfo->lookup_stmt (gsi_stmt (si)));
+         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
+         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+           vect_determine_mask_precision (vinfo, stmt_info);
        }
-      for (unsigned int i = 0; i < nbbs; i++)
+      for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         basic_block bb = bbs[nbbs - i - 1];
-         for (gimple_stmt_iterator si = gsi_last_bb (bb);
-              !gsi_end_p (si); gsi_prev (&si))
-           if (!is_gimple_debug (gsi_stmt (si)))
-             vect_determine_stmt_precisions
-               (vinfo, vinfo->lookup_stmt (gsi_stmt (si)));
-         for (auto gsi = gsi_start_phis (bb);
-              !gsi_end_p (gsi); gsi_next (&gsi))
-           {
-             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
-             if (stmt_info)
-               vect_determine_stmt_precisions (vinfo, stmt_info);
-           }
+         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
+         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+           vect_determine_mask_precision (vinfo, stmt_info);
        }
     }
-  else
+  for (unsigned int i = 0; i < nbbs; i++)
     {
-      bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
-      for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
+      basic_block bb = bbs[nbbs - i - 1];
+      for (auto gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
        {
-         basic_block bb = bb_vinfo->bbs[i];
-         for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next 
(&gsi))
-           {
-             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
-             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
-               vect_determine_mask_precision (vinfo, stmt_info);
-           }
-         for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-           {
-             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
-             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
-               vect_determine_mask_precision (vinfo, stmt_info);
-           }
+         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
+         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+           vect_determine_stmt_precisions (vinfo, stmt_info);
        }
-      for (int i = bb_vinfo->bbs.length () - 1; i != -1; --i)
+      for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         for (gimple_stmt_iterator gsi = gsi_last_bb (bb_vinfo->bbs[i]);
-              !gsi_end_p (gsi); gsi_prev (&gsi))
-           {
-             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
-             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
-               vect_determine_stmt_precisions (vinfo, stmt_info);
-           }
-         for (auto gsi = gsi_start_phis (bb_vinfo->bbs[i]);
-              !gsi_end_p (gsi); gsi_next (&gsi))
-           {
-             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
-             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
-               vect_determine_stmt_precisions (vinfo, stmt_info);
-           }
+         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
+         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+           vect_determine_stmt_precisions (vinfo, stmt_info);
        }
     }
 }
@@ -7328,56 +7288,32 @@ vect_pattern_recog_1 (vec_info *vinfo,
 void
 vect_pattern_recog (vec_info *vinfo)
 {
-  class loop *loop;
-  basic_block *bbs;
-  unsigned int nbbs;
-  gimple_stmt_iterator si;
-  unsigned int i, j;
+  basic_block *bbs = vinfo->bbs;
+  unsigned int nbbs = vinfo->nbbs;

   vect_determine_precisions (vinfo);

   DUMP_VECT_SCOPE ("vect_pattern_recog");

-  if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
+  /* Scan through the stmts in the region, applying the pattern recognition
+     functions starting at each stmt visited.  */
+  for (unsigned i = 0; i < nbbs; i++)
     {
-      loop = LOOP_VINFO_LOOP (loop_vinfo);
-      bbs = LOOP_VINFO_BBS (loop_vinfo);
-      nbbs = loop->num_nodes;
+      basic_block bb = bbs[i];

-      /* Scan through the loop stmts, applying the pattern recognition
-        functions starting at each stmt visited:  */
-      for (i = 0; i < nbbs; i++)
+      for (auto si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
        {
-         basic_block bb = bbs[i];
-         for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
-           {
-             if (is_gimple_debug (gsi_stmt (si)))
-               continue;
-             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
-             /* Scan over all generic vect_recog_xxx_pattern functions.  */
-             for (j = 0; j < NUM_PATTERNS; j++)
-               vect_pattern_recog_1 (vinfo, &vect_vect_recog_func_ptrs[j],
-                                     stmt_info);
-           }
+         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
+
+         if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info))
+           continue;
+
+         /* Scan over all generic vect_recog_xxx_pattern functions.  */
+         for (unsigned j = 0; j < NUM_PATTERNS; j++)
+           vect_pattern_recog_1 (vinfo, &vect_vect_recog_func_ptrs[j],
+                                 stmt_info);
        }
     }
-  else
-    {
-      bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
-      for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
-       for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
-            !gsi_end_p (gsi); gsi_next (&gsi))
-         {
-           stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (gsi_stmt (gsi));
-           if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info))
-             continue;
-
-           /* Scan over all generic vect_recog_xxx_pattern functions.  */
-           for (j = 0; j < NUM_PATTERNS; j++)
-             vect_pattern_recog_1 (vinfo,
-                                   &vect_vect_recog_func_ptrs[j], stmt_info);
-         }
-    }

   /* After this no more add_stmt calls are allowed.  */
   vinfo->stmt_vec_info_ro = true;
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 7a963e28063..bc7a85d6bfc 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -748,8 +748,7 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char 
swap,
          && is_a <bb_vec_info> (vinfo)
          && TREE_CODE (oprnd) == SSA_NAME
          && !SSA_NAME_IS_DEFAULT_DEF (oprnd)
-         && !dominated_by_p (CDI_DOMINATORS,
-                             as_a <bb_vec_info> (vinfo)->bbs[0],
+         && !dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
                              gimple_bb (SSA_NAME_DEF_STMT (oprnd))))
        {
          if (dump_enabled_p ())
@@ -6293,10 +6292,16 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)

 _bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, vec_info_shared *shared)
   : vec_info (vec_info::bb, shared),
-    bbs (_bbs),
     roots (vNULL)
 {
-  for (unsigned i = 0; i < bbs.length (); ++i)
+  /* The region we are operating on.  bbs[0] is the entry, excluding
+     its PHI nodes.  In the future we might want to track an explicit
+     entry edge to cover bbs[0] PHI nodes and have a region entry
+     insert location.  */
+  bbs = _bbs.address ();
+  nbbs = _bbs.length ();
+
+  for (unsigned i = 0; i < nbbs; ++i)
     {
       if (i != 0)
        for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
@@ -6325,7 +6330,7 @@ _bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, 
vec_info_shared *shared)
 _bb_vec_info::~_bb_vec_info ()
 {
   /* Reset region marker.  */
-  for (unsigned i = 0; i < bbs.length (); ++i)
+  for (unsigned i = 0; i < nbbs; ++i)
     {
       if (i != 0)
        for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
@@ -7630,7 +7635,7 @@ vect_slp_is_lane_insert (gimple *use_stmt, tree vec, 
unsigned *this_lane)
 static void
 vect_slp_check_for_roots (bb_vec_info bb_vinfo)
 {
-  for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
+  for (unsigned i = 0; i < bb_vinfo->nbbs; ++i)
     for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
         !gsi_end_p (gsi); gsi_next (&gsi))
     {
@@ -8114,7 +8119,7 @@ vect_slp_region (vec<basic_block> bbs, 
vec<data_reference_p> datarefs,
             we vectorized all if-converted code.  */
          if ((!profitable_subgraphs.is_empty () || force_clear) && orig_loop)
            {
-             gcc_assert (bb_vinfo->bbs.length () == 1);
+             gcc_assert (bb_vinfo->nbbs == 1);
              for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]);
                   !gsi_end_p (gsi); gsi_next (&gsi))
                {
@@ -9618,14 +9623,14 @@ vect_schedule_slp_node (vec_info *vinfo,
       if (!last_stmt)
        {
          gcc_assert (seen_vector_def);
-         si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
+         si = gsi_after_labels (vinfo->bbs[0]);
        }
       else if (is_ctrl_altering_stmt (last_stmt))
        {
          /* We split regions to vectorize at control altering stmts
             with a definition so this must be an external which
             we can insert at the start of the region.  */
-         si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
+         si = gsi_after_labels (vinfo->bbs[0]);
        }
       else if (is_a <bb_vec_info> (vinfo)
               && gimple_bb (last_stmt) != gimple_bb (stmt_info->stmt)
diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc
index 9001b738bf3..1fb4fb36ed4 100644
--- a/gcc/tree-vectorizer.cc
+++ b/gcc/tree-vectorizer.cc
@@ -463,7 +463,9 @@ shrink_simd_arrays
 vec_info::vec_info (vec_info::vec_kind kind_in, vec_info_shared *shared_)
   : kind (kind_in),
     shared (shared_),
-    stmt_vec_info_ro (false)
+    stmt_vec_info_ro (false),
+    bbs (NULL),
+    nbbs (0)
 {
   stmt_vec_infos.create (50);
 }
@@ -660,9 +662,8 @@ vec_info::insert_seq_on_entry (stmt_vec_info context, 
gimple_seq seq)
     }
   else
     {
-      bb_vec_info bb_vinfo = as_a <bb_vec_info> (this);
       gimple_stmt_iterator gsi_region_begin
-       = gsi_after_labels (bb_vinfo->bbs[0]);
+       = gsi_after_labels (bbs[0]);
       gsi_insert_seq_before (&gsi_region_begin, seq, GSI_SAME_STMT);
     }
 }
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 93bc30ef660..bd4f5952f4b 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -499,6 +499,12 @@ public:
      made any decisions about which vector modes to use.  */
   machine_mode vector_mode;

+  /* The basic blocks in the vectorization region.  */
+  basic_block *bbs;
+
+  /* The count of the basic blocks in the vectorization region.  */
+  unsigned int nbbs;
+
 private:
   stmt_vec_info new_stmt_vec_info (gimple *stmt);
   void set_vinfo_for_stmt (gimple *, stmt_vec_info, bool = true);
@@ -679,9 +685,6 @@ public:
   /* The loop to which this info struct refers to.  */
   class loop *loop;

-  /* The loop basic blocks.  */
-  basic_block *bbs;
-
   /* Number of latch executions.  */
   tree num_itersm1;
   /* Number of iterations.  */
@@ -969,6 +972,7 @@ public:
 #define LOOP_VINFO_EPILOGUE_IV_EXIT(L)     (L)->vec_epilogue_loop_iv_exit
 #define LOOP_VINFO_SCALAR_IV_EXIT(L)       (L)->scalar_loop_iv_exit
 #define LOOP_VINFO_BBS(L)                  (L)->bbs
+#define LOOP_VINFO_NBBS(L)                 (L)->nbbs
 #define LOOP_VINFO_NITERSM1(L)             (L)->num_itersm1
 #define LOOP_VINFO_NITERS(L)               (L)->num_iters
 /* Since LOOP_VINFO_NITERS and LOOP_VINFO_NITERSM1 can change after
@@ -1094,16 +1098,11 @@ public:
   _bb_vec_info (vec<basic_block> bbs, vec_info_shared *);
   ~_bb_vec_info ();

-  /* The region we are operating on.  bbs[0] is the entry, excluding
-     its PHI nodes.  In the future we might want to track an explicit
-     entry edge to cover bbs[0] PHI nodes and have a region entry
-     insert location.  */
-  vec<basic_block> bbs;
-
   vec<slp_root> roots;
 } *bb_vec_info;

-#define BB_VINFO_BB(B)               (B)->bb
+#define BB_VINFO_BBS(B)              (B)->bbs
+#define BB_VINFO_NBBS(B)             (B)->nbbs
 #define BB_VINFO_GROUPED_STORES(B)   (B)->grouped_stores
 #define BB_VINFO_SLP_INSTANCES(B)    (B)->slp_instances
 #define BB_VINFO_DATAREFS(B)         (B)->shared->datarefs
--
2.17.1

________________________________________
From: Richard Biener <richard.guent...@gmail.com>
Sent: Tuesday, May 28, 2024 5:43 PM
To: Feng Xue OS
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] vect: Unify bbs in loop_vec_info and bb_vec_info

On Sat, May 25, 2024 at 4:54 PM Feng Xue OS <f...@os.amperecomputing.com> wrote:
>
> Both derived classes ( loop_vec_info/bb_vec_info) have their own "bbs"
> field, which have exactly same purpose of recording all basic blocks
> inside the corresponding vect region, while the fields are composed by
> different data type, one is normal array, the other is auto_vec. This
> difference causes some duplicated code even handling the same stuff,
> almost in tree-vect-patterns. One refinement is lifting this field into the
> base class "vec_info", and reset its value to the continuous memory area
> pointed by two old "bbs" in each constructor of derived classes.

Nice.  But.  bbs_as_vector - why is that necessary?  Why is vinfo->bbs
not a vec<basic_block>?  Having bbs and nbbs feels like a step back.

Note the code duplications can probably be removed by "indirecting"
through an array_slice.

I'm a bit torn to approve this as-is given the above.  Can you explain what
made you not choose vec<> for bbs?  I bet you tried.

Richard.

> Regression test on x86-64 and aarch64.
>
> Feng
> --
> gcc/
>         * tree-vect-loop.cc (_loop_vec_info::_loop_vec_info): Move
>         initialization of bbs to explicit construction code.  Adjust the
>         definition of nbbs.
>         * tree-vect-pattern.cc (vect_determine_precisions): Make
>         loop_vec_info and bb_vec_info share same code.
>         (vect_pattern_recog): Remove duplicated vect_pattern_recog_1 loop.
>         * tree-vect-slp.cc (vect_get_and_check_slp_defs): Access to bbs[0]
>         via base vec_info class.
>         (_bb_vec_info::_bb_vec_info): Initialize bbs and nbbs using data
>         fields of input auto_vec<> bbs.
>         (_bb_vec_info::_bb_vec_info): Add assertions on bbs and nbbs to ensure
>         they are not changed externally.
>         (vect_slp_region): Use access to nbbs to replace original
>         bbs.length().
>         (vect_schedule_slp_node): Access to bbs[0] via base vec_info class.
>         * tree-vectorizer.cc (vec_info::vec_info): Add initialization of
>         bbs and nbbs.
>         (vec_info::insert_seq_on_entry): Access to bbs[0] via base vec_info
>         class.
>         * tree-vectorizer.h (vec_info): Add new fields bbs and nbbs.
>         (_loop_vec_info): Remove field bbs.
>         (_bb_vec_info): Rename old bbs field to bbs_as_vector, and make it
>         be private.
> ---
>  gcc/tree-vect-loop.cc     |   6 +-
>  gcc/tree-vect-patterns.cc | 142 +++++++++++---------------------------
>  gcc/tree-vect-slp.cc      |  24 ++++---
>  gcc/tree-vectorizer.cc    |   7 +-
>  gcc/tree-vectorizer.h     |  19 ++---
>  5 files changed, 72 insertions(+), 126 deletions(-)
>
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index 83c0544b6aa..aef17420a5f 100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -1028,7 +1028,6 @@ bb_in_loop_p (const_basic_block bb, const void *data)
>  _loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared)
>    : vec_info (vec_info::loop, shared),
>      loop (loop_in),
> -    bbs (XCNEWVEC (basic_block, loop->num_nodes)),
>      num_itersm1 (NULL_TREE),
>      num_iters (NULL_TREE),
>      num_iters_unchanged (NULL_TREE),
> @@ -1079,8 +1078,9 @@ _loop_vec_info::_loop_vec_info (class loop *loop_in, 
> vec_info_shared *shared)
>       case of the loop forms we allow, a dfs order of the BBs would the same
>       as reversed postorder traversal, so we are safe.  */
>
> -  unsigned int nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
> -                                         bbs, loop->num_nodes, loop);
> +  bbs = XCNEWVEC (basic_block, loop->num_nodes);
> +  nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p, bbs,
> +                            loop->num_nodes, loop);
>    gcc_assert (nbbs == loop->num_nodes);
>
>    for (unsigned int i = 0; i < nbbs; i++)
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index a313dc64643..848a3195a93 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -6925,81 +6925,41 @@ vect_determine_stmt_precisions (vec_info *vinfo, 
> stmt_vec_info stmt_info)
>  void
>  vect_determine_precisions (vec_info *vinfo)
>  {
> +  basic_block *bbs = vinfo->bbs;
> +  unsigned int nbbs = vinfo->nbbs;
> +
>    DUMP_VECT_SCOPE ("vect_determine_precisions");
>
> -  if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
> +  for (unsigned int i = 0; i < nbbs; i++)
>      {
> -      class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
> -      basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
> -      unsigned int nbbs = loop->num_nodes;
> -
> -      for (unsigned int i = 0; i < nbbs; i++)
> +      basic_block bb = bbs[i];
> +      for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>         {
> -         basic_block bb = bbs[i];
> -         for (auto gsi = gsi_start_phis (bb);
> -              !gsi_end_p (gsi); gsi_next (&gsi))
> -           {
> -             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
> -             if (stmt_info)
> -               vect_determine_mask_precision (vinfo, stmt_info);
> -           }
> -         for (auto si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
> -           if (!is_gimple_debug (gsi_stmt (si)))
> -             vect_determine_mask_precision
> -               (vinfo, vinfo->lookup_stmt (gsi_stmt (si)));
> +         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
> +         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> +           vect_determine_mask_precision (vinfo, stmt_info);
>         }
> -      for (unsigned int i = 0; i < nbbs; i++)
> +      for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>         {
> -         basic_block bb = bbs[nbbs - i - 1];
> -         for (gimple_stmt_iterator si = gsi_last_bb (bb);
> -              !gsi_end_p (si); gsi_prev (&si))
> -           if (!is_gimple_debug (gsi_stmt (si)))
> -             vect_determine_stmt_precisions
> -               (vinfo, vinfo->lookup_stmt (gsi_stmt (si)));
> -         for (auto gsi = gsi_start_phis (bb);
> -              !gsi_end_p (gsi); gsi_next (&gsi))
> -           {
> -             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
> -             if (stmt_info)
> -               vect_determine_stmt_precisions (vinfo, stmt_info);
> -           }
> +         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
> +         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> +           vect_determine_mask_precision (vinfo, stmt_info);
>         }
>      }
> -  else
> +  for (unsigned int i = 0; i < nbbs; i++)
>      {
> -      bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
> -      for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
> +      basic_block bb = bbs[nbbs - i - 1];
> +      for (auto gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
>         {
> -         basic_block bb = bb_vinfo->bbs[i];
> -         for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next 
> (&gsi))
> -           {
> -             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
> -             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> -               vect_determine_mask_precision (vinfo, stmt_info);
> -           }
> -         for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next 
> (&gsi))
> -           {
> -             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
> -             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> -               vect_determine_mask_precision (vinfo, stmt_info);
> -           }
> +         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
> +         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> +           vect_determine_stmt_precisions (vinfo, stmt_info);
>         }
> -      for (int i = bb_vinfo->bbs.length () - 1; i != -1; --i)
> +      for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>         {
> -         for (gimple_stmt_iterator gsi = gsi_last_bb (bb_vinfo->bbs[i]);
> -              !gsi_end_p (gsi); gsi_prev (&gsi))
> -           {
> -             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
> -             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> -               vect_determine_stmt_precisions (vinfo, stmt_info);
> -           }
> -         for (auto gsi = gsi_start_phis (bb_vinfo->bbs[i]);
> -              !gsi_end_p (gsi); gsi_next (&gsi))
> -           {
> -             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
> -             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> -               vect_determine_stmt_precisions (vinfo, stmt_info);
> -           }
> +         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
> +         if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
> +           vect_determine_stmt_precisions (vinfo, stmt_info);
>         }
>      }
>  }
> @@ -7328,56 +7288,32 @@ vect_pattern_recog_1 (vec_info *vinfo,
>  void
>  vect_pattern_recog (vec_info *vinfo)
>  {
> -  class loop *loop;
> -  basic_block *bbs;
> -  unsigned int nbbs;
> -  gimple_stmt_iterator si;
> -  unsigned int i, j;
> +  basic_block *bbs = vinfo->bbs;
> +  unsigned int nbbs = vinfo->nbbs;
>
>    vect_determine_precisions (vinfo);
>
>    DUMP_VECT_SCOPE ("vect_pattern_recog");
>
> -  if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
> +  /* Scan through the stmts in the region, applying the pattern recognition
> +     functions starting at each stmt visited.  */
> +  for (unsigned i = 0; i < nbbs; i++)
>      {
> -      loop = LOOP_VINFO_LOOP (loop_vinfo);
> -      bbs = LOOP_VINFO_BBS (loop_vinfo);
> -      nbbs = loop->num_nodes;
> +      basic_block bb = bbs[i];
>
> -      /* Scan through the loop stmts, applying the pattern recognition
> -        functions starting at each stmt visited:  */
> -      for (i = 0; i < nbbs; i++)
> +      for (auto si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
>         {
> -         basic_block bb = bbs[i];
> -         for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
> -           {
> -             if (is_gimple_debug (gsi_stmt (si)))
> -               continue;
> -             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
> -             /* Scan over all generic vect_recog_xxx_pattern functions.  */
> -             for (j = 0; j < NUM_PATTERNS; j++)
> -               vect_pattern_recog_1 (vinfo, &vect_vect_recog_func_ptrs[j],
> -                                     stmt_info);
> -           }
> +         stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
> +
> +         if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info))
> +           continue;
> +
> +         /* Scan over all generic vect_recog_xxx_pattern functions.  */
> +         for (unsigned j = 0; j < NUM_PATTERNS; j++)
> +           vect_pattern_recog_1 (vinfo, &vect_vect_recog_func_ptrs[j],
> +                                 stmt_info);
>         }
>      }
> -  else
> -    {
> -      bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
> -      for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
> -       for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
> -            !gsi_end_p (gsi); gsi_next (&gsi))
> -         {
> -           stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (gsi_stmt (gsi));
> -           if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info))
> -             continue;
> -
> -           /* Scan over all generic vect_recog_xxx_pattern functions.  */
> -           for (j = 0; j < NUM_PATTERNS; j++)
> -             vect_pattern_recog_1 (vinfo,
> -                                   &vect_vect_recog_func_ptrs[j], stmt_info);
> -         }
> -    }
>
>    /* After this no more add_stmt calls are allowed.  */
>    vinfo->stmt_vec_info_ro = true;
> diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
> index c7ed520b629..2e0244cf582 100644
> --- a/gcc/tree-vect-slp.cc
> +++ b/gcc/tree-vect-slp.cc
> @@ -748,8 +748,7 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned 
> char swap,
>           && is_a <bb_vec_info> (vinfo)
>           && TREE_CODE (oprnd) == SSA_NAME
>           && !SSA_NAME_IS_DEFAULT_DEF (oprnd)
> -         && !dominated_by_p (CDI_DOMINATORS,
> -                             as_a <bb_vec_info> (vinfo)->bbs[0],
> +         && !dominated_by_p (CDI_DOMINATORS, vinfo->bbs[0],
>                               gimple_bb (SSA_NAME_DEF_STMT (oprnd))))
>         {
>           if (dump_enabled_p ())
> @@ -6288,10 +6287,13 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
>
>  _bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, vec_info_shared *shared)
>    : vec_info (vec_info::bb, shared),
> -    bbs (_bbs),
> +    bbs_as_vector (_bbs),
>      roots (vNULL)
>  {
> -  for (unsigned i = 0; i < bbs.length (); ++i)
> +  bbs = bbs_as_vector.address ();
> +  nbbs = bbs_as_vector.length ();
> +
> +  for (unsigned i = 0; i < nbbs; ++i)
>      {
>        if (i != 0)
>         for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
> @@ -6319,8 +6321,12 @@ _bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, 
> vec_info_shared *shared)
>
>  _bb_vec_info::~_bb_vec_info ()
>  {
> +  /* Check that bbs stored in the vector is not changed externally.  */
> +  gcc_assert (bbs == bbs_as_vector.address ());
> +  gcc_assert (nbbs = bbs_as_vector.length ());
> +
>    /* Reset region marker.  */
> -  for (unsigned i = 0; i < bbs.length (); ++i)
> +  for (unsigned i = 0; i < nbbs; ++i)
>      {
>        if (i != 0)
>         for (gphi_iterator si = gsi_start_phis (bbs[i]); !gsi_end_p (si);
> @@ -7625,7 +7631,7 @@ vect_slp_is_lane_insert (gimple *use_stmt, tree vec, 
> unsigned *this_lane)
>  static void
>  vect_slp_check_for_roots (bb_vec_info bb_vinfo)
>  {
> -  for (unsigned i = 0; i < bb_vinfo->bbs.length (); ++i)
> +  for (unsigned i = 0; i < bb_vinfo->nbbs; ++i)
>      for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[i]);
>          !gsi_end_p (gsi); gsi_next (&gsi))
>      {
> @@ -8109,7 +8115,7 @@ vect_slp_region (vec<basic_block> bbs, 
> vec<data_reference_p> datarefs,
>              we vectorized all if-converted code.  */
>           if ((!profitable_subgraphs.is_empty () || force_clear) && orig_loop)
>             {
> -             gcc_assert (bb_vinfo->bbs.length () == 1);
> +             gcc_assert (bb_vinfo->nbbs == 1);
>               for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]);
>                    !gsi_end_p (gsi); gsi_next (&gsi))
>                 {
> @@ -9613,14 +9619,14 @@ vect_schedule_slp_node (vec_info *vinfo,
>        if (!last_stmt)
>         {
>           gcc_assert (seen_vector_def);
> -         si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
> +         si = gsi_after_labels (vinfo->bbs[0]);
>         }
>        else if (is_ctrl_altering_stmt (last_stmt))
>         {
>           /* We split regions to vectorize at control altering stmts
>              with a definition so this must be an external which
>              we can insert at the start of the region.  */
> -         si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]);
> +         si = gsi_after_labels (vinfo->bbs[0]);
>         }
>        else if (is_a <bb_vec_info> (vinfo)
>                && gimple_bb (last_stmt) != gimple_bb (stmt_info->stmt)
> diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc
> index 9001b738bf3..1fb4fb36ed4 100644
> --- a/gcc/tree-vectorizer.cc
> +++ b/gcc/tree-vectorizer.cc
> @@ -463,7 +463,9 @@ shrink_simd_arrays
>  vec_info::vec_info (vec_info::vec_kind kind_in, vec_info_shared *shared_)
>    : kind (kind_in),
>      shared (shared_),
> -    stmt_vec_info_ro (false)
> +    stmt_vec_info_ro (false),
> +    bbs (NULL),
> +    nbbs (0)
>  {
>    stmt_vec_infos.create (50);
>  }
> @@ -660,9 +662,8 @@ vec_info::insert_seq_on_entry (stmt_vec_info context, 
> gimple_seq seq)
>      }
>    else
>      {
> -      bb_vec_info bb_vinfo = as_a <bb_vec_info> (this);
>        gimple_stmt_iterator gsi_region_begin
> -       = gsi_after_labels (bb_vinfo->bbs[0]);
> +       = gsi_after_labels (bbs[0]);
>        gsi_insert_seq_before (&gsi_region_begin, seq, GSI_SAME_STMT);
>      }
>  }
> diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
> index 93bc30ef660..ffc2b223dd2 100644
> --- a/gcc/tree-vectorizer.h
> +++ b/gcc/tree-vectorizer.h
> @@ -499,6 +499,12 @@ public:
>       made any decisions about which vector modes to use.  */
>    machine_mode vector_mode;
>
> +  /* The basic blocks in the vectorization region.  */
> +  basic_block *bbs;
> +
> +  /* The count of the basic blocks in the vectorization region.  */
> +  unsigned int nbbs;
> +
>  private:
>    stmt_vec_info new_stmt_vec_info (gimple *stmt);
>    void set_vinfo_for_stmt (gimple *, stmt_vec_info, bool = true);
> @@ -679,9 +685,6 @@ public:
>    /* The loop to which this info struct refers to.  */
>    class loop *loop;
>
> -  /* The loop basic blocks.  */
> -  basic_block *bbs;
> -
>    /* Number of latch executions.  */
>    tree num_itersm1;
>    /* Number of iterations.  */
> @@ -1090,15 +1093,15 @@ struct slp_root
>
>  typedef class _bb_vec_info : public vec_info
>  {
> -public:
> -  _bb_vec_info (vec<basic_block> bbs, vec_info_shared *);
> -  ~_bb_vec_info ();
> -
>    /* The region we are operating on.  bbs[0] is the entry, excluding
>       its PHI nodes.  In the future we might want to track an explicit
>       entry edge to cover bbs[0] PHI nodes and have a region entry
>       insert location.  */
> -  vec<basic_block> bbs;
> +  vec<basic_block> bbs_as_vector;
> +
> +public:
> +  _bb_vec_info (vec<basic_block> bbs, vec_info_shared *);
> +  ~_bb_vec_info ();
>
>    vec<slp_root> roots;
>  } *bb_vec_info;
> --
> 2.17.1

Reply via email to