[V2,03/14] RISC-V: P3: Refactor vector_infos_manager

Message ID 20231017113500.1160997-4-lehua.ding@rivai.ai
State Unresolved
Headers
Series Refactor and cleanup vsetvl pass |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Lehua Ding Oct. 17, 2023, 11:34 a.m. UTC
  This sub-patch refactor vector_infos_manager to a pre_vsetvl class
which is responsible for the entire lazy vsetvl jobs. There is no need
to introduce a separate vsetvl infos manager, because vsetvl infos are
modified by the optimization code.

gcc/ChangeLog:

	* config/riscv/riscv-vsetvl.cc (vector_infos_manager::vector_infos_manager): Removed.
	(class pre_vsetvl): New class.
	(vector_infos_manager::create_expr): Removed.
	(vector_infos_manager::get_expr_id): Removed.
	(vector_infos_manager::all_same_ratio_p): Removed.
	(vector_infos_manager::all_avail_in_compatible_p): Removed.
	(vector_infos_manager::all_same_avl_p): Removed.
	(vector_infos_manager::expr_set_num): Removed.
	(vector_infos_manager::release): Removed.
	(vector_infos_manager::create_bitmap_vectors): Removed.
	(vector_infos_manager::free_bitmap_vectors): Removed.
	(vector_infos_manager::dump): Removed.
	* config/riscv/riscv-vsetvl.h (class vector_infos_manager): Removed.

---
 gcc/config/riscv/riscv-vsetvl.cc | 632 +++++++++++++------------------
 gcc/config/riscv/riscv-vsetvl.h  |  75 ----
 2 files changed, 257 insertions(+), 450 deletions(-)

--
2.36.3
  

Comments

juzhe.zhong@rivai.ai Oct. 18, 2023, 3:58 a.m. UTC | #1
+  demand_system dem;
+  auto_vec<vsetvl_block_info> vector_block_infos;
+
+  /* data for avl reaching defintion.  */
+  sbitmap avl_regs;
+  sbitmap *avl_def_in;
+  sbitmap *avl_def_out;
+  sbitmap *reg_def_loc;
+
+  /* data for vsetvl info reaching defintion.  */
+  vsetvl_info unknow_info;
+  auto_vec<vsetvl_info *> vsetvl_def_exprs;
+  sbitmap *vsetvl_def_in;
+  sbitmap *vsetvl_def_out;
+
+  /* data for lcm */
+  auto_vec<vsetvl_info *> exprs;
+  sbitmap *avloc;
+  sbitmap *avin;
+  sbitmap *avout;
+  sbitmap *kill;
+  sbitmap *antloc;
+  sbitmap *transp;
+  sbitmap *insert;
+  sbitmap *del;
+  struct edge_list *edges;
+
+  auto_vec<vsetvl_info> delete_list;

All of them add "m_" prefix.

earliest_fusion_worthwhile_p -> successors_probability_equal_p

calculate_dominance_info (CDI_POST_DOMINATORS); ----> remove
free_dominance_info (CDI_POST_DOMINATORS); ---> remove



juzhe.zhong@rivai.ai
 
From: Lehua Ding
Date: 2023-10-17 19:34
To: gcc-patches
CC: juzhe.zhong; kito.cheng; rdapp.gcc; palmer; jeffreyalaw; lehua.ding
Subject: [PATCH V2 03/14] RISC-V: P3: Refactor vector_infos_manager
This sub-patch refactor vector_infos_manager to a pre_vsetvl class
which is responsible for the entire lazy vsetvl jobs. There is no need
to introduce a separate vsetvl infos manager, because vsetvl infos are
modified by the optimization code.
 
gcc/ChangeLog:
 
* config/riscv/riscv-vsetvl.cc (vector_infos_manager::vector_infos_manager): Removed.
(class pre_vsetvl): New class.
(vector_infos_manager::create_expr): Removed.
(vector_infos_manager::get_expr_id): Removed.
(vector_infos_manager::all_same_ratio_p): Removed.
(vector_infos_manager::all_avail_in_compatible_p): Removed.
(vector_infos_manager::all_same_avl_p): Removed.
(vector_infos_manager::expr_set_num): Removed.
(vector_infos_manager::release): Removed.
(vector_infos_manager::create_bitmap_vectors): Removed.
(vector_infos_manager::free_bitmap_vectors): Removed.
(vector_infos_manager::dump): Removed.
* config/riscv/riscv-vsetvl.h (class vector_infos_manager): Removed.
 
---
gcc/config/riscv/riscv-vsetvl.cc | 632 +++++++++++++------------------
gcc/config/riscv/riscv-vsetvl.h  |  75 ----
2 files changed, 257 insertions(+), 450 deletions(-)
 
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index be40b6fdf4c..c219ad178bb 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -2390,402 +2390,284 @@ public:
   }
};
 
