[V2,03/14] RISC-V: P3: Refactor vector_infos_manager
Checks
Commit Message
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
+ 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
@@ -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 */
@@ -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