Skip to content

Conversation

mshockwave
Copy link
Member

LMULWriteResMXVariant is a helper class that makes creating LMUL-aware SchedVar easier. In preparation for later patches that require

  • LMUL- and SEW-aware SchedVar
  • Assign different processor resources for predicated and non-predicated variants

I factor out the core logics of LMULWriteResMXVariant into another impl class, such that it'll be easier to add "LMULSEWWriteResMXSEWVariant" easier later. I also extend this class so that users can customize processor resources for the non-predicated variant.

Despite these, this patch is still a NFC. I thought it'll be cleaner not to mix the changes here into later patches.

@llvmbot
Copy link
Member

llvmbot commented Oct 7, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Min-Yih Hsu (mshockwave)

Changes

LMULWriteResMXVariant is a helper class that makes creating LMUL-aware SchedVar easier. In preparation for later patches that require

  • LMUL- and SEW-aware SchedVar
  • Assign different processor resources for predicated and non-predicated variants

I factor out the core logics of LMULWriteResMXVariant into another impl class, such that it'll be easier to add "LMULSEWWriteResMXSEWVariant" easier later. I also extend this class so that users can customize processor resources for the non-predicated variant.

Despite these, this patch is still a NFC. I thought it'll be cleaner not to mix the changes here into later patches.


Full diff: https://github.com/llvm/llvm-project/pull/162347.diff

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVSchedSiFive7.td (+24-12)
  • (modified) llvm/lib/Target/RISCV/RISCVScheduleV.td (+35-20)
diff --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
index 3f2e7dbd07a67..3e07eff72bf70 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
@@ -567,9 +567,12 @@ multiclass SiFive7WriteResBase<int VLEN,
     defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;
     defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 8, VLEN>.c;
     defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;