-vector_infos_manager::vector_infos_manager ()
+class pre_vsetvl
{
-  vector_edge_list = nullptr;
-  vector_kill = nullptr;
-  vector_del = nullptr;
-  vector_insert = nullptr;
-  vector_antic = nullptr;
-  vector_transp = nullptr;
-  vector_comp = nullptr;
-  vector_avin = nullptr;
-  vector_avout = nullptr;
-  vector_antin = nullptr;
-  vector_antout = nullptr;
-  vector_earliest = nullptr;
-  vector_insn_infos.safe_grow_cleared (get_max_uid ());
-  vector_block_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
-  if (!optimize)
-    {
-      basic_block cfg_bb;
-      rtx_insn *rinsn;
-      FOR_ALL_BB_FN (cfg_bb, cfun)
- {
-   vector_block_infos[cfg_bb->index].local_dem = vector_insn_info ();
-   vector_block_infos[cfg_bb->index].reaching_out = vector_insn_info ();
-   FOR_BB_INSNS (cfg_bb, rinsn)
-     vector_insn_infos[INSN_UID (rinsn)].parse_insn (rinsn);
- }
-    }
-  else
-    {
-      for (const bb_info *bb : crtl->ssa->bbs ())
- {
-   vector_block_infos[bb->index ()].local_dem = vector_insn_info ();
-   vector_block_infos[bb->index ()].reaching_out = vector_insn_info ();
-   for (insn_info *insn : bb->real_insns ())
-     vector_insn_infos[insn->uid ()].parse_insn (insn);
-   vector_block_infos[bb->index ()].probability = profile_probability ();
- }
-    }
-}
-
-void
-vector_infos_manager::create_expr (vector_insn_info &info)
-{
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (*vector_exprs[i] == info)
-      return;
-  vector_exprs.safe_push (&info);
-}
-
-size_t
-vector_infos_manager::get_expr_id (const vector_insn_info &info) const
-{
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (*vector_exprs[i] == info)
-      return i;
-  gcc_unreachable ();
-}
-
-auto_vec<size_t>
-vector_infos_manager::get_all_available_exprs (
-  const vector_insn_info &info) const
-{
-  auto_vec<size_t> available_list;
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (info.available_p (*vector_exprs[i]))
-      available_list.safe_push (i);
-  return available_list;
-}
-
-bool
-vector_infos_manager::all_same_ratio_p (sbitmap bitdata) const
-{
-  if (bitmap_empty_p (bitdata))
-    return false;
-
-  int ratio = -1;
-  unsigned int bb_index;
-  sbitmap_iterator sbi;
-
-  EXECUTE_IF_SET_IN_BITMAP (bitdata, 0, bb_index, sbi)
-    {
-      if (ratio == -1)
- ratio = vector_exprs[bb_index]->get_ratio ();
-      else if (vector_exprs[bb_index]->get_ratio () != ratio)
- return false;
-    }
-  return true;
-}
-
-/* Return TRUE if the incoming vector configuration state
-   to CFG_BB is compatible with the vector configuration
-   state in CFG_BB, FALSE otherwise.  */
-bool
-vector_infos_manager::all_avail_in_compatible_p (const basic_block cfg_bb) const
-{
-  const auto &info = vector_block_infos[cfg_bb->index].local_dem;
-  sbitmap avin = vector_avin[cfg_bb->index];
-  unsigned int bb_index;
-  sbitmap_iterator sbi;
-  EXECUTE_IF_SET_IN_BITMAP (avin, 0, bb_index, sbi)
-    {
-      const auto &avin_info
- = static_cast<const vl_vtype_info &> (*vector_exprs[bb_index]);
-      if (!info.compatible_p (avin_info))
- return false;
-    }
-  return true;
-}
-
-bool
-vector_infos_manager::all_same_avl_p (const basic_block cfg_bb,
-       sbitmap bitdata) const
-{
-  if (bitmap_empty_p (bitdata))
-    return false;
-
-  const auto &block_info = vector_block_infos[cfg_bb->index];
-  if (!block_info.local_dem.demand_p (DEMAND_AVL))
-    return true;
-
-  avl_info avl = block_info.local_dem.get_avl_info ();
-  unsigned int bb_index;
-  sbitmap_iterator sbi;
-
-  EXECUTE_IF_SET_IN_BITMAP (bitdata, 0, bb_index, sbi)
-    {
-      if (vector_exprs[bb_index]->get_avl_info () != avl)
- return false;
-    }
-  return true;
-}
+private:
+  demand_system dem;
+  auto_vec<vsetvl_block_info> vector_block_infos;
+
+  /* data for avl reaching defintion.  */
+  sbitmap avl_regs;
+  sbitmap *avl_def_in;
+  sbitmap *avl_def_out;
+  sbitmap *reg_def_loc;
+
+  /* data for vsetvl info reaching defintion.  */
+  vsetvl_info unknow_info;
+  auto_vec<vsetvl_info *> vsetvl_def_exprs;
+  sbitmap *vsetvl_def_in;
+  sbitmap *vsetvl_def_out;
+
+  /* data for lcm */
+  auto_vec<vsetvl_info *> exprs;
+  sbitmap *avloc;
+  sbitmap *avin;
+  sbitmap *avout;
+  sbitmap *kill;
+  sbitmap *antloc;
+  sbitmap *transp;
+  sbitmap *insert;
+  sbitmap *del;
+  struct edge_list *edges;
+
+  auto_vec<vsetvl_info> delete_list;
+
+  vsetvl_block_info &get_block_info (const bb_info *bb)
+  {
+    return vector_block_infos[bb->index ()];
+  }
+  const vsetvl_block_info &get_block_info (const basic_block bb) const
+  {
+    return vector_block_infos[bb->index];
+  }
 
-bool
-vector_infos_manager::earliest_fusion_worthwhile_p (
-  const basic_block cfg_bb) const
-{
-  edge e;
-  edge_iterator ei;
-  profile_probability prob = profile_probability::uninitialized ();
-  FOR_EACH_EDGE (e, ei, cfg_bb->succs)
-    {
-      if (prob == profile_probability::uninitialized ())
- prob = vector_block_infos[e->dest->index].probability;
-      else if (prob == vector_block_infos[e->dest->index].probability)
- continue;
-      else
- /* We pick the highest probability among those incompatible VSETVL
-    infos. When all incompatible VSTEVL infos have same probability, we
-    don't pick any of them.  */
- return true;
-    }
-  return false;
-}
+  vsetvl_block_info &get_block_info (const basic_block bb)
+  {
+    return vector_block_infos[bb->index];
+  }
 
-bool
-vector_infos_manager::vsetvl_dominated_by_all_preds_p (
-  const basic_block cfg_bb, const vector_insn_info &info) const
-{
-  edge e;
-  edge_iterator ei;
-  FOR_EACH_EDGE (e, ei, cfg_bb->preds)
-    {
-      const auto &reaching_out = vector_block_infos[e->src->index].reaching_out;
-      if (e->src->index == cfg_bb->index && reaching_out.compatible_p (info))
- continue;
-      if (!vsetvl_dominated_by_p (e->src, info, reaching_out, false))
- return false;
-    }
-  return true;
-}
+  void add_expr (auto_vec<vsetvl_info *> &exprs, vsetvl_info &info)
+  {
+    for (vsetvl_info *item : exprs)
+      {
+ if (*item == info)
+   return;
+      }
+    exprs.safe_push (&info);
+  }
 
-size_t
-vector_infos_manager::expr_set_num (sbitmap bitdata) const
-{
-  size_t count = 0;
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (bitmap_bit_p (bitdata, i))
-      count++;
-  return count;
-}
+  unsigned get_expr_index (auto_vec<vsetvl_info *> &exprs,
+    const vsetvl_info &info)
+  {
+    for (size_t i = 0; i < exprs.length (); i += 1)
+      {
+ if (*exprs[i] == info)
+   return i;
+      }
+    gcc_unreachable ();
+  }
 
-void
-vector_infos_manager::release (void)
-{
-  if (!vector_insn_infos.is_empty ())
-    vector_insn_infos.release ();
-  if (!vector_block_infos.is_empty ())
-    vector_block_infos.release ();
-  if (!vector_exprs.is_empty ())
-    vector_exprs.release ();
-
-  gcc_assert (to_refine_vsetvls.is_empty ());
-  gcc_assert (to_delete_vsetvls.is_empty ());
-  if (optimize > 0)
-    free_bitmap_vectors ();
-}
+  bool anticpatable_exp_p (const vsetvl_info &header_info)
+  {
+    if (!header_info.has_reg_avl () && !header_info.has_reg_vl ())
+      return true;
 
-void
-vector_infos_manager::create_bitmap_vectors (void)
-{
-  /* Create the bitmap vectors.  */
-  vector_antic = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-        vector_exprs.length ());
-  vector_transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
- vector_exprs.length ());
-  vector_comp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-       vector_exprs.length ());
-  vector_avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-       vector_exprs.length ());
-  vector_avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-        vector_exprs.length ());
-  vector_kill = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-       vector_exprs.length ());
-  vector_antin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-        vector_exprs.length ());
-  vector_antout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
- vector_exprs.length ());
-
-  bitmap_vector_ones (vector_transp, last_basic_block_for_fn (cfun));
-  bitmap_vector_clear (vector_antic, last_basic_block_for_fn (cfun));
-  bitmap_vector_clear (vector_comp, last_basic_block_for_fn (cfun));
-  vector_edge_list = create_edge_list ();
-  vector_earliest = sbitmap_vector_alloc (NUM_EDGES (vector_edge_list),
-   vector_exprs.length ());
-}
+    bb_info *bb = header_info.get_bb ();
+    insn_info *prev_insn = bb->head_insn ();
+    insn_info *next_insn = header_info.get_insn ();
+    if (bb != next_insn->bb ())
+      next_insn = bb->end_insn ();
 
-void
-vector_infos_manager::free_bitmap_vectors (void)
-{
-  /* Finished. Free up all the things we've allocated.  */
-  free_edge_list (vector_edge_list);
-  if (vector_del)
-    sbitmap_vector_free (vector_del);
-  if (vector_insert)
-    sbitmap_vector_free (vector_insert);
-  if (vector_kill)
-    sbitmap_vector_free (vector_kill);
-  if (vector_antic)
-    sbitmap_vector_free (vector_antic);
-  if (vector_transp)
-    sbitmap_vector_free (vector_transp);
-  if (vector_comp)
-    sbitmap_vector_free (vector_comp);
-  if (vector_avin)
-    sbitmap_vector_free (vector_avin);
-  if (vector_avout)
-    sbitmap_vector_free (vector_avout);
-  if (vector_antin)
-    sbitmap_vector_free (vector_antin);
-  if (vector_antout)
-    sbitmap_vector_free (vector_antout);
-  if (vector_earliest)
-    sbitmap_vector_free (vector_earliest);
-
-  vector_edge_list = nullptr;
-  vector_kill = nullptr;
-  vector_del = nullptr;
-  vector_insert = nullptr;
-  vector_antic = nullptr;
-  vector_transp = nullptr;
-  vector_comp = nullptr;
-  vector_avin = nullptr;
-  vector_avout = nullptr;
-  vector_antin = nullptr;
-  vector_antout = nullptr;
-  vector_earliest = nullptr;
-}
+    return dem.safe_move_avl_vl_p (prev_insn, next_insn, header_info);
+  }
 
-void
-vector_infos_manager::dump (FILE *file) const
-{
-  basic_block cfg_bb;
-  rtx_insn *rinsn;
+  bool available_exp_p (const vsetvl_info &prev_info,
+ const vsetvl_info &next_info)
+  {
+    return dem.available_with (prev_info, next_info);
+  }
 
-  fprintf (file, "\n");
-  FOR_ALL_BB_FN (cfg_bb, cfun)
-    {
-      fprintf (file, "Local vector info of <bb %d>:\n", cfg_bb->index);
-      fprintf (file, "<HEADER>=");
-      vector_block_infos[cfg_bb->index].local_dem.dump (file);
-      FOR_BB_INSNS (cfg_bb, rinsn)
- {
-   if (!NONDEBUG_INSN_P (rinsn) || !has_vtype_op (rinsn))
-     continue;
-   fprintf (file, "<insn %d>=", INSN_UID (rinsn));
-   const auto &info = vector_insn_infos[INSN_UID (rinsn)];
-   info.dump (file);
- }
-      fprintf (file, "<FOOTER>=");
-      vector_block_infos[cfg_bb->index].reaching_out.dump (file);
-      fprintf (file, "<Probability>=");
-      vector_block_infos[cfg_bb->index].probability.dump (file);
-      fprintf (file, "\n\n");
-    }
+  void compute_probabilities ()
+  {
+    edge e;
+    edge_iterator ei;
 
-  fprintf (file, "\n");
-  FOR_ALL_BB_FN (cfg_bb, cfun)
-    {
-      fprintf (file, "Local properties of <bb %d>:\n", cfg_bb->index);
+    for (const bb_info *bb : crtl->ssa->bbs ())
+      {
+ basic_block cfg_bb = bb->cfg_bb ();
+ auto &curr_prob = get_block_info (cfg_bb).probability;
+
+ /* GCC assume entry block (bb 0) are always so
+    executed so set its probability as "always".  */
+ if (ENTRY_BLOCK_PTR_FOR_FN (cfun) == cfg_bb)
+   curr_prob = profile_probability::always ();
+ /* Exit block (bb 1) is the block we don't need to process.  */
+ if (EXIT_BLOCK_PTR_FOR_FN (cfun) == cfg_bb)
+   continue;
 
-      fprintf (file, "<ANTLOC>=");
-      if (vector_antic == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_antic[cfg_bb->index]);
+ gcc_assert (curr_prob.initialized_p ());
+ FOR_EACH_EDGE (e, ei, cfg_bb->succs)
+   {
+     auto &new_prob = get_block_info (e->dest).probability;
+     /* Normally, the edge probability should be initialized.
+        However, some special testing code which is written in
+        GIMPLE IR style force the edge probility uninitialized,
+        we conservatively set it as never so that it will not
+        affect PRE (Phase 3 && Phse 4).  */
+     if (!e->probability.initialized_p ())
+       new_prob = profile_probability::never ();
+     else if (!new_prob.initialized_p ())
+       new_prob = curr_prob * e->probability;
+     else if (new_prob == profile_probability::always ())
+       continue;
+     else
+       new_prob += curr_prob * e->probability;
+   }
+      }
+  }
 
-      fprintf (file, "<AVLOC>=");
-      if (vector_comp == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_comp[cfg_bb->index]);
+  void insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
+       const vsetvl_info &info)
+  {
+    if (info.change_vtype_only_p ())
+      emit_vsetvl_insn (VSETVL_VTYPE_CHANGE_ONLY, emit_type, info, NULL_RTX,
+ rinsn);
 
-      fprintf (file, "<TRANSP>=");
-      if (vector_transp == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_transp[cfg_bb->index]);
+    else if (info.has_reg_vl ())
+      emit_vsetvl_insn (VSETVL_NORMAL, emit_type, info, info.get_vl (), rinsn);
+    else
+      emit_vsetvl_insn (VSETVL_DISCARD_RESULT, emit_type, info, NULL_RTX,
+ rinsn);
+  }
 
-      fprintf (file, "<KILL>=");
-      if (vector_kill == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_kill[cfg_bb->index]);
+  bool earliest_fusion_worthwhile_p (const basic_block cfg_bb) const
+  {
+    edge e;
+    edge_iterator ei;
+    profile_probability prob = profile_probability::uninitialized ();
+    FOR_EACH_EDGE (e, ei, cfg_bb->succs)
+      {
+ if (prob == profile_probability::uninitialized ())
+   prob = vector_block_infos[e->dest->index].probability;
+ else if (prob == vector_block_infos[e->dest->index].probability)
+   continue;
+ else
+   /* We pick the highest probability among those incompatible VSETVL
+      infos. When all incompatible VSTEVL infos have same probability, we
+      don't pick any of them.  */
+   return true;
+      }
+    return false;
+  }
 
-      fprintf (file, "<ANTIN>=");
-      if (vector_antin == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_antin[cfg_bb->index]);
+  bool preds_has_same_avl_p (const vsetvl_info &curr_info)
+  {
+    if (bitmap_empty_p (avin[curr_info.get_bb ()->index ()]))
+      return false;
 
-      fprintf (file, "<ANTOUT>=");
-      if (vector_antout == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_antout[cfg_bb->index]);
-    }
+    unsigned expr_index;
+    sbitmap_iterator sbi;
+    EXECUTE_IF_SET_IN_BITMAP (avin[curr_info.get_bb ()->index ()], 0,
+       expr_index, sbi)
+      {
+ const vsetvl_info &prev_info = *exprs[expr_index];
+ if (!prev_info.valid_p ()
+     || !dem.available_avl_with (prev_info, curr_info))
+   return false;
+      }
+    return true;
+  }
 
