|| INSN_CODE (rinsn) == CODE_FOR_vsetvlsi);
}
+/* Return true if it is the bogus vsetvl_pre instruction:
+
+ (define_insn "@vlmax_avl<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand:P 1 "const_int_operand" "i")] UNSPEC_VLMAX))]
+ "TARGET_VECTOR"
+ ""
+ [(set_attr "type" "vsetvl_pre")])
+
+ As described above, it's the bogus instruction which doesn't any assembler
+ and should be removed eventually. It's used for occupying a scalar register
+ for VLMAX avl RVV instruction before register allocation.
+
+ Before RA:
+
+ ...
+ vsetvl_pre (set r136)
+ vadd.vv (use r136 with VLMAX avl)
+ ...
+
+ After RA:
+
+ ...
+ vsetvl_pre (set a5)
+ vadd.vv (use r136 with VLMAX avl)
+ ...
+
+ VSETVL PASS:
+
+ ...
+ vsetvl_pre (set a5) ---> removed.
+ vsetvl a5,zero,... ---> Inserted.
+ vadd.vv
+ ...
+*/
+static bool
+vsetvl_pre_insn_p (rtx_insn *rinsn)
+{
+ return recog_memoized (rinsn) >= 0
+ && get_attr_type (rinsn) == TYPE_VSETVL_PRE;
+}
+
/* Return true if it is vsetvl zero, rs1. */
static bool
vsetvl_discard_result_insn_p (rtx_insn *rinsn)
void cleaup ();
void remove_avl_operand ();
void remove_unused_dest_operand ();
+ void remove_vsetvl_pre_insns ();
void dump (FILE *file, const char *title) const
{
{
remove_avl_operand ();
remove_unused_dest_operand ();
+ remove_vsetvl_pre_insns ();
}
void
}
}
+/* Remove all bogus vsetvl_pre instructions. */
+void
+pre_vsetvl::remove_vsetvl_pre_insns ()
+{
+ 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) && vsetvl_pre_insn_p (rinsn))
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, " Eliminate vsetvl_pre insn %d:\n",
+ INSN_UID (rinsn));
+ print_rtl_single (dump_file, rinsn);
+ }
+ remove_insn (rinsn);
+ }
+}
+
const pass_data pass_data_vsetvl = {
RTL_PASS, /* type */
"vsetvl", /* name */