]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/riscv/vector.md
RISC-V: Support VSETVL PASS for RVV support
[thirdparty/gcc.git] / gcc / config / riscv / vector.md
index 1b822184d27ed9f149f0bdc1ee56a81a6f0ad194..985373838bb0ee3d2e9bdf55ab70d23ee93c2f03 100644 (file)
@@ -32,6 +32,7 @@
   UNSPEC_VSETVL
   UNSPEC_VUNDEF
   UNSPEC_VPREDICATE
+  UNSPEC_VLMAX
 ])
 
 (define_constants [
         (const_int 32)
         (eq_attr "mode" "VNx1DI,VNx2DI,VNx4DI,VNx8DI,\
                          VNx1DF,VNx2DF,VNx4DF,VNx8DF")
-        (const_int 64)]
+        (const_int 64)
+
+        (eq_attr "type" "vsetvl")
+        (if_then_else (eq_attr "INSN_CODE (curr_insn) == CODE_FOR_vsetvldi
+                                || INSN_CODE (curr_insn) == CODE_FOR_vsetvlsi")
+                      (symbol_ref "INTVAL (operands[2])")
+                      (const_int INVALID_ATTRIBUTE))]
        (const_int INVALID_ATTRIBUTE)))
 
 ;; Ditto to LMUL.
         (eq_attr "mode" "VNx4DI,VNx4DF")
           (symbol_ref "riscv_vector::get_vlmul(E_VNx4DImode)")
         (eq_attr "mode" "VNx8DI,VNx8DF")
-          (symbol_ref "riscv_vector::get_vlmul(E_VNx8DImode)")]
+          (symbol_ref "riscv_vector::get_vlmul(E_VNx8DImode)")
+        (eq_attr "type" "vsetvl")
+        (if_then_else (eq_attr "INSN_CODE (curr_insn) == CODE_FOR_vsetvldi
+                                || INSN_CODE (curr_insn) == CODE_FOR_vsetvlsi")
+                      (symbol_ref "INTVAL (operands[3])")
+                      (const_int INVALID_ATTRIBUTE))]
        (const_int INVALID_ATTRIBUTE)))
 
 ;; It is valid for instruction that require sew/lmul ratio.
         (const_int 6)]
        (const_int INVALID_ATTRIBUTE)))
 
+;; The index of operand[] to get the mask policy op.
+(define_attr "avl_type_op_idx" ""
+  (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vlds,vlds")
+        (const_int 7)
+        (eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
+        (const_int 5)]
+       (const_int INVALID_ATTRIBUTE)))
+
+;; The tail policy op value.
+(define_attr "ta" ""
+  (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vlds")
+          (symbol_ref "riscv_vector::get_ta(operands[5])")]
+       (const_int INVALID_ATTRIBUTE)))
+
+;; The mask policy op value.
+(define_attr "ma" ""
+  (cond [(eq_attr "type" "vlde,vlds")
+          (symbol_ref "riscv_vector::get_ma(operands[6])")]
+       (const_int INVALID_ATTRIBUTE)))
+
+;; The avl type value.
+(define_attr "avl_type" ""
+  (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vlds,vlds")
+          (symbol_ref "INTVAL (operands[7])")
+        (eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
+          (symbol_ref "INTVAL (operands[5])")]
+       (const_int INVALID_ATTRIBUTE)))
+
 ;; -----------------------------------------------------------------
 ;; ---- Miscellaneous Operations
 ;; -----------------------------------------------------------------
   "TARGET_VECTOR"
   "")
 
+;; This pattern is used to hold the AVL operand for
+;; RVV instructions that implicity use VLMAX AVL.
+;; RVV instruction implicitly use GPR that is ultimately
+;; defined by this pattern is safe for VSETVL pass emit
+;; a vsetvl instruction modify this register after RA.
+;; Case 1:
+;;   vlmax_avl a5
+;;   ... (across many blocks)
+;;   vadd (implicit use a5)  ====> emit: vsetvl a5,zero
+;; Case 2:
+;;   vlmax_avl a5
+;;   ... (across many blocks)
+;;   mv a6,a5
+;;   ... (across many blocks)
+;;   vadd (implicit use a6)  ====> emit: vsetvl a6,zero
+;; Case 3:
+;;   vlmax_avl a5
+;;   ... (across many blocks)
+;;   store mem,a5 (spill)
+;;   ... (across many blocks)
+;;   load a7,mem (spill)
+;;   ... (across many blocks)
+;;   vadd (implicit use a7)  ====> emit: vsetvl a7,zero
+;; Such cases are all safe for VSETVL PASS to emit a vsetvl
+;; instruction that modifies the AVL operand.
+(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"
+  "")
+
 ;; -----------------------------------------------------------------
 ;; ---- Moves Operations
 ;; -----------------------------------------------------------------
   [(set_attr "type" "vsetvl")
    (set_attr "mode" "<MODE>")])
 
-;; We keep it as no side effects before reload_completed.
-;; In this case, we can gain benefits from different GCC
-;; internal PASS such as cprop, fwprop, combine,...etc.
-
-;; Then recover it for "insert-vsetvl" and "sched2" PASS
-;; in order to get correct codegen.
-(define_insn_and_split "@vsetvl<mode>_no_side_effects"
-  [(set (match_operand:P 0 "register_operand" "=r")
-       (unspec:P [(match_operand:P 1 "csr_operand" "rK")
-                  (match_operand 2 "const_int_operand" "i")
-                  (match_operand 3 "const_int_operand" "i")
-                  (match_operand 4 "const_int_operand" "i")
-                  (match_operand 5 "const_int_operand" "i")] UNSPEC_VSETVL))]
+;; vsetvl zero,zero,vtype instruction.
+;; This pattern has no side effects and does not set X0 register.
+(define_insn "vsetvl_vtype_change_only"
+  [(set (reg:SI VTYPE_REGNUM)
+       (unspec:SI
+         [(match_operand 0 "const_int_operand" "i")
+          (match_operand 1 "const_int_operand" "i")
+          (match_operand 2 "const_int_operand" "i")
+          (match_operand 3 "const_int_operand" "i")] UNSPEC_VSETVL))]
   "TARGET_VECTOR"
-  "#"
-  "&& reload_completed"
-  [(parallel
-    [(set (match_dup 0)
-         (unspec:P [(match_dup 1) (match_dup 2) (match_dup 3)
-                    (match_dup 4) (match_dup 5)] UNSPEC_VSETVL))
-     (set (reg:SI VL_REGNUM)
-         (unspec:SI [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPEC_VSETVL))
-     (set (reg:SI VTYPE_REGNUM)
-         (unspec:SI [(match_dup 2) (match_dup 3) (match_dup 4)
-                     (match_dup 5)] UNSPEC_VSETVL))])]
-  ""
+  "vsetvli\tzero,zero,e%0,%m1,t%p2,m%p3"
+  [(set_attr "type" "vsetvl")
+   (set_attr "mode" "SI")])
+
+;; vsetvl zero,rs1,vtype instruction.
+;; The reason we need this pattern since we should avoid setting X0 register
+;; in vsetvl instruction pattern.
+(define_insn "@vsetvl_discard_result<mode>"
+  [(set (reg:SI VL_REGNUM)
+       (unspec:SI [(match_operand:P 0 "csr_operand" "rK")
+                   (match_operand 1 "const_int_operand" "i")
+                   (match_operand 2 "const_int_operand" "i")] UNSPEC_VSETVL))
+   (set (reg:SI VTYPE_REGNUM)
+       (unspec:SI [(match_dup 1)
+                   (match_dup 2)
+                   (match_operand 3 "const_int_operand" "i")
+                   (match_operand 4 "const_int_operand" "i")] UNSPEC_VSETVL))]
+  "TARGET_VECTOR"
+  "vsetvli\tzero,%0,e%1,%m2,t%p3,m%p4"
   [(set_attr "type" "vsetvl")
    (set_attr "mode" "<MODE>")])
 
             (match_operand 4 "vector_length_operand"    " rK,  rK,    rK,    rK,    rK")
             (match_operand 5 "const_int_operand"        "  i,   i,     i,     i,     i")
             (match_operand 6 "const_int_operand"        "  i,   i,     i,     i,     i")
+            (match_operand 7 "const_int_operand"        "  i,   i,     i,     i,     i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
          (match_operand:V 3 "vector_move_operand"       "  m,   m,    vr,    vr, viWc0")
          (unspec:VB
            [(match_operand:VB 1 "vector_mask_operand"   "Wc1, Wc1, Wc1, Wc1, Wc1")
             (match_operand 4 "vector_length_operand"    " rK,  rK,  rK,  rK,  rK")
+            (match_operand 5 "const_int_operand"        "  i,   i,   i,   i,   i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
          (match_operand:VB 3 "vector_move_operand"      "  m,  vr,  vr, Wc0, Wc1")
             (match_operand 4 "vector_length_operand"         " rK,  rK,  rK,  rK")
             (match_operand 5 "const_int_operand"             "  i,   i,   i,   i")
             (match_operand 6 "const_int_operand"             "  i,   i,   i,   i")
+            (match_operand 7 "const_int_operand"             "  i,   i,   i,   i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
          (vec_duplicate:V