-  fprintf (file, "\n");
-  FOR_ALL_BB_FN (cfg_bb, cfun)
-    {
-      fprintf (file, "Global LCM (Lazy code motion) result of <bb %d>:\n",
-        cfg_bb->index);
+public:
+  pre_vsetvl ()
+    : avl_def_in (nullptr), avl_def_out (nullptr), vsetvl_def_in (nullptr),
+      vsetvl_def_out (nullptr), avloc (nullptr), avin (nullptr),
+      avout (nullptr), kill (nullptr), antloc (nullptr), transp (nullptr),
+      insert (nullptr), del (nullptr), edges (nullptr)
+  {
+    /* Initialization of RTL_SSA.  */
+    calculate_dominance_info (CDI_DOMINATORS);
+    calculate_dominance_info (CDI_POST_DOMINATORS);
+    df_analyze ();
+    crtl->ssa = new function_info (cfun);
+    vector_block_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
+    compute_probabilities ();
+    unknow_info.set_unknown ();
+  }
 
-      fprintf (file, "<AVIN>=");
-      if (vector_avin == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_avin[cfg_bb->index]);
+  void finish ()
+  {
+    free_dominance_info (CDI_DOMINATORS);
+    free_dominance_info (CDI_POST_DOMINATORS);
+    if (crtl->ssa->perform_pending_updates ())
+      cleanup_cfg (0);
+    delete crtl->ssa;
+    crtl->ssa = nullptr;
+
+    if (avl_regs)
+      sbitmap_free (avl_regs);
+    if (reg_def_loc)
+      sbitmap_vector_free (reg_def_loc);
+
+    if (avl_def_in)
+      sbitmap_vector_free (avl_def_in);
+    if (avl_def_out)
+      sbitmap_vector_free (avl_def_out);
+
+    if (vsetvl_def_in)
+      sbitmap_vector_free (vsetvl_def_in);
+    if (vsetvl_def_out)
+      sbitmap_vector_free (vsetvl_def_out);
+
+    if (avloc)
+      sbitmap_vector_free (avloc);
+    if (kill)
+      sbitmap_vector_free (kill);
+    if (antloc)
+      sbitmap_vector_free (antloc);
+    if (transp)
+      sbitmap_vector_free (transp);
+    if (insert)
+      sbitmap_vector_free (insert);
+    if (del)
+      sbitmap_vector_free (del);
+    if (avin)
+      sbitmap_vector_free (avin);
+    if (avout)
+      sbitmap_vector_free (avout);
+
+    if (edges)
+      free_edge_list (edges);
+  }
 
-      fprintf (file, "<AVOUT>=");
-      if (vector_avout == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_avout[cfg_bb->index]);
+  void compute_avl_def_data ();
+  void compute_vsetvl_def_data ();
+  void compute_vsetvl_lcm_data ();
 
-      fprintf (file, "<DELETE>=");
-      if (vector_del == nullptr)
- fprintf (file, "(nil)\n");
-      else
- dump_bitmap_file (file, vector_del[cfg_bb->index]);
-    }
+  void fuse_local_vsetvl_info ();
+  bool earliest_fuse_vsetvl_info ();
+  void pre_global_vsetvl_info ();
+  void emit_vsetvl ();
+  void cleaup ();
+  void remove_avl_operand ();
+  void remove_unused_dest_operand ();
 
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    {
-      for (int ed = 0; ed < NUM_EDGES (vector_edge_list); ed++)
- {
-   edge eg = INDEX_EDGE (vector_edge_list, ed);
-   if (vector_insert)
-     {
-       if (bitmap_bit_p (vector_insert[ed], i))
- {
-   fprintf (file,
-    "\nGlobal LCM (Lazy code motion) INSERT info:\n");
-   fprintf (file,
-    "INSERT edge %d from <bb %d> to <bb %d> for VSETVL "
-    "expr[%ld]\n",
-    ed, eg->src->index, eg->dest->index, i);
- }
-     }
-   else
-     {
-       if (bitmap_bit_p (vector_earliest[ed], i))
- {
-   fprintf (file,
-    "\nGlobal LCM (Lazy code motion) EARLIEST info:\n");
-   fprintf (
-     file,
-     "EARLIEST edge %d from <bb %d> to <bb %d> for VSETVL "
-     "expr[%ld]\n",
-     ed, eg->src->index, eg->dest->index, i);
- }
-     }
- }
-    }
-}
+  void dump (FILE *file, const char *title) const
+  {
+    fprintf (file, "\nVSETVL infos after %s\n\n", title);
+    for (const bb_info *bb : crtl->ssa->bbs ())
+      {
+ const auto &block_info = vector_block_infos[bb->index ()];
+ fprintf (file, "  bb %d:\n", bb->index ());
+ fprintf (file, "    probability: ");
+ block_info.probability.dump (file);
+ fprintf (file, "\n");
+ if (!block_info.empty_p ())
+   {
+     fprintf (file, "    Header vsetvl info:");
+     block_info.get_header_info ().dump (file, "      ");
+     fprintf (file, "    Footer vsetvl info:");
+     block_info.get_footer_info ().dump (file, "      ");
+     for (const auto &info : block_info.infos)
+       {
+ fprintf (file,
+ "    insn %d vsetvl info:", info.get_insn ()->uid ());
+ info.dump (file, "      ");
+       }
+   }
+      }
+  }
+};
 
const pass_data pass_data_vsetvl = {
   RTL_PASS, /* type */
diff --git a/gcc/config/riscv/riscv-vsetvl.h b/gcc/config/riscv/riscv-vsetvl.h
index 542b2aea625..96e36403af7 100644
--- a/gcc/config/riscv/riscv-vsetvl.h
+++ b/gcc/config/riscv/riscv-vsetvl.h
@@ -69,80 +69,5 @@ struct vector_block_info
   vector_block_info () = default;
};
 
-class vector_infos_manager
-{
-public:
-  auto_vec<vector_insn_info> vector_insn_infos;
-  auto_vec<vector_block_info> vector_block_infos;
-  auto_vec<vector_insn_info *> vector_exprs;
-  hash_set<rtx_insn *> to_refine_vsetvls;
-  hash_set<rtx_insn *> to_delete_vsetvls;
-
-  struct edge_list *vector_edge_list;
-  sbitmap *vector_kill;
-  sbitmap *vector_del;
-  sbitmap *vector_insert;
-  sbitmap *vector_antic;
-  sbitmap *vector_transp;
-  sbitmap *vector_comp;
-  sbitmap *vector_avin;
-  sbitmap *vector_avout;
-  sbitmap *vector_antin;
-  sbitmap *vector_antout;
-  sbitmap *vector_earliest;
-
-  vector_infos_manager ();
-
-  /* Create a new expr in expr list if it is not exist.  */
-  void create_expr (vector_insn_info &);
-
-  /* Get the expr id of the pair of expr.  */
-  size_t get_expr_id (const vector_insn_info &) const;
-
-  /* Return the number of expr that is set in the bitmap.  */
-  size_t expr_set_num (sbitmap) const;
-
-  /* Get all relaxer expression id for corresponding vector info.  */
-  auto_vec<size_t> get_all_available_exprs (const vector_insn_info &) const;
-
-  /* Return true if all expression set in bitmap are same AVL.  */
-  bool all_same_avl_p (const basic_block, sbitmap) const;
-
-  /* Return true if all expression set in bitmap are same ratio.  */
-  bool all_same_ratio_p (sbitmap) const;
-
-  bool all_avail_in_compatible_p (const basic_block) const;
-  bool earliest_fusion_worthwhile_p (const basic_block) const;
-  bool vsetvl_dominated_by_all_preds_p (const basic_block,
- const vector_insn_info &) const;
-
-  bool to_delete_p (rtx_insn *rinsn)
-  {
-    if (to_delete_vsetvls.contains (rinsn))
-      {
- to_delete_vsetvls.remove (rinsn);
- if (to_refine_vsetvls.contains (rinsn))
-   to_refine_vsetvls.remove (rinsn);
- return true;
-      }
-    return false;
-  }
-  bool to_refine_p (rtx_insn *rinsn)
-  {
-    if (to_refine_vsetvls.contains (rinsn))
-      {
- to_refine_vsetvls.remove (rinsn);
- return true;
-      }
-    return false;
-  }
-
-  void release (void);
-  void create_bitmap_vectors (void);
-  void free_bitmap_vectors (void);
-
-  void dump (FILE *) const;
-};
-
} // namespace riscv_vector
#endif
--
2.36.3
  

Patch

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index be40b6fdf4c..c219ad178bb 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -2390,402 +2390,284 @@  public:
   }
 };

-vector_infos_manager::vector_infos_manager ()
+class pre_vsetvl
 {
-  vector_edge_list = nullptr;
-  vector_kill = nullptr;
-  vector_del = nullptr;
-  vector_insert = nullptr;
-  vector_antic = nullptr;
-  vector_transp = nullptr;
-  vector_comp = nullptr;
-  vector_avin = nullptr;
-  vector_avout = nullptr;
-  vector_antin = nullptr;
-  vector_antout = nullptr;
-  vector_earliest = nullptr;
-  vector_insn_infos.safe_grow_cleared (get_max_uid ());
-  vector_block_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
-  if (!optimize)
-    {
-      basic_block cfg_bb;
-      rtx_insn *rinsn;
-      FOR_ALL_BB_FN (cfg_bb, cfun)
-	{
-	  vector_block_infos[cfg_bb->index].local_dem = vector_insn_info ();
-	  vector_block_infos[cfg_bb->index].reaching_out = vector_insn_info ();
-	  FOR_BB_INSNS (cfg_bb, rinsn)
-	    vector_insn_infos[INSN_UID (rinsn)].parse_insn (rinsn);
-	}
-    }
-  else
-    {
-      for (const bb_info *bb : crtl->ssa->bbs ())
-	{
-	  vector_block_infos[bb->index ()].local_dem = vector_insn_info ();
-	  vector_block_infos[bb->index ()].reaching_out = vector_insn_info ();
-	  for (insn_info *insn : bb->real_insns ())
-	    vector_insn_infos[insn->uid ()].parse_insn (insn);
-	  vector_block_infos[bb->index ()].probability = profile_probability ();
-	}
-    }
-}
-
-void
-vector_infos_manager::create_expr (vector_insn_info &info)
-{
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (*vector_exprs[i] == info)
-      return;
-  vector_exprs.safe_push (&info);
-}
-
-size_t
-vector_infos_manager::get_expr_id (const vector_insn_info &info) const
-{
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (*vector_exprs[i] == info)
-      return i;
-  gcc_unreachable ();
-}
-
-auto_vec<size_t>
-vector_infos_manager::get_all_available_exprs (
-  const vector_insn_info &info) const
-{
-  auto_vec<size_t> available_list;
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (info.available_p (*vector_exprs[i]))
-      available_list.safe_push (i);
-  return available_list;
-}
-
-bool
-vector_infos_manager::all_same_ratio_p (sbitmap bitdata) const
-{
-  if (bitmap_empty_p (bitdata))
-    return false;
-
-  int ratio = -1;
-  unsigned int bb_index;
-  sbitmap_iterator sbi;
-
-  EXECUTE_IF_SET_IN_BITMAP (bitdata, 0, bb_index, sbi)
-    {
-      if (ratio == -1)
-	ratio = vector_exprs[bb_index]->get_ratio ();
-      else if (vector_exprs[bb_index]->get_ratio () != ratio)
-	return false;
-    }
-  return true;
-}
-
-/* Return TRUE if the incoming vector configuration state
-   to CFG_BB is compatible with the vector configuration
-   state in CFG_BB, FALSE otherwise.  */
-bool
-vector_infos_manager::all_avail_in_compatible_p (const basic_block cfg_bb) const
-{
-  const auto &info = vector_block_infos[cfg_bb->index].local_dem;
-  sbitmap avin = vector_avin[cfg_bb->index];
-  unsigned int bb_index;
-  sbitmap_iterator sbi;
-  EXECUTE_IF_SET_IN_BITMAP (avin, 0, bb_index, sbi)
-    {
-      const auto &avin_info
-	= static_cast<const vl_vtype_info &> (*vector_exprs[bb_index]);
-      if (!info.compatible_p (avin_info))
-	return false;
-    }
-  return true;
-}
-
-bool
-vector_infos_manager::all_same_avl_p (const basic_block cfg_bb,
-				      sbitmap bitdata) const
-{
-  if (bitmap_empty_p (bitdata))
-    return false;
-
-  const auto &block_info = vector_block_infos[cfg_bb->index];
-  if (!block_info.local_dem.demand_p (DEMAND_AVL))
-    return true;
-
-  avl_info avl = block_info.local_dem.get_avl_info ();
-  unsigned int bb_index;
-  sbitmap_iterator sbi;
-
-  EXECUTE_IF_SET_IN_BITMAP (bitdata, 0, bb_index, sbi)
-    {
-      if (vector_exprs[bb_index]->get_avl_info () != avl)
-	return false;
-    }
-  return true;
-}
+private:
+  demand_system dem;
+  auto_vec<vsetvl_block_info> vector_block_infos;
+
+  /* data for avl reaching defintion.  */
+  sbitmap avl_regs;
+  sbitmap *avl_def_in;
+  sbitmap *avl_def_out;
+  sbitmap *reg_def_loc;
+
+  /* data for vsetvl info reaching defintion.  */
+  vsetvl_info unknow_info;
+  auto_vec<vsetvl_info *> vsetvl_def_exprs;
+  sbitmap *vsetvl_def_in;
+  sbitmap *vsetvl_def_out;
+
+  /* data for lcm */
+  auto_vec<vsetvl_info *> exprs;
+  sbitmap *avloc;
+  sbitmap *avin;
+  sbitmap *avout;
+  sbitmap *kill;
+  sbitmap *antloc;
+  sbitmap *transp;
+  sbitmap *insert;
+  sbitmap *del;
+  struct edge_list *edges;
+
+  auto_vec<vsetvl_info> delete_list;
+
+  vsetvl_block_info &get_block_info (const bb_info *bb)
+  {
+    return vector_block_infos[bb->index ()];
+  }
+  const vsetvl_block_info &get_block_info (const basic_block bb) const
+  {
+    return vector_block_infos[bb->index];
+  }