-    defm  : LMULWriteResMXVariant<"WriteVLDS8",  VLDSX0Pred, [VCQ, VL],
-                                         4, [0, 1], [1, !add(1, VLDSX0Cycles)], !add(3, Cycles),
-                                         [0, 1], [1, !add(1, Cycles)], mx, IsWorstCase>;
+    defm  : LMULWriteResMXVariant<"WriteVLDS8",  VLDSX0Pred,
+                                  // Predicated
+                                  [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],
+                                  // Not Predicated
+                                  [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],
+                                  mx, IsWorstCase>;
     let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {
       defm : LMULWriteResMX<"WriteVLDUX8", [VCQ, VL], mx, IsWorstCase>;
       defm : LMULWriteResMX<"WriteVLDOX8", [VCQ, VL], mx, IsWorstCase>;
@@ -587,9 +590,12 @@ multiclass SiFive7WriteResBase<int VLEN,
     defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;
     defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 16, VLEN>.c;
     defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;
-    defm  : LMULWriteResMXVariant<"WriteVLDS16",  VLDSX0Pred, [VCQ, VL],
-                                         4, [0, 1], [1, !add(1, VLDSX0Cycles)], !add(3, Cycles),
-                                         [0, 1], [1, !add(1, Cycles)], mx, IsWorstCase>;
+    defm  : LMULWriteResMXVariant<"WriteVLDS16",  VLDSX0Pred,
+                                  // Predicated
+                                  [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],
+                                  // Not Predicated
+                                  [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],
+                                  mx, IsWorstCase>;
     let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {
       defm : LMULWriteResMX<"WriteVLDUX16", [VCQ, VL], mx, IsWorstCase>;
       defm : LMULWriteResMX<"WriteVLDOX16", [VCQ, VL], mx, IsWorstCase>;
@@ -604,9 +610,12 @@ multiclass SiFive7WriteResBase<int VLEN,
     defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;
     defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 32, VLEN>.c;
     defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;
-    defm  : LMULWriteResMXVariant<"WriteVLDS32",  VLDSX0Pred, [VCQ, VL],
-                                         4, [0, 1], [1, !add(1, VLDSX0Cycles)], !add(3, Cycles),
-                                         [0, 1], [1, !add(1, Cycles)], mx, IsWorstCase>;
+    defm  : LMULWriteResMXVariant<"WriteVLDS32",  VLDSX0Pred,
+                                  // Predicated
+                                  [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],
+                                  // Not Predicated
+                                  [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],
+                                  mx, IsWorstCase>;
     let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {
       defm : LMULWriteResMX<"WriteVLDUX32", [VCQ, VL], mx, IsWorstCase>;
       defm : LMULWriteResMX<"WriteVLDOX32", [VCQ, VL], mx, IsWorstCase>;
@@ -621,9 +630,12 @@ multiclass SiFive7WriteResBase<int VLEN,
     defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;
     defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 64, VLEN>.c;
     defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;
-    defm  : LMULWriteResMXVariant<"WriteVLDS64",  VLDSX0Pred, [VCQ, VL],
-                                         4, [0, 1], [1, !add(1, VLDSX0Cycles)], !add(3, Cycles),
-                                         [0, 1], [1, !add(1, Cycles)], mx, IsWorstCase>;
+    defm  : LMULWriteResMXVariant<"WriteVLDS64",  VLDSX0Pred,
+                                  // Predicated
+                                  [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],
+                                  // Not Predicated
+                                  [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],
+                                  mx, IsWorstCase>;
     let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {
       defm : LMULWriteResMX<"WriteVLDUX64", [VCQ, VL], mx, IsWorstCase>;
       defm : LMULWriteResMX<"WriteVLDOX64", [VCQ, VL], mx, IsWorstCase>;
diff --git a/llvm/lib/Target/RISCV/RISCVScheduleV.td b/llvm/lib/Target/RISCV/RISCVScheduleV.td
index 6c7658c7d93d8..01a4308a1366d 100644
--- a/llvm/lib/Target/RISCV/RISCVScheduleV.td
+++ b/llvm/lib/Target/RISCV/RISCVScheduleV.td
@@ -67,42 +67,41 @@ multiclass LMULSEWWriteResMXSEW<string name, list<ProcResourceKind> resources,
 // ReleaseAtCycles predCycles if the SchedPredicate Pred is true, otherwise has
 // Latency noPredLat and ReleaseAtCycles noPredCycles. The WorstCase SchedWrite
 // is created similarly if IsWorstCase is true.
-multiclass LMULWriteResMXVariant<string name, SchedPredicateBase Pred,
-                                 list<ProcResourceKind> resources,
-                                 int predLat, list<int> predAcquireCycles,
-                                 list<int> predReleaseCycles, int noPredLat,
-                                 list<int> noPredAcquireCycles,
-                                 list<int> noPredReleaseCycles,
-                                 string mx, bit IsWorstCase> {
-  defvar nameMX = name # "_" # mx;
-
+multiclass LMULWriteResVariantImpl<string name, string writeResName, SchedPredicateBase Pred,
+                                   list<ProcResourceKind> predResources,
+                                   int predLat, list<int> predAcquireCycles,
+                                   list<int> predReleaseCycles,
+                                   list<ProcResourceKind> noPredResources,
+                                   int noPredLat, list<int> noPredAcquireCycles,
+                                   list<int> noPredReleaseCycles,
+                                   bit IsWorstCase> {
   // Define the different behaviors
-  def nameMX # "_Pred" : SchedWriteRes<resources>{
+  def writeResName # "_Pred" : SchedWriteRes<predResources>{
     let Latency = predLat;
     let AcquireAtCycles = predAcquireCycles;
     let ReleaseAtCycles = predReleaseCycles;
   }
-  def nameMX # "_NoPred" : SchedWriteRes<resources> {
+  def writeResName # "_NoPred" : SchedWriteRes<noPredResources> {
     let Latency = noPredLat;
     let AcquireAtCycles = noPredAcquireCycles;
     let ReleaseAtCycles = noPredReleaseCycles;
   }
 
   // Define SchedVars
-  def nameMX # PredSchedVar
-      : SchedVar<Pred, [!cast<SchedWriteRes>(NAME # nameMX # "_Pred")]>;
-  def nameMX # NoPredSchedVar
-      : SchedVar<NoSchedPred, [!cast<SchedWriteRes>(NAME # nameMX #"_NoPred")]>;
+  def writeResName # PredSchedVar
+      : SchedVar<Pred, [!cast<SchedWriteRes>(NAME # writeResName # "_Pred")]>;
+  def writeResName # NoPredSchedVar
+      : SchedVar<NoSchedPred, [!cast<SchedWriteRes>(NAME # writeResName #"_NoPred")]>;
   // Allow multiclass to refer to SchedVars -- need to have NAME prefix.
-  defvar PredSchedVar = !cast<SchedVar>(NAME # nameMX # PredSchedVar);
-  defvar NoPredSchedVar = !cast<SchedVar>(NAME # nameMX # NoPredSchedVar);
+  defvar PredSchedVar = !cast<SchedVar>(NAME # writeResName # PredSchedVar);
+  defvar NoPredSchedVar = !cast<SchedVar>(NAME # writeResName # NoPredSchedVar);
 
   // Tie behavior to predicate
-  def NAME # nameMX # "_Variant"
+  def NAME # writeResName # "_Variant"
       : SchedWriteVariant<[PredSchedVar, NoPredSchedVar]>;
   def : SchedAlias<
-    !cast<SchedReadWrite>(nameMX),
-    !cast<SchedReadWrite>(NAME # nameMX # "_Variant")>;
+    !cast<SchedReadWrite>(writeResName),
+    !cast<SchedReadWrite>(NAME # writeResName # "_Variant")>;
 
   if IsWorstCase then {
     def NAME # name # "_WorstCase_Variant"
@@ -113,6 +112,22 @@ multiclass LMULWriteResMXVariant<string name, SchedPredicateBase Pred,
   }
 }
 
+multiclass LMULWriteResMXVariant<string name, SchedPredicateBase Pred,
+                                 list<ProcResourceKind> predResources,
+                                 int predLat, list<int> predAcquireCycles,
+                                 list<int> predReleaseCycles,
+                                 list<ProcResourceKind> noPredResources,
+                                 int noPredLat, list<int> noPredAcquireCycles,
+                                 list<int> noPredReleaseCycles,
+                                 string mx, bit IsWorstCase> {
+  defm "" : LMULWriteResVariantImpl<name, name # "_" # mx, Pred, predResources,
+                                    predLat, predAcquireCycles,
+                                    predReleaseCycles, noPredResources,
+                                    noPredLat, noPredAcquireCycles,
+                                    noPredReleaseCycles,
+                                    IsWorstCase>;
+}
+
 // Define multiclasses to define SchedWrite, SchedRead,  WriteRes, and
 // ReadAdvance for each (name, LMUL) pair and for each LMUL in each of the
 // SchedMxList variants above. Each multiclass is responsible for defining

defm : LMULWriteResMXVariant<"WriteVLDS8", VLDSX0Pred, [VCQ, VL],
4, [0, 1], [1, !add(1, VLDSX0Cycles)], !add(3, Cycles),
[0, 1], [1, !add(1, Cycles)], mx, IsWorstCase>;
defm : LMULWriteResMXVariant<"WriteVLDS8", VLDSX0Pred,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just formatting and adding comments?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting + comment + adding the non-predicated-variant proc resources argument (i.e. the second appearance of [VCQ, VL]) -- previously LMULWriteResMXVariant always uses the same proc resource for both predicated and non-predicated variant. This patch splits it so that users can customize the resources for non-predicated variant as well.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mshockwave mshockwave merged commit 30b9ef8 into llvm:main Oct 7, 2025
11 checks passed
@mshockwave mshockwave deleted the patch/riscv/sched-variant-cleanup-nfc branch October 7, 2025 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants