[V2,13/14] RISC-V: P13: Reorganize functions used to modify RTL
Checks
Commit Message
This sub-patch reoriganize the functions that used to modify RTL.
gcc/ChangeLog:
* config/riscv/riscv-vsetvl.cc (has_no_uses): Moved.
(validate_change_or_fail): Moved.
(gen_vsetvl_pat): Removed.
(emit_vsetvl_insn): Removed.
(eliminate_insn): Removed.
(change_insn): Removed.
(change_vsetvl_insn): New.
(pre_vsetvl::emit_vsetvl): New.
(pre_vsetvl::remove_avl_operand): Adjust.
(pre_vsetvl::remove_unused_dest_operand): Adjust.
(pass_vsetvl::simple_vsetvl): Adjust.
---
gcc/config/riscv/riscv-vsetvl.cc | 443 ++++++++++++-------------------
1 file changed, 176 insertions(+), 267 deletions(-)
--
2.36.3
Comments
OK
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 13/14] RISC-V: P13: Reorganize functions used to modify RTL
This sub-patch reoriganize the functions that used to modify RTL.
gcc/ChangeLog:
* config/riscv/riscv-vsetvl.cc (has_no_uses): Moved.
(validate_change_or_fail): Moved.
(gen_vsetvl_pat): Removed.
(emit_vsetvl_insn): Removed.
(eliminate_insn): Removed.
(change_insn): Removed.
(change_vsetvl_insn): New.
(pre_vsetvl::emit_vsetvl): New.
(pre_vsetvl::remove_avl_operand): Adjust.
(pre_vsetvl::remove_unused_dest_operand): Adjust.
(pass_vsetvl::simple_vsetvl): Adjust.
---
gcc/config/riscv/riscv-vsetvl.cc | 443 ++++++++++++-------------------
1 file changed, 176 insertions(+), 267 deletions(-)
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index d91b0272d9f..78816cbee15 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -680,6 +680,30 @@ get_bb_index (unsigned expr_id, unsigned num_bb)
return expr_id % num_bb;
}
+/* Return true if the SET result is not used by any instructions. */
+static bool
+has_no_uses (basic_block cfg_bb, rtx_insn *rinsn, int regno)
+{
+ if (bitmap_bit_p (df_get_live_out (cfg_bb), regno))
+ return false;
+
+ rtx_insn *iter;
+ for (iter = NEXT_INSN (rinsn); iter && iter != NEXT_INSN (BB_END (cfg_bb));
+ iter = NEXT_INSN (iter))
+ if (df_find_use (iter, regno_reg_rtx[regno]))
+ return false;
+
+ return true;
+}
+
+/* Change insn and Assert the change always happens. */
+static void
+validate_change_or_fail (rtx object, rtx *loc, rtx new_rtx, bool in_group)
+{
+ bool change_p = validate_change (object, loc, new_rtx, in_group);
+ gcc_assert (change_p);
+}
+
/* This flags indicates the minimum demand of the vl and vtype values by the
RVV instruction. For example, DEMAND_RATIO_P indicates that this RVV
instruction only needs the SEW/LMUL ratio to remain the same, and does not
@@ -1126,6 +1150,28 @@ public:
}
}
+ /* Returns the corresponding vsetvl rtx pat. */
+ rtx get_vsetvl_pat (bool ignore_vl = false) const
+ {
+ rtx avl = get_avl ();
+ /* if optimization == 0 and the instruction is vmv.x.s/vfmv.f.s,
+ set the value of avl to (const_int 0) so that VSETVL PASS will
+ insert vsetvl correctly.*/
+ if (!get_avl ())
+ avl = GEN_INT (0);
+ rtx sew = gen_int_mode (get_sew (), Pmode);
+ rtx vlmul = gen_int_mode (get_vlmul (), Pmode);
+ rtx ta = gen_int_mode (get_ta (), Pmode);
+ rtx ma = gen_int_mode (get_ma (), Pmode);
+
+ if (change_vtype_only_p ())
+ return gen_vsetvl_vtype_change_only (sew, vlmul, ta, ma);
+ else if (has_reg_vl () && !ignore_vl)
+ return gen_vsetvl (Pmode, get_vl (), avl, sew, vlmul, ta, ma);
+ else
+ return gen_vsetvl_discard_result (Pmode, avl, sew, vlmul, ta, ma);
+ }
+
bool operator== (const vsetvl_info &other) const
{
gcc_assert (!uninit_p () && !other.uninit_p ()
@@ -1938,199 +1984,6 @@ public:
}
};
-/* Emit vsetvl instruction. */
-static rtx
-gen_vsetvl_pat (enum vsetvl_type insn_type, const vsetvl_info &info, rtx vl)
-{
- rtx avl = info.get_avl ();
- /* if optimization == 0 and the instruction is vmv.x.s/vfmv.f.s,
- set the value of avl to (const_int 0) so that VSETVL PASS will
- insert vsetvl correctly.*/
- if (!info.get_avl ())
- avl = GEN_INT (0);
- rtx sew = gen_int_mode (info.get_sew (), Pmode);
- rtx vlmul = gen_int_mode (info.get_vlmul (), Pmode);
- rtx ta = gen_int_mode (info.get_ta (), Pmode);
- rtx ma = gen_int_mode (info.get_ma (), Pmode);
-
- if (insn_type == VSETVL_NORMAL)
- {
- gcc_assert (vl != NULL_RTX);
- return gen_vsetvl (Pmode, vl, avl, sew, vlmul, ta, ma);
- }
- else if (insn_type == VSETVL_VTYPE_CHANGE_ONLY)
- return gen_vsetvl_vtype_change_only (sew, vlmul, ta, ma);
- else
- return gen_vsetvl_discard_result (Pmode, avl, sew, vlmul, ta, ma);
-}
-
-static rtx
-gen_vsetvl_pat (rtx_insn *rinsn, const vsetvl_info &info, rtx vl = NULL_RTX)
-{
- rtx new_pat;
- vsetvl_info new_info = info;
- /* For vmv.x.s, use 0 for avl. */
- if (!info.get_avl ())
- {
- new_info.set_avl (const0_rtx);
- new_info.set_avl_def (nullptr);
- }
-
- if (vl)
- new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, vl);
- else
- {
- if (vsetvl_insn_p (rinsn) && !info.change_vtype_only_p ())
- new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, get_vl (rinsn));
- else if (info.change_vtype_only_p ()
- || INSN_CODE (rinsn) == CODE_FOR_vsetvl_vtype_change_only)
- new_pat = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, new_info, NULL_RTX);
- else
- new_pat = gen_vsetvl_pat (VSETVL_DISCARD_RESULT, new_info, NULL_RTX);
- }
- return new_pat;
-}
-
-static void
-emit_vsetvl_insn (enum vsetvl_type insn_type, enum emit_type emit_type,
- const vsetvl_info &info, rtx vl, rtx_insn *rinsn)
-{
- rtx pat = gen_vsetvl_pat (insn_type, info, vl);
-
- if (emit_type == EMIT_DIRECT)
- {
- emit_insn (pat);
- if (dump_file)
- {
- fprintf (dump_file, " Insert vsetvl insn %d:\n",
- INSN_UID (get_last_insn ()));
- print_rtl_single (dump_file, get_last_insn ());
- }
- }
- else if (emit_type == EMIT_BEFORE)
- {
- emit_insn_before (pat, rinsn);
- if (dump_file)
- {
- fprintf (dump_file, " Insert vsetvl insn before insn %d:\n",
- INSN_UID (rinsn));
- print_rtl_single (dump_file, PREV_INSN (rinsn));
- }
- }
- else
- {
- emit_insn_after (pat, rinsn);
- if (dump_file)
- {
- fprintf (dump_file, " Insert vsetvl insn after insn %d:\n",
- INSN_UID (rinsn));
- print_rtl_single (dump_file, NEXT_INSN (rinsn));
- }
- }
-}
-
-static void
-eliminate_insn (rtx_insn *rinsn)
-{
- if (dump_file)
- {
- fprintf (dump_file, " Eliminate insn %d:\n", INSN_UID (rinsn));
- print_rtl_single (dump_file, rinsn);
- }
- if (in_sequence_p ())
- remove_insn (rinsn);
- else
- delete_insn (rinsn);
-}
-
-/* Change insn and Assert the change always happens. */
-static void
-validate_change_or_fail (rtx object, rtx *loc, rtx new_rtx, bool in_group)
-{
- bool change_p = validate_change (object, loc, new_rtx, in_group);
- gcc_assert (change_p);
-}
-
-static void
-change_insn (rtx_insn *rinsn, rtx new_pat)
-{
- /* We don't apply change on RTL_SSA here since it's possible a
- new INSN we add in the PASS before which doesn't have RTL_SSA
- info yet.*/
- if (dump_file)
- {
- fprintf (dump_file, " Change insn %d from:\n", INSN_UID (rinsn));
- print_rtl_single (dump_file, rinsn);
- }
-
- validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false);
-
- if (dump_file)
- {
- fprintf (dump_file, "\n to:\n");
- print_rtl_single (dump_file, rinsn);
- }
-}
-
-static bool
-change_insn (function_info *ssa, insn_change change, insn_info *insn,
- rtx new_pat)
-{
- rtx_insn *rinsn = insn->rtl ();
- auto attempt = ssa->new_change_attempt ();
- if (!restrict_movement (change))
- return false;
-
- if (dump_file)
- {
- fprintf (dump_file, " Change insn %d from:\n", INSN_UID (rinsn));
- print_rtl_single (dump_file, rinsn);
- }
-
- insn_change_watermark watermark;
- validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, true);
-
- /* These routines report failures themselves. */
- if (!recog (attempt, change) || !change_is_worthwhile (change, false))
- return false;
-
- remove_reg_equal_equiv_notes (rinsn);
- confirm_change_group ();
- ssa->change_insn (change);
-
- if (dump_file)
- {
- fprintf (dump_file, "\n to:\n");
- print_rtl_single (dump_file, rinsn);
- }
-
- return true;
-}
-
-static void
-change_vsetvl_insn (const insn_info *insn, const vsetvl_info &info)
-{
- rtx_insn *rinsn = insn->rtl ();
- rtx new_pat = gen_vsetvl_pat (rinsn, info);
- change_insn (rinsn, new_pat);
-}
-
-/* Return true if the SET result is not used by any instructions. */
-static bool
-has_no_uses (basic_block cfg_bb, rtx_insn *rinsn, int regno)
-{
- if (bitmap_bit_p (df_get_live_out (cfg_bb), regno))
- return false;
-
- rtx_insn *iter;
- for (iter = NEXT_INSN (rinsn); iter && iter != NEXT_INSN (BB_END (cfg_bb));
- iter = NEXT_INSN (iter))
- if (df_find_use (iter, regno_reg_rtx[regno]))
- return false;
-
- return true;
-}
-
class pre_vsetvl
{
private:
@@ -2257,18 +2110,75 @@ private:
}
}
- void insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
- const vsetvl_info &info)
+ void insert_vsetvl_insn (enum emit_type emit_type, const vsetvl_info &info)
{
- if (info.change_vtype_only_p ())
- emit_vsetvl_insn (VSETVL_VTYPE_CHANGE_ONLY, emit_type, info, NULL_RTX,
- rinsn);
+ rtx pat = info.get_vsetvl_pat ();
+ rtx_insn *rinsn = info.get_insn ()->rtl ();
- else if (info.has_reg_vl ())
- emit_vsetvl_insn (VSETVL_NORMAL, emit_type, info, info.get_vl (), rinsn);
+ if (emit_type == EMIT_DIRECT)
+ {
+ emit_insn (pat);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn %d:\n",
+ INSN_UID (get_last_insn ()));
+ print_rtl_single (dump_file, get_last_insn ());
+ }
+ }
+ else if (emit_type == EMIT_BEFORE)
+ {
+ emit_insn_before (pat, rinsn);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn before insn %d:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, PREV_INSN (rinsn));
+ }
+ }
else
- emit_vsetvl_insn (VSETVL_DISCARD_RESULT, emit_type, info, NULL_RTX,
- rinsn);
+ {
+ emit_insn_after (pat, rinsn);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn after insn %d:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, NEXT_INSN (rinsn));
+ }
+ }
+ }
+
+ void change_vsetvl_insn (const vsetvl_info &info)
+ {
+ rtx_insn *rinsn = info.get_insn ()->rtl ();
+ rtx new_pat = info.get_vsetvl_pat ();
+
+ if (dump_file)
+ {
+ fprintf (dump_file, " Change insn %d from:\n", INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+
+ validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "\n to:\n");
+ print_rtl_single (dump_file, rinsn);
+ }
+ }
+
+ void remove_vsetvl_insn (const vsetvl_info &info)
+ {
+ rtx_insn *rinsn = info.get_insn ()->rtl ();
+ if (dump_file)
+ {
+ fprintf (dump_file, " Eliminate insn %d:\n", INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+ if (in_sequence_p ())
+ remove_insn (rinsn);
+ else
+ delete_insn (rinsn);
}
bool earliest_fusion_worthwhile_p (const basic_block cfg_bb) const
@@ -3297,7 +3207,7 @@ pre_vsetvl::emit_vsetvl ()
if (curr_info.ignore_p ())
{
if (vsetvl_insn_p (insn->rtl ()))
- eliminate_insn (insn->rtl ());
+ remove_vsetvl_insn (curr_info);
continue;
}
else if (curr_info.valid_p ())
@@ -3314,7 +3224,7 @@ pre_vsetvl::emit_vsetvl ()
fprintf (dump_file, " to: ");
curr_info.dump (dump_file, " ");
}
- change_vsetvl_insn (insn, curr_info);
+ change_vsetvl_insn (curr_info);
}
}
else
@@ -3326,7 +3236,7 @@ pre_vsetvl::emit_vsetvl ()
insn->uid ());
curr_info.dump (dump_file, " ");
}
- insert_vsetvl (EMIT_BEFORE, insn->rtl (), curr_info);
+ insert_vsetvl_insn (EMIT_BEFORE, curr_info);
}
}
}
@@ -3335,7 +3245,7 @@ pre_vsetvl::emit_vsetvl ()
for (const vsetvl_info &item : delete_list)
{
gcc_assert (vsetvl_insn_p (item.get_insn ()->rtl ()));
- eliminate_insn (item.get_insn ()->rtl ());
+ remove_vsetvl_insn (item);
}
/* Insert vsetvl as LCM suggest. */
@@ -3365,8 +3275,7 @@ pre_vsetvl::emit_vsetvl ()
rtl_profile_for_edge (eg);
start_sequence ();
- insn_info *insn = info.get_insn ();
- insert_vsetvl (EMIT_DIRECT, insn->rtl (), info);
+ insert_vsetvl_insn (EMIT_DIRECT, info);
rtx_insn *rinsn = get_insns ();
end_sequence ();
default_rtl_profile ();
@@ -3385,7 +3294,6 @@ pre_vsetvl::emit_vsetvl ()
continue;
const vsetvl_info &footer_info = block_info.get_footer_info ();
- insn_info *insn = footer_info.get_insn ();
if (footer_info.ignore_p ())
continue;
@@ -3404,7 +3312,7 @@ pre_vsetvl::emit_vsetvl ()
footer_info.dump (dump_file, " ");
}
start_sequence ();
- insert_vsetvl (EMIT_DIRECT, insn->rtl (), footer_info);
+ insert_vsetvl_insn (EMIT_DIRECT, footer_info);
rtx_insn *rinsn = get_insns ();
end_sequence ();
default_rtl_profile ();
@@ -3427,71 +3335,66 @@ pre_vsetvl::cleaup ()
void
pre_vsetvl::remove_avl_operand ()
{
- for (const bb_info *bb : crtl->ssa->bbs ())
- for (insn_info *insn : bb->real_nondebug_insns ())
- {
- rtx_insn *rinsn = insn->rtl ();
- /* Erase the AVL operand from the instruction. */
- if (!has_vl_op (rinsn) || !REG_P (get_vl (rinsn)))
- continue;
- rtx avl = get_vl (rinsn);
- if (count_regno_occurrences (rinsn, REGNO (avl)) == 1)
- {
- /* Get the list of uses for the new instruction. */
- auto attempt = crtl->ssa->new_change_attempt ();
- insn_change change (insn);
- /* Remove the use of the substituted value. */
- access_array_builder uses_builder (attempt);
- uses_builder.reserve (insn->num_uses () - 1);
- for (use_info *use : insn->uses ())
- if (use != find_access (insn->uses (), REGNO (avl)))
- uses_builder.quick_push (use);
- use_array new_uses = use_array (uses_builder.finish ());
- change.new_uses = new_uses;
- change.move_range = insn->ebb ()->insn_range ();
- rtx pat;
- if (fault_first_load_p (rinsn))
- pat = simplify_replace_rtx (PATTERN (rinsn), avl, const0_rtx);
- else
- {
- rtx set = single_set (rinsn);
- rtx src = simplify_replace_rtx (SET_SRC (set), avl, const0_rtx);
- pat = gen_rtx_SET (SET_DEST (set), src);
- }
- bool ok = change_insn (crtl->ssa, change, insn, pat);
- gcc_assert (ok);
- }
- }
+ basic_block cfg_bb;
+ rtx_insn *rinsn;
+ FOR_ALL_BB_FN (cfg_bb, cfun)
+ FOR_BB_INSNS (cfg_bb, rinsn)
+ if (NONDEBUG_INSN_P (rinsn) && has_vl_op (rinsn)
+ && REG_P (get_vl (rinsn)))
+ {
+ rtx avl = get_vl (rinsn);
+ if (count_regno_occurrences (rinsn, REGNO (avl)) == 1)
+ {
+ rtx new_pat;
+ if (fault_first_load_p (rinsn))
+ new_pat
+ = simplify_replace_rtx (PATTERN (rinsn), avl, const0_rtx);
+ else
+ {
+ rtx set = single_set (rinsn);
+ rtx src
+ = simplify_replace_rtx (SET_SRC (set), avl, const0_rtx);
+ new_pat = gen_rtx_SET (SET_DEST (set), src);
+ }
+ if (dump_file)
+ {
+ fprintf (dump_file, " Cleanup insn %u's avl operand:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+ validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false);
+ }
+ }
}
void
pre_vsetvl::remove_unused_dest_operand ()
{
df_analyze ();
- hash_set<rtx_insn *> to_delete;
basic_block cfg_bb;
rtx_insn *rinsn;
FOR_ALL_BB_FN (cfg_bb, cfun)
- {
- FOR_BB_INSNS (cfg_bb, rinsn)
+ FOR_BB_INSNS (cfg_bb, rinsn)
+ if (NONDEBUG_INSN_P (rinsn) && vsetvl_insn_p (rinsn))
{
- if (NONDEBUG_INSN_P (rinsn) && vsetvl_insn_p (rinsn))
- {
- rtx vl = get_vl (rinsn);
- vsetvl_info info = vsetvl_info (rinsn);
- if (has_no_uses (cfg_bb, rinsn, REGNO (vl)))
- {
- if (!info.has_vlmax_avl ())
- {
- rtx new_pat = gen_vsetvl_pat (VSETVL_DISCARD_RESULT, info,
- NULL_RTX);
- validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat,
- false);
- }
- }
- }
+ rtx vl = get_vl (rinsn);
+ vsetvl_info info = vsetvl_info (rinsn);
+ if (has_no_uses (cfg_bb, rinsn, REGNO (vl)))
+ if (!info.has_vlmax_avl ())
+ {
+ rtx new_pat = info.get_vsetvl_pat (true);
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ " Remove vsetvl insn %u's dest(vl) operand since "
+ "it unused:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+ validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat,
+ false);
+ }
}
- }
}
const pass_data pass_data_vsetvl = {
@@ -3536,9 +3439,15 @@ pass_vsetvl::simple_vsetvl ()
continue;
if (has_vtype_op (rinsn))
{
- const auto info = vsetvl_info (rinsn);
- emit_vsetvl_insn (VSETVL_DISCARD_RESULT, EMIT_BEFORE, info,
- NULL_RTX, rinsn);
+ const auto &info = vsetvl_info (rinsn);
+ rtx pat = info.get_vsetvl_pat ();
+ emit_insn_before (pat, rinsn);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn before insn %d:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, PREV_INSN (rinsn));
+ }
}
}
}
--
2.36.3
@@ -680,6 +680,30 @@ get_bb_index (unsigned expr_id, unsigned num_bb)
return expr_id % num_bb;
}
+/* Return true if the SET result is not used by any instructions. */
+static bool
+has_no_uses (basic_block cfg_bb, rtx_insn *rinsn, int regno)
+{
+ if (bitmap_bit_p (df_get_live_out (cfg_bb), regno))
+ return false;
+
+ rtx_insn *iter;
+ for (iter = NEXT_INSN (rinsn); iter && iter != NEXT_INSN (BB_END (cfg_bb));
+ iter = NEXT_INSN (iter))
+ if (df_find_use (iter, regno_reg_rtx[regno]))
+ return false;
+
+ return true;
+}
+
+/* Change insn and Assert the change always happens. */
+static void
+validate_change_or_fail (rtx object, rtx *loc, rtx new_rtx, bool in_group)
+{
+ bool change_p = validate_change (object, loc, new_rtx, in_group);
+ gcc_assert (change_p);
+}
+
/* This flags indicates the minimum demand of the vl and vtype values by the
RVV instruction. For example, DEMAND_RATIO_P indicates that this RVV
instruction only needs the SEW/LMUL ratio to remain the same, and does not
@@ -1126,6 +1150,28 @@ public:
}
}
+ /* Returns the corresponding vsetvl rtx pat. */
+ rtx get_vsetvl_pat (bool ignore_vl = false) const
+ {
+ rtx avl = get_avl ();
+ /* if optimization == 0 and the instruction is vmv.x.s/vfmv.f.s,
+ set the value of avl to (const_int 0) so that VSETVL PASS will
+ insert vsetvl correctly.*/
+ if (!get_avl ())
+ avl = GEN_INT (0);
+ rtx sew = gen_int_mode (get_sew (), Pmode);
+ rtx vlmul = gen_int_mode (get_vlmul (), Pmode);
+ rtx ta = gen_int_mode (get_ta (), Pmode);
+ rtx ma = gen_int_mode (get_ma (), Pmode);
+
+ if (change_vtype_only_p ())
+ return gen_vsetvl_vtype_change_only (sew, vlmul, ta, ma);
+ else if (has_reg_vl () && !ignore_vl)
+ return gen_vsetvl (Pmode, get_vl (), avl, sew, vlmul, ta, ma);
+ else
+ return gen_vsetvl_discard_result (Pmode, avl, sew, vlmul, ta, ma);
+ }
+
bool operator== (const vsetvl_info &other) const
{
gcc_assert (!uninit_p () && !other.uninit_p ()
@@ -1938,199 +1984,6 @@ public:
}
};
-/* Emit vsetvl instruction. */
-static rtx
-gen_vsetvl_pat (enum vsetvl_type insn_type, const vsetvl_info &info, rtx vl)
-{
- rtx avl = info.get_avl ();
- /* if optimization == 0 and the instruction is vmv.x.s/vfmv.f.s,
- set the value of avl to (const_int 0) so that VSETVL PASS will
- insert vsetvl correctly.*/
- if (!info.get_avl ())
- avl = GEN_INT (0);
- rtx sew = gen_int_mode (info.get_sew (), Pmode);
- rtx vlmul = gen_int_mode (info.get_vlmul (), Pmode);
- rtx ta = gen_int_mode (info.get_ta (), Pmode);
- rtx ma = gen_int_mode (info.get_ma (), Pmode);
-
- if (insn_type == VSETVL_NORMAL)
- {
- gcc_assert (vl != NULL_RTX);
- return gen_vsetvl (Pmode, vl, avl, sew, vlmul, ta, ma);
- }
- else if (insn_type == VSETVL_VTYPE_CHANGE_ONLY)
- return gen_vsetvl_vtype_change_only (sew, vlmul, ta, ma);
- else
- return gen_vsetvl_discard_result (Pmode, avl, sew, vlmul, ta, ma);
-}
-
-static rtx
-gen_vsetvl_pat (rtx_insn *rinsn, const vsetvl_info &info, rtx vl = NULL_RTX)
-{
- rtx new_pat;
- vsetvl_info new_info = info;
- /* For vmv.x.s, use 0 for avl. */
- if (!info.get_avl ())
- {
- new_info.set_avl (const0_rtx);
- new_info.set_avl_def (nullptr);
- }
-
- if (vl)
- new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, vl);
- else
- {
- if (vsetvl_insn_p (rinsn) && !info.change_vtype_only_p ())
- new_pat = gen_vsetvl_pat (VSETVL_NORMAL, new_info, get_vl (rinsn));
- else if (info.change_vtype_only_p ()
- || INSN_CODE (rinsn) == CODE_FOR_vsetvl_vtype_change_only)
- new_pat = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, new_info, NULL_RTX);
- else
- new_pat = gen_vsetvl_pat (VSETVL_DISCARD_RESULT, new_info, NULL_RTX);
- }
- return new_pat;
-}
-
-static void
-emit_vsetvl_insn (enum vsetvl_type insn_type, enum emit_type emit_type,
- const vsetvl_info &info, rtx vl, rtx_insn *rinsn)
-{
- rtx pat = gen_vsetvl_pat (insn_type, info, vl);
-
- if (emit_type == EMIT_DIRECT)
- {
- emit_insn (pat);
- if (dump_file)
- {
- fprintf (dump_file, " Insert vsetvl insn %d:\n",
- INSN_UID (get_last_insn ()));
- print_rtl_single (dump_file, get_last_insn ());
- }
- }
- else if (emit_type == EMIT_BEFORE)
- {
- emit_insn_before (pat, rinsn);
- if (dump_file)
- {
- fprintf (dump_file, " Insert vsetvl insn before insn %d:\n",
- INSN_UID (rinsn));
- print_rtl_single (dump_file, PREV_INSN (rinsn));
- }
- }
- else
- {
- emit_insn_after (pat, rinsn);
- if (dump_file)
- {
- fprintf (dump_file, " Insert vsetvl insn after insn %d:\n",
- INSN_UID (rinsn));
- print_rtl_single (dump_file, NEXT_INSN (rinsn));
- }
- }
-}
-
-static void
-eliminate_insn (rtx_insn *rinsn)
-{
- if (dump_file)
- {
- fprintf (dump_file, " Eliminate insn %d:\n", INSN_UID (rinsn));
- print_rtl_single (dump_file, rinsn);
- }
- if (in_sequence_p ())
- remove_insn (rinsn);
- else
- delete_insn (rinsn);
-}
-
-/* Change insn and Assert the change always happens. */
-static void
-validate_change_or_fail (rtx object, rtx *loc, rtx new_rtx, bool in_group)
-{
- bool change_p = validate_change (object, loc, new_rtx, in_group);
- gcc_assert (change_p);
-}
-
-static void
-change_insn (rtx_insn *rinsn, rtx new_pat)
-{
- /* We don't apply change on RTL_SSA here since it's possible a
- new INSN we add in the PASS before which doesn't have RTL_SSA
- info yet.*/
- if (dump_file)
- {
- fprintf (dump_file, " Change insn %d from:\n", INSN_UID (rinsn));
- print_rtl_single (dump_file, rinsn);
- }
-
- validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false);
-
- if (dump_file)
- {
- fprintf (dump_file, "\n to:\n");
- print_rtl_single (dump_file, rinsn);
- }
-}
-
-static bool
-change_insn (function_info *ssa, insn_change change, insn_info *insn,
- rtx new_pat)
-{
- rtx_insn *rinsn = insn->rtl ();
- auto attempt = ssa->new_change_attempt ();
- if (!restrict_movement (change))
- return false;
-
- if (dump_file)
- {
- fprintf (dump_file, " Change insn %d from:\n", INSN_UID (rinsn));
- print_rtl_single (dump_file, rinsn);
- }
-
- insn_change_watermark watermark;
- validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, true);
-
- /* These routines report failures themselves. */
- if (!recog (attempt, change) || !change_is_worthwhile (change, false))
- return false;
-
- remove_reg_equal_equiv_notes (rinsn);
- confirm_change_group ();
- ssa->change_insn (change);
-
- if (dump_file)
- {
- fprintf (dump_file, "\n to:\n");
- print_rtl_single (dump_file, rinsn);
- }
-
- return true;
-}
-
-static void
-change_vsetvl_insn (const insn_info *insn, const vsetvl_info &info)
-{
- rtx_insn *rinsn = insn->rtl ();
- rtx new_pat = gen_vsetvl_pat (rinsn, info);
- change_insn (rinsn, new_pat);
-}
-
-/* Return true if the SET result is not used by any instructions. */
-static bool
-has_no_uses (basic_block cfg_bb, rtx_insn *rinsn, int regno)
-{
- if (bitmap_bit_p (df_get_live_out (cfg_bb), regno))
- return false;
-
- rtx_insn *iter;
- for (iter = NEXT_INSN (rinsn); iter && iter != NEXT_INSN (BB_END (cfg_bb));
- iter = NEXT_INSN (iter))
- if (df_find_use (iter, regno_reg_rtx[regno]))
- return false;
-
- return true;
-}
-
class pre_vsetvl
{
private:
@@ -2257,18 +2110,75 @@ private:
}
}
- void insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
- const vsetvl_info &info)
+ void insert_vsetvl_insn (enum emit_type emit_type, const vsetvl_info &info)
{
- if (info.change_vtype_only_p ())
- emit_vsetvl_insn (VSETVL_VTYPE_CHANGE_ONLY, emit_type, info, NULL_RTX,
- rinsn);
+ rtx pat = info.get_vsetvl_pat ();
+ rtx_insn *rinsn = info.get_insn ()->rtl ();
- else if (info.has_reg_vl ())
- emit_vsetvl_insn (VSETVL_NORMAL, emit_type, info, info.get_vl (), rinsn);
+ if (emit_type == EMIT_DIRECT)
+ {
+ emit_insn (pat);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn %d:\n",
+ INSN_UID (get_last_insn ()));
+ print_rtl_single (dump_file, get_last_insn ());
+ }
+ }
+ else if (emit_type == EMIT_BEFORE)
+ {
+ emit_insn_before (pat, rinsn);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn before insn %d:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, PREV_INSN (rinsn));
+ }
+ }
else
- emit_vsetvl_insn (VSETVL_DISCARD_RESULT, emit_type, info, NULL_RTX,
- rinsn);
+ {
+ emit_insn_after (pat, rinsn);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn after insn %d:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, NEXT_INSN (rinsn));
+ }
+ }
+ }
+
+ void change_vsetvl_insn (const vsetvl_info &info)
+ {
+ rtx_insn *rinsn = info.get_insn ()->rtl ();
+ rtx new_pat = info.get_vsetvl_pat ();
+
+ if (dump_file)
+ {
+ fprintf (dump_file, " Change insn %d from:\n", INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+
+ validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "\n to:\n");
+ print_rtl_single (dump_file, rinsn);
+ }
+ }
+
+ void remove_vsetvl_insn (const vsetvl_info &info)
+ {
+ rtx_insn *rinsn = info.get_insn ()->rtl ();
+ if (dump_file)
+ {
+ fprintf (dump_file, " Eliminate insn %d:\n", INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+ if (in_sequence_p ())
+ remove_insn (rinsn);
+ else
+ delete_insn (rinsn);
}
bool earliest_fusion_worthwhile_p (const basic_block cfg_bb) const
@@ -3297,7 +3207,7 @@ pre_vsetvl::emit_vsetvl ()
if (curr_info.ignore_p ())
{
if (vsetvl_insn_p (insn->rtl ()))
- eliminate_insn (insn->rtl ());
+ remove_vsetvl_insn (curr_info);
continue;
}
else if (curr_info.valid_p ())
@@ -3314,7 +3224,7 @@ pre_vsetvl::emit_vsetvl ()
fprintf (dump_file, " to: ");
curr_info.dump (dump_file, " ");
}
- change_vsetvl_insn (insn, curr_info);
+ change_vsetvl_insn (curr_info);
}
}
else
@@ -3326,7 +3236,7 @@ pre_vsetvl::emit_vsetvl ()
insn->uid ());
curr_info.dump (dump_file, " ");
}
- insert_vsetvl (EMIT_BEFORE, insn->rtl (), curr_info);
+ insert_vsetvl_insn (EMIT_BEFORE, curr_info);
}
}
}
@@ -3335,7 +3245,7 @@ pre_vsetvl::emit_vsetvl ()
for (const vsetvl_info &item : delete_list)
{
gcc_assert (vsetvl_insn_p (item.get_insn ()->rtl ()));
- eliminate_insn (item.get_insn ()->rtl ());
+ remove_vsetvl_insn (item);
}
/* Insert vsetvl as LCM suggest. */
@@ -3365,8 +3275,7 @@ pre_vsetvl::emit_vsetvl ()
rtl_profile_for_edge (eg);
start_sequence ();
- insn_info *insn = info.get_insn ();
- insert_vsetvl (EMIT_DIRECT, insn->rtl (), info);
+ insert_vsetvl_insn (EMIT_DIRECT, info);
rtx_insn *rinsn = get_insns ();
end_sequence ();
default_rtl_profile ();
@@ -3385,7 +3294,6 @@ pre_vsetvl::emit_vsetvl ()
continue;
const vsetvl_info &footer_info = block_info.get_footer_info ();
- insn_info *insn = footer_info.get_insn ();
if (footer_info.ignore_p ())
continue;
@@ -3404,7 +3312,7 @@ pre_vsetvl::emit_vsetvl ()
footer_info.dump (dump_file, " ");
}
start_sequence ();
- insert_vsetvl (EMIT_DIRECT, insn->rtl (), footer_info);
+ insert_vsetvl_insn (EMIT_DIRECT, footer_info);
rtx_insn *rinsn = get_insns ();
end_sequence ();
default_rtl_profile ();
@@ -3427,71 +3335,66 @@ pre_vsetvl::cleaup ()
void
pre_vsetvl::remove_avl_operand ()
{
- for (const bb_info *bb : crtl->ssa->bbs ())
- for (insn_info *insn : bb->real_nondebug_insns ())
- {
- rtx_insn *rinsn = insn->rtl ();
- /* Erase the AVL operand from the instruction. */
- if (!has_vl_op (rinsn) || !REG_P (get_vl (rinsn)))
- continue;
- rtx avl = get_vl (rinsn);
- if (count_regno_occurrences (rinsn, REGNO (avl)) == 1)
- {
- /* Get the list of uses for the new instruction. */
- auto attempt = crtl->ssa->new_change_attempt ();
- insn_change change (insn);
- /* Remove the use of the substituted value. */
- access_array_builder uses_builder (attempt);
- uses_builder.reserve (insn->num_uses () - 1);
- for (use_info *use : insn->uses ())
- if (use != find_access (insn->uses (), REGNO (avl)))
- uses_builder.quick_push (use);
- use_array new_uses = use_array (uses_builder.finish ());
- change.new_uses = new_uses;
- change.move_range = insn->ebb ()->insn_range ();
- rtx pat;
- if (fault_first_load_p (rinsn))
- pat = simplify_replace_rtx (PATTERN (rinsn), avl, const0_rtx);
- else
- {
- rtx set = single_set (rinsn);
- rtx src = simplify_replace_rtx (SET_SRC (set), avl, const0_rtx);
- pat = gen_rtx_SET (SET_DEST (set), src);
- }
- bool ok = change_insn (crtl->ssa, change, insn, pat);
- gcc_assert (ok);
- }
- }
+ basic_block cfg_bb;
+ rtx_insn *rinsn;
+ FOR_ALL_BB_FN (cfg_bb, cfun)
+ FOR_BB_INSNS (cfg_bb, rinsn)
+ if (NONDEBUG_INSN_P (rinsn) && has_vl_op (rinsn)
+ && REG_P (get_vl (rinsn)))
+ {
+ rtx avl = get_vl (rinsn);
+ if (count_regno_occurrences (rinsn, REGNO (avl)) == 1)
+ {
+ rtx new_pat;
+ if (fault_first_load_p (rinsn))
+ new_pat
+ = simplify_replace_rtx (PATTERN (rinsn), avl, const0_rtx);
+ else
+ {
+ rtx set = single_set (rinsn);
+ rtx src
+ = simplify_replace_rtx (SET_SRC (set), avl, const0_rtx);
+ new_pat = gen_rtx_SET (SET_DEST (set), src);
+ }
+ if (dump_file)
+ {
+ fprintf (dump_file, " Cleanup insn %u's avl operand:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+ validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat, false);
+ }
+ }
}
void
pre_vsetvl::remove_unused_dest_operand ()
{
df_analyze ();
- hash_set<rtx_insn *> to_delete;
basic_block cfg_bb;
rtx_insn *rinsn;
FOR_ALL_BB_FN (cfg_bb, cfun)
- {
- FOR_BB_INSNS (cfg_bb, rinsn)
+ FOR_BB_INSNS (cfg_bb, rinsn)
+ if (NONDEBUG_INSN_P (rinsn) && vsetvl_insn_p (rinsn))
{
- if (NONDEBUG_INSN_P (rinsn) && vsetvl_insn_p (rinsn))
- {
- rtx vl = get_vl (rinsn);
- vsetvl_info info = vsetvl_info (rinsn);
- if (has_no_uses (cfg_bb, rinsn, REGNO (vl)))
- {
- if (!info.has_vlmax_avl ())
- {
- rtx new_pat = gen_vsetvl_pat (VSETVL_DISCARD_RESULT, info,
- NULL_RTX);
- validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat,
- false);
- }
- }
- }
+ rtx vl = get_vl (rinsn);
+ vsetvl_info info = vsetvl_info (rinsn);
+ if (has_no_uses (cfg_bb, rinsn, REGNO (vl)))
+ if (!info.has_vlmax_avl ())
+ {
+ rtx new_pat = info.get_vsetvl_pat (true);
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ " Remove vsetvl insn %u's dest(vl) operand since "
+ "it unused:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+ validate_change_or_fail (rinsn, &PATTERN (rinsn), new_pat,
+ false);
+ }
}
- }
}
const pass_data pass_data_vsetvl = {
@@ -3536,9 +3439,15 @@ pass_vsetvl::simple_vsetvl ()
continue;
if (has_vtype_op (rinsn))
{
- const auto info = vsetvl_info (rinsn);
- emit_vsetvl_insn (VSETVL_DISCARD_RESULT, EMIT_BEFORE, info,
- NULL_RTX, rinsn);
+ const auto &info = vsetvl_info (rinsn);
+ rtx pat = info.get_vsetvl_pat ();
+ emit_insn_before (pat, rinsn);
+ if (dump_file)
+ {
+ fprintf (dump_file, " Insert vsetvl insn before insn %d:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, PREV_INSN (rinsn));
+ }
}
}
}