-bool
-vector_infos_manager::earliest_fusion_worthwhile_p (
-  const basic_block cfg_bb) const
-{
-  edge e;
-  edge_iterator ei;
-  profile_probability prob = profile_probability::uninitialized ();
-  FOR_EACH_EDGE (e, ei, cfg_bb->succs)
-    {
-      if (prob == profile_probability::uninitialized ())
-	prob = vector_block_infos[e->dest->index].probability;
-      else if (prob == vector_block_infos[e->dest->index].probability)
-	continue;
-      else
-	/* We pick the highest probability among those incompatible VSETVL
-	   infos. When all incompatible VSTEVL infos have same probability, we
-	   don't pick any of them.  */
-	return true;
-    }
-  return false;
-}
+  vsetvl_block_info &get_block_info (const basic_block bb)
+  {
+    return vector_block_infos[bb->index];
+  }

-bool
-vector_infos_manager::vsetvl_dominated_by_all_preds_p (
-  const basic_block cfg_bb, const vector_insn_info &info) const
-{
-  edge e;
-  edge_iterator ei;
-  FOR_EACH_EDGE (e, ei, cfg_bb->preds)
-    {
-      const auto &reaching_out = vector_block_infos[e->src->index].reaching_out;
-      if (e->src->index == cfg_bb->index && reaching_out.compatible_p (info))
-	continue;
-      if (!vsetvl_dominated_by_p (e->src, info, reaching_out, false))
-	return false;
-    }
-  return true;
-}
+  void add_expr (auto_vec<vsetvl_info *> &exprs, vsetvl_info &info)
+  {
+    for (vsetvl_info *item : exprs)
+      {
+	if (*item == info)
+	  return;
+      }
+    exprs.safe_push (&info);
+  }

-size_t
-vector_infos_manager::expr_set_num (sbitmap bitdata) const
-{
-  size_t count = 0;
-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    if (bitmap_bit_p (bitdata, i))
-      count++;
-  return count;
-}
+  unsigned get_expr_index (auto_vec<vsetvl_info *> &exprs,
+			   const vsetvl_info &info)
+  {
+    for (size_t i = 0; i < exprs.length (); i += 1)
+      {
+	if (*exprs[i] == info)
+	  return i;
+      }
+    gcc_unreachable ();
+  }

-void
-vector_infos_manager::release (void)
-{
-  if (!vector_insn_infos.is_empty ())
-    vector_insn_infos.release ();
-  if (!vector_block_infos.is_empty ())
-    vector_block_infos.release ();
-  if (!vector_exprs.is_empty ())
-    vector_exprs.release ();
-
-  gcc_assert (to_refine_vsetvls.is_empty ());
-  gcc_assert (to_delete_vsetvls.is_empty ());
-  if (optimize > 0)
-    free_bitmap_vectors ();
-}
+  bool anticpatable_exp_p (const vsetvl_info &header_info)
+  {
+    if (!header_info.has_reg_avl () && !header_info.has_reg_vl ())
+      return true;

-void
-vector_infos_manager::create_bitmap_vectors (void)
-{
-  /* Create the bitmap vectors.  */
-  vector_antic = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-				       vector_exprs.length ());
-  vector_transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-					vector_exprs.length ());
-  vector_comp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-				      vector_exprs.length ());
-  vector_avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-				      vector_exprs.length ());
-  vector_avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-				       vector_exprs.length ());
-  vector_kill = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-				      vector_exprs.length ());
-  vector_antin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-				       vector_exprs.length ());
-  vector_antout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
-					vector_exprs.length ());
-
-  bitmap_vector_ones (vector_transp, last_basic_block_for_fn (cfun));
-  bitmap_vector_clear (vector_antic, last_basic_block_for_fn (cfun));
-  bitmap_vector_clear (vector_comp, last_basic_block_for_fn (cfun));
-  vector_edge_list = create_edge_list ();
-  vector_earliest = sbitmap_vector_alloc (NUM_EDGES (vector_edge_list),
-					  vector_exprs.length ());
-}
+    bb_info *bb = header_info.get_bb ();
+    insn_info *prev_insn = bb->head_insn ();
+    insn_info *next_insn = header_info.get_insn ();
+    if (bb != next_insn->bb ())
+      next_insn = bb->end_insn ();

-void
-vector_infos_manager::free_bitmap_vectors (void)
-{
-  /* Finished. Free up all the things we've allocated.  */
-  free_edge_list (vector_edge_list);
-  if (vector_del)
-    sbitmap_vector_free (vector_del);
-  if (vector_insert)
-    sbitmap_vector_free (vector_insert);
-  if (vector_kill)
-    sbitmap_vector_free (vector_kill);
-  if (vector_antic)
-    sbitmap_vector_free (vector_antic);
-  if (vector_transp)
-    sbitmap_vector_free (vector_transp);
-  if (vector_comp)
-    sbitmap_vector_free (vector_comp);
-  if (vector_avin)
-    sbitmap_vector_free (vector_avin);
-  if (vector_avout)
-    sbitmap_vector_free (vector_avout);
-  if (vector_antin)
-    sbitmap_vector_free (vector_antin);
-  if (vector_antout)
-    sbitmap_vector_free (vector_antout);
-  if (vector_earliest)
-    sbitmap_vector_free (vector_earliest);
-
-  vector_edge_list = nullptr;
-  vector_kill = nullptr;
-  vector_del = nullptr;
-  vector_insert = nullptr;
-  vector_antic = nullptr;
-  vector_transp = nullptr;
-  vector_comp = nullptr;
-  vector_avin = nullptr;
-  vector_avout = nullptr;
-  vector_antin = nullptr;
-  vector_antout = nullptr;
-  vector_earliest = nullptr;
-}
+    return dem.safe_move_avl_vl_p (prev_insn, next_insn, header_info);
+  }

