[llvm] [RISCV][CostModel][NFC] Add getRISCVInstructionCost() to TTI for Cost… (PR #73651)

Shih-Po Hung via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 29 03:34:30 PST 2023


https://github.com/arcbbb updated https://github.com/llvm/llvm-project/pull/73651

>From e3965f7fab2a1c143017f372d89ba07553f90a89 Mon Sep 17 00:00:00 2001
From: ShihPo Hung <shihpo.hung at sifive.com>
Date: Tue, 28 Nov 2023 01:07:26 -0800
Subject: [PATCH 1/4] [RISCV][CostModel][NFC] Add getRISCVInstructionCost() to
 TTI for CostKind

Instruction cost for CodeSize and Latency/RecipThroughput can be very differnet.
Considering the diversity of CostKind and vendor-specific cost, and how
they are spread across various TTI functions, it's becoming quite a challenge to handle.
This patch adds an interface getRISCVInstructionCost to address it.
---
 .../Target/RISCV/RISCVTargetTransformInfo.cpp | 102 +++++++++++++++---
 .../Target/RISCV/RISCVTargetTransformInfo.h   |  18 ++++
 2 files changed, 108 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index 3a2f2f39cd1c9b0..b583a6a9cb43298 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -34,6 +34,51 @@ static cl::opt<unsigned> SLPMaxVF(
         "exclusively by SLP vectorizer."),
     cl::Hidden);
 
+InstructionCost
+RISCVTTIImpl::getRISCVInstructionCost(RISCVInstruction Inst, MVT VT,
+                                      unsigned NumInstr,
+                                      TTI::TargetCostKind CostKind) {
+  if (CostKind == TTI::TCK_CodeSize)
+    return NumInstr;
+
+  InstructionCost LMUL = TLI->getLMULCost(VT);
+  InstructionCost Cost = LMUL * NumInstr;
+
+  if ((CostKind == TTI::TCK_RecipThroughput) ||
+      (CostKind == TTI::TCK_Latency)) {
+    switch (Inst) {
+    case RISCVInstruction::VRGATHER_VI:
+      return NumInstr * TLI->getVRGatherVICost(VT);
+    case RISCVInstruction::VRGATHER_VV:
+      return NumInstr * TLI->getVRGatherVVCost(VT);
+    case RISCVInstruction::VSLIDE:
+      return NumInstr * TLI->getVSlideCost(VT);
+    case RISCVInstruction::VSIMPLE_INT_RED:
+    case RISCVInstruction::VMINMAX_INTFP_RED:
+    case RISCVInstruction::VUNORD_FP_RED: {
+      unsigned VL = VT.getVectorMinNumElements();
+      if (!VT.isFixedLengthVector()) {
+        VL *= *getVScaleForTuning();
+      }
+      return Log2_32_Ceil(VL);
+    }
+    case RISCVInstruction::VORD_FP_RED: {
+      unsigned VL = VT.getVectorMinNumElements();
+      if (!VT.isFixedLengthVector()) {
+        VL *= *getVScaleForTuning();
+      }
+      return VL;
+    }
+    case RISCVInstruction::VMERGE:
+    case RISCVInstruction::VMV:
+    case RISCVInstruction::VSIMPLE_INT:
+    case RISCVInstruction::VNARROWING:
+      return Cost;
+    }
+  }
+  return Cost;
+}
+
 InstructionCost RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
                                             TTI::TargetCostKind CostKind) {
   assert(Ty->isIntegerTy() &&
@@ -279,7 +324,9 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
             // Example sequence:
             //   vnsrl.wi   v10, v8, 0
             if (equal(DeinterleaveMask, Mask))
-              return LT.first * TLI->getLMULCost(LT.second);
+              return LT.first *
+                     getRISCVInstructionCost(RISCVInstruction::VNARROWING,
+                                             LT.second, 1, CostKind);
           }
         }
       }
@@ -290,7 +337,9 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
            LT.second.getVectorNumElements() <= 256)) {
         VectorType *IdxTy = getVRGatherIndexType(LT.second, *ST, Tp->getContext());
         InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
-        return IndexCost + TLI->getVRGatherVVCost(LT.second);
+        return IndexCost +
+               getRISCVInstructionCost(RISCVInstruction::VRGATHER_VV, LT.second,
+                                       1, CostKind);
       }
       [[fallthrough]];
     }