-void
-vector_infos_manager::dump (FILE *file) const
-{
-  basic_block cfg_bb;
-  rtx_insn *rinsn;
+  bool available_exp_p (const vsetvl_info &prev_info,
+			const vsetvl_info &next_info)
+  {
+    return dem.available_with (prev_info, next_info);
+  }

-  fprintf (file, "\n");
-  FOR_ALL_BB_FN (cfg_bb, cfun)
-    {
-      fprintf (file, "Local vector info of <bb %d>:\n", cfg_bb->index);
-      fprintf (file, "<HEADER>=");
-      vector_block_infos[cfg_bb->index].local_dem.dump (file);
-      FOR_BB_INSNS (cfg_bb, rinsn)
-	{
-	  if (!NONDEBUG_INSN_P (rinsn) || !has_vtype_op (rinsn))
-	    continue;
-	  fprintf (file, "<insn %d>=", INSN_UID (rinsn));
-	  const auto &info = vector_insn_infos[INSN_UID (rinsn)];
-	  info.dump (file);
-	}
-      fprintf (file, "<FOOTER>=");
-      vector_block_infos[cfg_bb->index].reaching_out.dump (file);
-      fprintf (file, "<Probability>=");
-      vector_block_infos[cfg_bb->index].probability.dump (file);
-      fprintf (file, "\n\n");
-    }
+  void compute_probabilities ()
+  {
+    edge e;
+    edge_iterator ei;

-  fprintf (file, "\n");
-  FOR_ALL_BB_FN (cfg_bb, cfun)
-    {
-      fprintf (file, "Local properties of <bb %d>:\n", cfg_bb->index);
+    for (const bb_info *bb : crtl->ssa->bbs ())
+      {
+	basic_block cfg_bb = bb->cfg_bb ();
+	auto &curr_prob = get_block_info (cfg_bb).probability;
+
+	/* GCC assume entry block (bb 0) are always so
+	   executed so set its probability as "always".  */
+	if (ENTRY_BLOCK_PTR_FOR_FN (cfun) == cfg_bb)
+	  curr_prob = profile_probability::always ();
+	/* Exit block (bb 1) is the block we don't need to process.  */
+	if (EXIT_BLOCK_PTR_FOR_FN (cfun) == cfg_bb)
+	  continue;

-      fprintf (file, "<ANTLOC>=");
-      if (vector_antic == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_antic[cfg_bb->index]);
+	gcc_assert (curr_prob.initialized_p ());
+	FOR_EACH_EDGE (e, ei, cfg_bb->succs)
+	  {
+	    auto &new_prob = get_block_info (e->dest).probability;
+	    /* Normally, the edge probability should be initialized.
+	       However, some special testing code which is written in
+	       GIMPLE IR style force the edge probility uninitialized,
+	       we conservatively set it as never so that it will not
+	       affect PRE (Phase 3 && Phse 4).  */
+	    if (!e->probability.initialized_p ())
+	      new_prob = profile_probability::never ();
+	    else if (!new_prob.initialized_p ())
+	      new_prob = curr_prob * e->probability;
+	    else if (new_prob == profile_probability::always ())
+	      continue;
+	    else
+	      new_prob += curr_prob * e->probability;
+	  }
+      }
+  }

-      fprintf (file, "<AVLOC>=");
-      if (vector_comp == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_comp[cfg_bb->index]);
+  void insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
+		      const vsetvl_info &info)
+  {
+    if (info.change_vtype_only_p ())
+      emit_vsetvl_insn (VSETVL_VTYPE_CHANGE_ONLY, emit_type, info, NULL_RTX,
+			rinsn);

-      fprintf (file, "<TRANSP>=");
-      if (vector_transp == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_transp[cfg_bb->index]);
+    else if (info.has_reg_vl ())
+      emit_vsetvl_insn (VSETVL_NORMAL, emit_type, info, info.get_vl (), rinsn);
+    else
+      emit_vsetvl_insn (VSETVL_DISCARD_RESULT, emit_type, info, NULL_RTX,
+			rinsn);
+  }

-      fprintf (file, "<KILL>=");
-      if (vector_kill == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_kill[cfg_bb->index]);
+  bool earliest_fusion_worthwhile_p (const basic_block cfg_bb) const
+  {
+    edge e;
+    edge_iterator ei;
+    profile_probability prob = profile_probability::uninitialized ();
+    FOR_EACH_EDGE (e, ei, cfg_bb->succs)
+      {
+	if (prob == profile_probability::uninitialized ())
+	  prob = vector_block_infos[e->dest->index].probability;
+	else if (prob == vector_block_infos[e->dest->index].probability)
+	  continue;
+	else
+	  /* We pick the highest probability among those incompatible VSETVL
+	     infos. When all incompatible VSTEVL infos have same probability, we
+	     don't pick any of them.  */
+	  return true;
+      }
+    return false;
+  }

-      fprintf (file, "<ANTIN>=");
-      if (vector_antin == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_antin[cfg_bb->index]);
+  bool preds_has_same_avl_p (const vsetvl_info &curr_info)
+  {
+    if (bitmap_empty_p (avin[curr_info.get_bb ()->index ()]))
+      return false;

-      fprintf (file, "<ANTOUT>=");
-      if (vector_antout == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_antout[cfg_bb->index]);
-    }
+    unsigned expr_index;
+    sbitmap_iterator sbi;
+    EXECUTE_IF_SET_IN_BITMAP (avin[curr_info.get_bb ()->index ()], 0,
+			      expr_index, sbi)
+      {
+	const vsetvl_info &prev_info = *exprs[expr_index];
+	if (!prev_info.valid_p ()
+	    || !dem.available_avl_with (prev_info, curr_info))
+	  return false;
+      }
+    return true;
+  }

-  fprintf (file, "\n");
-  FOR_ALL_BB_FN (cfg_bb, cfun)
-    {
-      fprintf (file, "Global LCM (Lazy code motion) result of <bb %d>:\n",
-	       cfg_bb->index);
+public:
+  pre_vsetvl ()
+    : avl_def_in (nullptr), avl_def_out (nullptr), vsetvl_def_in (nullptr),
+      vsetvl_def_out (nullptr), avloc (nullptr), avin (nullptr),
+      avout (nullptr), kill (nullptr), antloc (nullptr), transp (nullptr),
+      insert (nullptr), del (nullptr), edges (nullptr)
+  {
+    /* Initialization of RTL_SSA.  */
+    calculate_dominance_info (CDI_DOMINATORS);
+    calculate_dominance_info (CDI_POST_DOMINATORS);
+    df_analyze ();
+    crtl->ssa = new function_info (cfun);
+    vector_block_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
+    compute_probabilities ();
+    unknow_info.set_unknown ();
+  }

-      fprintf (file, "<AVIN>=");
-      if (vector_avin == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_avin[cfg_bb->index]);
+  void finish ()
+  {
+    free_dominance_info (CDI_DOMINATORS);
+    free_dominance_info (CDI_POST_DOMINATORS);
+    if (crtl->ssa->perform_pending_updates ())
+      cleanup_cfg (0);
+    delete crtl->ssa;
+    crtl->ssa = nullptr;
+
+    if (avl_regs)
+      sbitmap_free (avl_regs);
+    if (reg_def_loc)
+      sbitmap_vector_free (reg_def_loc);
+
+    if (avl_def_in)
+      sbitmap_vector_free (avl_def_in);
+    if (avl_def_out)
+      sbitmap_vector_free (avl_def_out);
+
+    if (vsetvl_def_in)
+      sbitmap_vector_free (vsetvl_def_in);
+    if (vsetvl_def_out)
+      sbitmap_vector_free (vsetvl_def_out);
+
+    if (avloc)
+      sbitmap_vector_free (avloc);
+    if (kill)
+      sbitmap_vector_free (kill);
+    if (antloc)
+      sbitmap_vector_free (antloc);
+    if (transp)
+      sbitmap_vector_free (transp);
+    if (insert)
+      sbitmap_vector_free (insert);
+    if (del)
+      sbitmap_vector_free (del);
+    if (avin)
+      sbitmap_vector_free (avin);
+    if (avout)
+      sbitmap_vector_free (avout);
+
+    if (edges)
+      free_edge_list (edges);
+  }

-      fprintf (file, "<AVOUT>=");
-      if (vector_avout == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_avout[cfg_bb->index]);
+  void compute_avl_def_data ();
+  void compute_vsetvl_def_data ();
+  void compute_vsetvl_lcm_data ();

-      fprintf (file, "<DELETE>=");
-      if (vector_del == nullptr)
-	fprintf (file, "(nil)\n");
-      else
-	dump_bitmap_file (file, vector_del[cfg_bb->index]);
-    }
+  void fuse_local_vsetvl_info ();
+  bool earliest_fuse_vsetvl_info ();
+  void pre_global_vsetvl_info ();
+  void emit_vsetvl ();
+  void cleaup ();
+  void remove_avl_operand ();
+  void remove_unused_dest_operand ();

-  for (size_t i = 0; i < vector_exprs.length (); i++)
-    {
-      for (int ed = 0; ed < NUM_EDGES (vector_edge_list); ed++)
-	{
-	  edge eg = INDEX_EDGE (vector_edge_list, ed);
-	  if (vector_insert)
-	    {
-	      if (bitmap_bit_p (vector_insert[ed], i))
-		{
-		  fprintf (file,
-			   "\nGlobal LCM (Lazy code motion) INSERT info:\n");
-		  fprintf (file,
-			   "INSERT edge %d from <bb %d> to <bb %d> for VSETVL "
-			   "expr[%ld]\n",
-			   ed, eg->src->index, eg->dest->index, i);
-		}
-	    }
-	  else
-	    {
-	      if (bitmap_bit_p (vector_earliest[ed], i))
-		{
-		  fprintf (file,
-			   "\nGlobal LCM (Lazy code motion) EARLIEST info:\n");
-		  fprintf (
-		    file,
-		    "EARLIEST edge %d from <bb %d> to <bb %d> for VSETVL "
-		    "expr[%ld]\n",
-		    ed, eg->src->index, eg->dest->index, i);
-		}
-	    }
-	}
-    }
-}
+  void dump (FILE *file, const char *title) const
+  {
+    fprintf (file, "\nVSETVL infos after %s\n\n", title);
+    for (const bb_info *bb : crtl->ssa->bbs ())
+      {
+	const auto &block_info = vector_block_infos[bb->index ()];
+	fprintf (file, "  bb %d:\n", bb->index ());
+	fprintf (file, "    probability: ");
+	block_info.probability.dump (file);
+	fprintf (file, "\n");
+	if (!block_info.empty_p ())
+	  {
+	    fprintf (file, "    Header vsetvl info:");
+	    block_info.get_header_info ().dump (file, "      ");
+	    fprintf (file, "    Footer vsetvl info:");
+	    block_info.get_footer_info ().dump (file, "      ");
+	    for (const auto &info : block_info.infos)
+	      {
+		fprintf (file,
+			 "    insn %d vsetvl info:", info.get_insn ()->uid ());
+		info.dump (file, "      ");
+	      }
+	  }
+      }
+  }
+};

 const pass_data pass_data_vsetvl = {
   RTL_PASS,	 /* type */
diff --git a/gcc/config/riscv/riscv-vsetvl.h b/gcc/config/riscv/riscv-vsetvl.h
index 542b2aea625..96e36403af7 100644
--- a/gcc/config/riscv/riscv-vsetvl.h
+++ b/gcc/config/riscv/riscv-vsetvl.h
@@ -69,80 +69,5 @@  struct vector_block_info
   vector_block_info () = default;
 };

-class vector_infos_manager
-{
-public:
-  auto_vec<vector_insn_info> vector_insn_infos;
-  auto_vec<vector_block_info> vector_block_infos;
-  auto_vec<vector_insn_info *> vector_exprs;
-  hash_set<rtx_insn *> to_refine_vsetvls;
-  hash_set<rtx_insn *> to_delete_vsetvls;
-
-  struct edge_list *vector_edge_list;
-  sbitmap *vector_kill;
-  sbitmap *vector_del;
-  sbitmap *vector_insert;
-  sbitmap *vector_antic;
-  sbitmap *vector_transp;
-  sbitmap *vector_comp;
-  sbitmap *vector_avin;
-  sbitmap *vector_avout;
-  sbitmap *vector_antin;
-  sbitmap *vector_antout;
-  sbitmap *vector_earliest;
-
-  vector_infos_manager ();
-
-  /* Create a new expr in expr list if it is not exist.  */
-  void create_expr (vector_insn_info &);
-
-  /* Get the expr id of the pair of expr.  */
-  size_t get_expr_id (const vector_insn_info &) const;
-
-  /* Return the number of expr that is set in the bitmap.  */
-  size_t expr_set_num (sbitmap) const;
-
-  /* Get all relaxer expression id for corresponding vector info.  */
-  auto_vec<size_t> get_all_available_exprs (const vector_insn_info &) const;
-
-  /* Return true if all expression set in bitmap are same AVL.  */
-  bool all_same_avl_p (const basic_block, sbitmap) const;
-
-  /* Return true if all expression set in bitmap are same ratio.  */
-  bool all_same_ratio_p (sbitmap) const;
-
-  bool all_avail_in_compatible_p (const basic_block) const;
-  bool earliest_fusion_worthwhile_p (const basic_block) const;
-  bool vsetvl_dominated_by_all_preds_p (const basic_block,
-					const vector_insn_info &) const;
-
-  bool to_delete_p (rtx_insn *rinsn)
-  {
-    if (to_delete_vsetvls.contains (rinsn))
-      {
-	to_delete_vsetvls.remove (rinsn);
-	if (to_refine_vsetvls.contains (rinsn))
-	  to_refine_vsetvls.remove (rinsn);
-	return true;
-      }
-    return false;
-  }
-  bool to_refine_p (rtx_insn *rinsn)
-  {
-    if (to_refine_vsetvls.contains (rinsn))
-      {
-	to_refine_vsetvls.remove (rinsn);
-	return true;
-      }
-    return false;
-  }
-
-  void release (void);
-  void create_bitmap_vectors (void);
-  void free_bitmap_vectors (void);
-
-  void dump (FILE *) const;
-};
-
 } // namespace riscv_vector
 #endif