@@ -308,7 +357,10 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         VectorType *MaskTy = VectorType::get(IntegerType::getInt1Ty(C), EC);
         InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
         InstructionCost MaskCost = getConstantPoolLoadCost(MaskTy, CostKind);
-        return 2 * IndexCost + 2 * TLI->getVRGatherVVCost(LT.second) + MaskCost;
+        return 2 * IndexCost +
+               getRISCVInstructionCost(RISCVInstruction::VRGATHER_VV, LT.second,
+                                       2, CostKind) +
+               MaskCost;
       }
       [[fallthrough]];
     }
@@ -363,19 +415,26 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // Example sequence:
     // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
     // vslidedown.vi  v8, v9, 2
-    return LT.first * TLI->getVSlideCost(LT.second);
+    return LT.first * getRISCVInstructionCost(RISCVInstruction::VSLIDE,
+                                              LT.second, 1, CostKind);
   case TTI::SK_InsertSubvector:
     // Example sequence:
     // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
     // vslideup.vi  v8, v9, 2
-    return LT.first * TLI->getVSlideCost(LT.second);
+    return LT.first * getRISCVInstructionCost(RISCVInstruction::VSLIDE,
+                                              LT.second, 1, CostKind);
   case TTI::SK_Select: {
     // Example sequence:
     // li           a0, 90
     // vsetivli     zero, 8, e8, mf2, ta, ma (ignored)
     // vmv.s.x      v0, a0
     // vmerge.vvm   v8, v9, v8, v0
-    return LT.first * 3 * TLI->getLMULCost(LT.second);
+    return LT.first *
+           (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for li
+            getRISCVInstructionCost(RISCVInstruction::VMV, LT.second, 1,
+                                    CostKind) +
+            getRISCVInstructionCost(RISCVInstruction::VMERGE, LT.second, 1,
+                                    CostKind));
   }
   case TTI::SK_Broadcast: {
     bool HasScalar = (Args.size() > 0) && (Operator::getOpcode(Args[0]) ==
@@ -387,7 +446,12 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         //   vsetivli zero, 2, e8, mf8, ta, ma (ignored)
         //   vmv.v.x v8, a0
         //   vmsne.vi v0, v8, 0
-        return LT.first * TLI->getLMULCost(LT.second) * 3;
+        return LT.first *
+               (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for andi
+                getRISCVInstructionCost(RISCVInstruction::VMV, LT.second, 1,
+                                        CostKind) +
+                getRISCVInstructionCost(RISCVInstruction::VSIMPLE_INT,
+                                        LT.second, 1, CostKind));
       }
       // Example sequence:
       //   vsetivli  zero, 2, e8, mf8, ta, mu (ignored)
@@ -398,24 +462,34 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
       //   vmv.v.x v8, a0
       //   vmsne.vi  v0, v8, 0
 
-      return LT.first * TLI->getLMULCost(LT.second) * 6;
+      return LT.first *
+             (TLI->getLMULCost(LT.second) + // FIXME: this should be 1 for andi
+              getRISCVInstructionCost(RISCVInstruction::VMV, LT.second, 3,
+                                      CostKind) +
+              getRISCVInstructionCost(RISCVInstruction::VMERGE, LT.second, 1,
+                                      CostKind) +
+              getRISCVInstructionCost(RISCVInstruction::VSIMPLE_INT, LT.second,
+                                      1, CostKind));
     }
 
     if (HasScalar) {
       // Example sequence:
       //   vmv.v.x v8, a0
-      return LT.first * TLI->getLMULCost(LT.second);
+      return LT.first * getRISCVInstructionCost(RISCVInstruction::VMV,
+                                                LT.second, 1, CostKind);
     }
 
     // Example sequence:
     //   vrgather.vi     v9, v8, 0
-    return LT.first * TLI->getVRGatherVICost(LT.second);
+    return LT.first * getRISCVInstructionCost(RISCVInstruction::VRGATHER_VI,
+                                              LT.second, 1, CostKind);
   }
   case TTI::SK_Splice:
     // vslidedown+vslideup.
     // TODO: Multiplying by LT.first implies this legalizes into multiple copies
     // of similar code, but I think we expand through memory.
-    return 2 * LT.first * TLI->getVSlideCost(LT.second);
+    return LT.first * getRISCVInstructionCost(RISCVInstruction::VSLIDE,
+                                              LT.second, 2, CostKind);
   case TTI::SK_Reverse: {
     // TODO: Cases to improve here:
     // * Illegal vector types
@@ -435,7 +509,11 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     if (LT.second.isFixedLengthVector())
       // vrsub.vi has a 5 bit immediate field, otherwise an li suffices
       LenCost = isInt<5>(LT.second.getVectorNumElements() - 1) ? 0 : 1;
-    InstructionCost GatherCost = 2 + TLI->getVRGatherVVCost(LT.second);
+    // FIXME: replace the constant `2` below with cost of VSIMPLE_INT (vid.v &
+    // vrsub.vx)
+    InstructionCost GatherCost =
+        2 + getRISCVInstructionCost(RISCVInstruction::VRGATHER_VV, LT.second, 1,
+                                    CostKind);
     // Mask operation additionally required extend and truncate
     InstructionCost ExtendCost = Tp->getElementType()->isIntegerTy(1) ? 3 : 0;
     return LT.first * (LenCost + GatherCost + ExtendCost);
diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
index 81a45f623d294e8..829eace9d1236d2 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
@@ -48,6 +48,24 @@ class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
   /// actual target hardware.
   unsigned getEstimatedVLFor(VectorType *Ty);
 
+  enum class RISCVInstruction {
+    VRGATHER_VV,
+    VRGATHER_VI,
+    VSLIDE,
+    VMERGE,
+    VMV,
+    VSIMPLE_INT,       // ICMP
+    VNARROWING,        // VNSRL
+    VSIMPLE_INT_RED,   // VREDSUM, VREDAND, VREDOR, VREDXOR
+    VMINMAX_INTFP_RED, // VREDMAX, VREDMAXU, VREDMIN, VREDMINU
+    VUNORD_FP_RED,     // VFREDUSUM, VFREDMAX, VFREDMIN
+    VORD_FP_RED,       // VFREDOSUM
+  };
+
+  InstructionCost getRISCVInstructionCost(RISCVInstruction Inst, MVT VT,
+                                          unsigned NumInstr,
+                                          TTI::TargetCostKind CostKind);
+
   /// Return the cost of accessing a constant pool entry of the specified
   /// type.
   InstructionCost getConstantPoolLoadCost(Type *Ty,

>From 9ff94a24b56d80a1e72a8da62805859f26b77cd4 Mon Sep 17 00:00:00 2001
From: ShihPo Hung <shihpo.hung at sifive.com>
Date: Tue, 28 Nov 2023 19:26:23 -0800
Subject: [PATCH 2/4] Split VMV into VMV_SX and VMV_V

---
 llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp | 14 +++++++++-----
 llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h   |  3 ++-
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index b583a6a9cb43298..cbbf0ef0c159a57 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -69,8 +69,10 @@ RISCVTTIImpl::getRISCVInstructionCost(RISCVInstruction Inst, MVT VT,
       }
       return VL;
     }
+    case RISCVInstruction::VMV_SX:
+      // FIXME: VMV_SX doesn't use LMUL, just return NumInstr
+    case RISCVInstruction::VMV_V:
     case RISCVInstruction::VMERGE:
-    case RISCVInstruction::VMV:
     case RISCVInstruction::VSIMPLE_INT:
     case RISCVInstruction::VNARROWING:
       return Cost;
@@ -431,7 +433,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // vmerge.vvm   v8, v9, v8, v0
     return LT.first *
            (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for li
-            getRISCVInstructionCost(RISCVInstruction::VMV, LT.second, 1,
+            getRISCVInstructionCost(RISCVInstruction::VMV_SX, LT.second, 1,
                                     CostKind) +
             getRISCVInstructionCost(RISCVInstruction::VMERGE, LT.second, 1,
                                     CostKind));
@@ -448,7 +450,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         //   vmsne.vi v0, v8, 0
         return LT.first *
                (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for andi
-                getRISCVInstructionCost(RISCVInstruction::VMV, LT.second, 1,
+                getRISCVInstructionCost(RISCVInstruction::VMV_V, LT.second, 1,
                                         CostKind) +
                 getRISCVInstructionCost(RISCVInstruction::VSIMPLE_INT,
                                         LT.second, 1, CostKind));
@@ -464,7 +466,9 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
 
       return LT.first *
              (TLI->getLMULCost(LT.second) + // FIXME: this should be 1 for andi
-              getRISCVInstructionCost(RISCVInstruction::VMV, LT.second, 3,
+              TLI->getLMULCost(
+                  LT.second) + // FIXME: vmv.x.s is the same as extractelement
+              getRISCVInstructionCost(RISCVInstruction::VMV_V, LT.second, 2,
                                       CostKind) +
               getRISCVInstructionCost(RISCVInstruction::VMERGE, LT.second, 1,
                                       CostKind) +
@@ -475,7 +479,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     if (HasScalar) {
       // Example sequence:
       //   vmv.v.x v8, a0
-      return LT.first * getRISCVInstructionCost(RISCVInstruction::VMV,
+      return LT.first * getRISCVInstructionCost(RISCVInstruction::VMV_V,
                                                 LT.second, 1, CostKind);
     }
 
diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
index 829eace9d1236d2..e053e0e3ebb2b19 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
@@ -53,7 +53,8 @@ class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
     VRGATHER_VI,
     VSLIDE,
     VMERGE,
-    VMV,
+    VMV_V,
+    VMV_SX,
     VSIMPLE_INT,       // ICMP
     VNARROWING,        // VNSRL
     VSIMPLE_INT_RED,   // VREDSUM, VREDAND, VREDOR, VREDXOR

>From 45ac18eac3b0d1cef96467fa7188e9b0c9fa9b36 Mon Sep 17 00:00:00 2001
From: ShihPo Hung <shihpo.hung at sifive.com>
Date: Wed, 29 Nov 2023 00:28:19 -0800
Subject: [PATCH 3/4] Use Opcode defined in RISCV namespace

---
 .../Target/RISCV/RISCVTargetTransformInfo.cpp | 76 ++++++++++---------
 .../Target/RISCV/RISCVTargetTransformInfo.h   | 17 +----
 2 files changed, 42 insertions(+), 51 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index cbbf0ef0c159a57..a8a2bdc0e4d4d69 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -35,7 +35,7 @@ static cl::opt<unsigned> SLPMaxVF(
     cl::Hidden);
 
 InstructionCost
-RISCVTTIImpl::getRISCVInstructionCost(RISCVInstruction Inst, MVT VT,
+RISCVTTIImpl::getRISCVInstructionCost(unsigned OpCode, MVT VT,
                                       unsigned NumInstr,
                                       TTI::TargetCostKind CostKind) {
   if (CostKind == TTI::TCK_CodeSize)
@@ -46,35 +46,41 @@ RISCVTTIImpl::getRISCVInstructionCost(RISCVInstruction Inst, MVT VT,
 
   if ((CostKind == TTI::TCK_RecipThroughput) ||
       (CostKind == TTI::TCK_Latency)) {
-    switch (Inst) {
-    case RISCVInstruction::VRGATHER_VI:
+    switch (OpCode) {
+    case RISCV::VRGATHER_VI:
       return NumInstr * TLI->getVRGatherVICost(VT);
-    case RISCVInstruction::VRGATHER_VV:
+    case RISCV::VRGATHER_VV:
       return NumInstr * TLI->getVRGatherVVCost(VT);
-    case RISCVInstruction::VSLIDE:
+    case RISCV::VSLIDEUP_VI:
+    case RISCV::VSLIDEDOWN_VI:
+    case RISCV::VSLIDEUP_VX:
+    case RISCV::VSLIDEDOWN_VX:
       return NumInstr * TLI->getVSlideCost(VT);
-    case RISCVInstruction::VSIMPLE_INT_RED:
-    case RISCVInstruction::VMINMAX_INTFP_RED:
-    case RISCVInstruction::VUNORD_FP_RED: {
+    case RISCV::VREDMAX_VS:
+    case RISCV::VREDMIN_VS:
+    case RISCV::VREDMAXU_VS:
+    case RISCV::VREDMINU_VS:
+    case RISCV::VREDSUM_VS:
+    case RISCV::VREDAND_VS:
+    case RISCV::VREDOR_VS:
+    case RISCV::VREDXOR_VS:
+    case RISCV::VFREDMAX_VS:
+    case RISCV::VFREDMIN_VS:
+    case RISCV::VFREDUSUM_VS: {
       unsigned VL = VT.getVectorMinNumElements();
-      if (!VT.isFixedLengthVector()) {
+      if (!VT.isFixedLengthVector())
         VL *= *getVScaleForTuning();
-      }
       return Log2_32_Ceil(VL);
     }
-    case RISCVInstruction::VORD_FP_RED: {
+    case RISCV::VFREDOSUM_VS: {
       unsigned VL = VT.getVectorMinNumElements();
-      if (!VT.isFixedLengthVector()) {
+      if (!VT.isFixedLengthVector())
         VL *= *getVScaleForTuning();
-      }
       return VL;
     }
-    case RISCVInstruction::VMV_SX:
-      // FIXME: VMV_SX doesn't use LMUL, just return NumInstr
-    case RISCVInstruction::VMV_V:
-    case RISCVInstruction::VMERGE:
-    case RISCVInstruction::VSIMPLE_INT:
-    case RISCVInstruction::VNARROWING:
+    case RISCV::VMV_S_X:
+      // FIXME: VMV_S_X doesn't use LMUL, just return NumInstr
+    default:
       return Cost;
     }
   }
@@ -327,7 +333,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
             //   vnsrl.wi   v10, v8, 0
             if (equal(DeinterleaveMask, Mask))
               return LT.first *
-                     getRISCVInstructionCost(RISCVInstruction::VNARROWING,
+                     getRISCVInstructionCost(RISCV::VNSRL_WI,
                                              LT.second, 1, CostKind);
           }
         }
@@ -340,7 +346,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         VectorType *IdxTy = getVRGatherIndexType(LT.second, *ST, Tp->getContext());
         InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
         return IndexCost +
-               getRISCVInstructionCost(RISCVInstruction::VRGATHER_VV, LT.second,
+               getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
                                        1, CostKind);
       }
       [[fallthrough]];
@@ -360,7 +366,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
         InstructionCost MaskCost = getConstantPoolLoadCost(MaskTy, CostKind);
         return 2 * IndexCost +
-               getRISCVInstructionCost(RISCVInstruction::VRGATHER_VV, LT.second,
+               getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
                                        2, CostKind) +
                MaskCost;
       }
@@ -417,13 +423,13 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // Example sequence:
     // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
     // vslidedown.vi  v8, v9, 2
-    return LT.first * getRISCVInstructionCost(RISCVInstruction::VSLIDE,
+    return LT.first * getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI,
                                               LT.second, 1, CostKind);
   case TTI::SK_InsertSubvector:
     // Example sequence:
     // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
     // vslideup.vi  v8, v9, 2
-    return LT.first * getRISCVInstructionCost(RISCVInstruction::VSLIDE,
+    return LT.first * getRISCVInstructionCost(RISCV::VSLIDEUP_VI,
                                               LT.second, 1, CostKind);
   case TTI::SK_Select: {
     // Example sequence:
@@ -433,9 +439,9 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // vmerge.vvm   v8, v9, v8, v0
     return LT.first *
            (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for li
-            getRISCVInstructionCost(RISCVInstruction::VMV_SX, LT.second, 1,
+            getRISCVInstructionCost(RISCV::VMV_S_X, LT.second, 1,
                                     CostKind) +
-            getRISCVInstructionCost(RISCVInstruction::VMERGE, LT.second, 1,
+            getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second, 1,
                                     CostKind));
   }
   case TTI::SK_Broadcast: {
@@ -450,9 +456,9 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         //   vmsne.vi v0, v8, 0
         return LT.first *
                (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for andi
-                getRISCVInstructionCost(RISCVInstruction::VMV_V, LT.second, 1,
+                getRISCVInstructionCost(RISCV::VMV_V_X, LT.second, 1,
                                         CostKind) +
-                getRISCVInstructionCost(RISCVInstruction::VSIMPLE_INT,
+                getRISCVInstructionCost(RISCV::VMSNE_VI,
                                         LT.second, 1, CostKind));
       }
       // Example sequence:
@@ -468,31 +474,31 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
              (TLI->getLMULCost(LT.second) + // FIXME: this should be 1 for andi
               TLI->getLMULCost(
                   LT.second) + // FIXME: vmv.x.s is the same as extractelement
-              getRISCVInstructionCost(RISCVInstruction::VMV_V, LT.second, 2,
+              getRISCVInstructionCost(RISCV::VMV_V_X, LT.second, 2,
                                       CostKind) +
-              getRISCVInstructionCost(RISCVInstruction::VMERGE, LT.second, 1,
+              getRISCVInstructionCost(RISCV::VMERGE_VIM, LT.second, 1,
                                       CostKind) +
-              getRISCVInstructionCost(RISCVInstruction::VSIMPLE_INT, LT.second,
+              getRISCVInstructionCost(RISCV::VMSNE_VI, LT.second,
                                       1, CostKind));
     }
 
     if (HasScalar) {
       // Example sequence:
       //   vmv.v.x v8, a0
-      return LT.first * getRISCVInstructionCost(RISCVInstruction::VMV_V,
+      return LT.first * getRISCVInstructionCost(RISCV::VMV_V_X,
                                                 LT.second, 1, CostKind);
     }
 
     // Example sequence:
     //   vrgather.vi     v9, v8, 0
-    return LT.first * getRISCVInstructionCost(RISCVInstruction::VRGATHER_VI,
+    return LT.first * getRISCVInstructionCost(RISCV::VRGATHER_VI,
                                               LT.second, 1, CostKind);
   }
   case TTI::SK_Splice:
     // vslidedown+vslideup.
     // TODO: Multiplying by LT.first implies this legalizes into multiple copies
     // of similar code, but I think we expand through memory.
-    return LT.first * getRISCVInstructionCost(RISCVInstruction::VSLIDE,
+    return LT.first * getRISCVInstructionCost(RISCV::VSLIDEDOWN_VX,
                                               LT.second, 2, CostKind);
   case TTI::SK_Reverse: {
     // TODO: Cases to improve here:
@@ -516,7 +522,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // FIXME: replace the constant `2` below with cost of VSIMPLE_INT (vid.v &
     // vrsub.vx)
     InstructionCost GatherCost =
-        2 + getRISCVInstructionCost(RISCVInstruction::VRGATHER_VV, LT.second, 1,
+        2 + getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second, 1,
                                     CostKind);
     // Mask operation additionally required extend and truncate
     InstructionCost ExtendCost = Tp->getElementType()->isIntegerTy(1) ? 3 : 0;
diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
index e053e0e3ebb2b19..06fbde9d5686592 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
@@ -48,22 +48,7 @@ class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
   /// actual target hardware.
   unsigned getEstimatedVLFor(VectorType *Ty);
 
-  enum class RISCVInstruction {
-    VRGATHER_VV,
-    VRGATHER_VI,
-    VSLIDE,
-    VMERGE,
-    VMV_V,
-    VMV_SX,
-    VSIMPLE_INT,       // ICMP
-    VNARROWING,        // VNSRL
-    VSIMPLE_INT_RED,   // VREDSUM, VREDAND, VREDOR, VREDXOR
-    VMINMAX_INTFP_RED, // VREDMAX, VREDMAXU, VREDMIN, VREDMINU
-    VUNORD_FP_RED,     // VFREDUSUM, VFREDMAX, VFREDMIN
-    VORD_FP_RED,       // VFREDOSUM
-  };
-
-  InstructionCost getRISCVInstructionCost(RISCVInstruction Inst, MVT VT,
+  InstructionCost getRISCVInstructionCost(unsigned OpCode, MVT VT,
                                           unsigned NumInstr,
                                           TTI::TargetCostKind CostKind);
 

>From d1365823e88e74564f06bc8d8f09f729e197957d Mon Sep 17 00:00:00 2001
From: ShihPo Hung <shihpo.hung at sifive.com>
Date: Wed, 29 Nov 2023 03:24:05 -0800
Subject: [PATCH 4/4] Support array of Opcodes

---
 .../Target/RISCV/RISCVTargetTransformInfo.cpp | 95 +++++++++----------
 .../Target/RISCV/RISCVTargetTransformInfo.h   |  3 +-
 2 files changed, 46 insertions(+), 52 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index a8a2bdc0e4d4d69..03fd8c745793f2c 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -35,27 +35,29 @@ static cl::opt<unsigned> SLPMaxVF(
     cl::Hidden);
 
 InstructionCost
-RISCVTTIImpl::getRISCVInstructionCost(unsigned OpCode, MVT VT,
-                                      unsigned NumInstr,
+RISCVTTIImpl::getRISCVInstructionCost(ArrayRef<unsigned> OpCodes, MVT VT,
                                       TTI::TargetCostKind CostKind) {
+  size_t NumInstr = OpCodes.size();
   if (CostKind == TTI::TCK_CodeSize)
     return NumInstr;
-
-  InstructionCost LMUL = TLI->getLMULCost(VT);
-  InstructionCost Cost = LMUL * NumInstr;
-
-  if ((CostKind == TTI::TCK_RecipThroughput) ||
-      (CostKind == TTI::TCK_Latency)) {
-    switch (OpCode) {
+  InstructionCost LMULCost = TLI->getLMULCost(VT);
+  if ((CostKind != TTI::TCK_RecipThroughput) && (CostKind != TTI::TCK_Latency))
+    return LMULCost * NumInstr;
+  InstructionCost Cost = 0;
+  for (auto Op : OpCodes) {
+    switch (Op) {
     case RISCV::VRGATHER_VI:
-      return NumInstr * TLI->getVRGatherVICost(VT);
+      Cost += TLI->getVRGatherVICost(VT);
+      break;
     case RISCV::VRGATHER_VV:
-      return NumInstr * TLI->getVRGatherVVCost(VT);
+      Cost += TLI->getVRGatherVVCost(VT);
+      break;
     case RISCV::VSLIDEUP_VI:
     case RISCV::VSLIDEDOWN_VI:
     case RISCV::VSLIDEUP_VX:
     case RISCV::VSLIDEDOWN_VX:
-      return NumInstr * TLI->getVSlideCost(VT);
+      Cost += TLI->getVSlideCost(VT);
+      break;
     case RISCV::VREDMAX_VS:
     case RISCV::VREDMIN_VS:
     case RISCV::VREDMAXU_VS:
@@ -70,18 +72,20 @@ RISCVTTIImpl::getRISCVInstructionCost(unsigned OpCode, MVT VT,
       unsigned VL = VT.getVectorMinNumElements();
       if (!VT.isFixedLengthVector())
         VL *= *getVScaleForTuning();
-      return Log2_32_Ceil(VL);
+      Cost += Log2_32_Ceil(VL);
+      break;
     }
     case RISCV::VFREDOSUM_VS: {
       unsigned VL = VT.getVectorMinNumElements();
       if (!VT.isFixedLengthVector())
         VL *= *getVScaleForTuning();
-      return VL;
+      Cost += VL;
+      break;
     }
     case RISCV::VMV_S_X:
-      // FIXME: VMV_S_X doesn't use LMUL, just return NumInstr
+      // FIXME: VMV_S_X doesn't use LMUL, the cost should be 1
     default:
-      return Cost;
+      Cost += LMULCost;
     }
   }
   return Cost;
@@ -332,9 +336,8 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
             // Example sequence:
             //   vnsrl.wi   v10, v8, 0
             if (equal(DeinterleaveMask, Mask))
-              return LT.first *
-                     getRISCVInstructionCost(RISCV::VNSRL_WI,
-                                             LT.second, 1, CostKind);
+              return LT.first * getRISCVInstructionCost({RISCV::VNSRL_WI},
+                                                        LT.second, CostKind);
           }
         }
       }
@@ -345,9 +348,8 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
            LT.second.getVectorNumElements() <= 256)) {
         VectorType *IdxTy = getVRGatherIndexType(LT.second, *ST, Tp->getContext());
         InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
-        return IndexCost +
-               getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
-                                       1, CostKind);
+        return IndexCost + getRISCVInstructionCost({RISCV::VRGATHER_VV},
+                                                   LT.second, CostKind);
       }
       [[fallthrough]];
     }
@@ -366,8 +368,8 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
         InstructionCost MaskCost = getConstantPoolLoadCost(MaskTy, CostKind);
         return 2 * IndexCost +
-               getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second,
-                                       2, CostKind) +
+               getRISCVInstructionCost({RISCV::VRGATHER_VV, RISCV::VRGATHER_VV},
+                                       LT.second, CostKind) +
                MaskCost;
       }
       [[fallthrough]];
@@ -423,14 +425,14 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // Example sequence:
     // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
     // vslidedown.vi  v8, v9, 2
-    return LT.first * getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI,
-                                              LT.second, 1, CostKind);
+    return LT.first *
+           getRISCVInstructionCost({RISCV::VSLIDEDOWN_VI}, LT.second, CostKind);
   case TTI::SK_InsertSubvector:
     // Example sequence:
     // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
     // vslideup.vi  v8, v9, 2
-    return LT.first * getRISCVInstructionCost(RISCV::VSLIDEUP_VI,
-                                              LT.second, 1, CostKind);
+    return LT.first *
+           getRISCVInstructionCost({RISCV::VSLIDEUP_VI}, LT.second, CostKind);
   case TTI::SK_Select: {
     // Example sequence:
     // li           a0, 90
@@ -439,10 +441,8 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // vmerge.vvm   v8, v9, v8, v0
     return LT.first *
            (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for li
-            getRISCVInstructionCost(RISCV::VMV_S_X, LT.second, 1,
-                                    CostKind) +
-            getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second, 1,
-                                    CostKind));
+            getRISCVInstructionCost({RISCV::VMV_S_X, RISCV::VMERGE_VVM},
+                                    LT.second, CostKind));
   }
   case TTI::SK_Broadcast: {
     bool HasScalar = (Args.size() > 0) && (Operator::getOpcode(Args[0]) ==
@@ -456,10 +456,8 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
         //   vmsne.vi v0, v8, 0
         return LT.first *
                (TLI->getLMULCost(LT.second) + // FIXME: should be 1 for andi
-                getRISCVInstructionCost(RISCV::VMV_V_X, LT.second, 1,
-                                        CostKind) +
-                getRISCVInstructionCost(RISCV::VMSNE_VI,
-                                        LT.second, 1, CostKind));
+                getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
+                                        LT.second, CostKind));
       }
       // Example sequence:
       //   vsetivli  zero, 2, e8, mf8, ta, mu (ignored)
@@ -474,32 +472,30 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
              (TLI->getLMULCost(LT.second) + // FIXME: this should be 1 for andi
               TLI->getLMULCost(
                   LT.second) + // FIXME: vmv.x.s is the same as extractelement
-              getRISCVInstructionCost(RISCV::VMV_V_X, LT.second, 2,
-                                      CostKind) +
-              getRISCVInstructionCost(RISCV::VMERGE_VIM, LT.second, 1,
-                                      CostKind) +
-              getRISCVInstructionCost(RISCV::VMSNE_VI, LT.second,
-                                      1, CostKind));
+              getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM,
+                                       RISCV::VMV_V_X, RISCV::VMSNE_VI},
+                                      LT.second, CostKind));
     }
 
     if (HasScalar) {
       // Example sequence:
       //   vmv.v.x v8, a0
-      return LT.first * getRISCVInstructionCost(RISCV::VMV_V_X,
-                                                LT.second, 1, CostKind);
+      return LT.first *
+             getRISCVInstructionCost({RISCV::VMV_V_X}, LT.second, CostKind);
     }
 
     // Example sequence:
     //   vrgather.vi     v9, v8, 0
-    return LT.first * getRISCVInstructionCost(RISCV::VRGATHER_VI,
-                                              LT.second, 1, CostKind);
+    return LT.first *
+           getRISCVInstructionCost({RISCV::VRGATHER_VI}, LT.second, CostKind);
   }
   case TTI::SK_Splice:
     // vslidedown+vslideup.
     // TODO: Multiplying by LT.first implies this legalizes into multiple copies
     // of similar code, but I think we expand through memory.
-    return LT.first * getRISCVInstructionCost(RISCV::VSLIDEDOWN_VX,
-                                              LT.second, 2, CostKind);
+    return LT.first *
+           getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX},
+                                   LT.second, CostKind);
   case TTI::SK_Reverse: {
     // TODO: Cases to improve here:
     // * Illegal vector types
@@ -522,8 +518,7 @@ InstructionCost RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
     // FIXME: replace the constant `2` below with cost of VSIMPLE_INT (vid.v &
     // vrsub.vx)
     InstructionCost GatherCost =
-        2 + getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second, 1,
-                                    CostKind);
+        2 + getRISCVInstructionCost({RISCV::VRGATHER_VV}, LT.second, CostKind);
     // Mask operation additionally required extend and truncate
     InstructionCost ExtendCost = Tp->getElementType()->isIntegerTy(1) ? 3 : 0;
     return LT.first * (LenCost + GatherCost + ExtendCost);
diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
index 06fbde9d5686592..c60ea54c5d44984 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
@@ -48,8 +48,7 @@ class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
   /// actual target hardware.
   unsigned getEstimatedVLFor(VectorType *Ty);
 
-  InstructionCost getRISCVInstructionCost(unsigned OpCode, MVT VT,
-                                          unsigned NumInstr,
+  InstructionCost getRISCVInstructionCost(ArrayRef<unsigned> OpCodes, MVT VT,
                                           TTI::TargetCostKind CostKind);
 
   /// Return the cost of accessing a constant pool entry of the specified



More information about the llvm-commits mailing list