summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Maitland <michaeltmaitland@gmail.com>2024-02-23 09:15:48 -0500
committerGitHub <noreply@github.com>2024-02-23 09:15:48 -0500
commitbe083dba95dfbbb0286d798cc06fbe021715bc03 (patch)
tree81322d5364108c76becf2627106b2e46ddef082e
parent52ada07ef5df2829e90ca2dd48305465a55e8121 (diff)
[RISCV][NFC] Allow SchedVar to be a def inside our scheduler model files. (#82634)
All SchedModel files have a line that looks like: ``` def SomeModel : SchedMachineModel; let SchedModel = SomeModel in { ... } ``` TableGen requires that all records defined within the top level `let` must have a field `SchedModel` somewhere in their nested record hierarchy (i.e. the record has a field `SchedModel : SchedMachineModel` or recursively, one of its members has a field `SchedModel : SchedMachineModel`). Classes such as `SchedPredicate` have added a field `SchedModel : SchedMachineModel`, even though the field is never used, just to supress **errors** (not warnings) caused from having the top level let in the model files. This decision was made to avoid having hundreds of the same `let` statement littered in every scheduler model file. The reason we have never seen an error for `SchedVar` before is because `SchedVar` is never instantiated with a `def`. Instead, it is only created as a value that is consumed by `SchedWriteVariant`: ``` ... : SchedWriteVariant<[SchedVar<...>, SchedVar<...>]>; ``` There is a problem with this style of instantiation. In particular, the problem arises as we try to take a class based approach to building scheduler models. I will describe the problem from the bottom up. The `LMULWriteResMXVariant` multiclass takes in a `SchedPredicateBase Pred`. Today, the RISCVSchedSiFive7.td file defines `VLDSX0Pred` outside the scope of any class. That means that `VLDSX0Pred` exists before `LMULWriteResMXVariant` multiclass is instantiated. With this approach, there is no error since the predicate is instantated in entirety before the variant multiclass is instantiated. However, I have the intention to move the definition of both the predicate and the variant multiclass records inside a multiclass to factor out common parts between multiple scheduler models. I plan to have something like: ``` multiclass SiFive7Base<SiFive7BaseConfig c> { def VLDSX0Pred : ...; // Need defvar since record is prefixed with NAME. defvar VLDSX0Pred = !cast<...>(NAME # VLDSX0Pred); defm SiFive7 : LMULWriteResMXVariant<VLDSX0Pred>; } defm "SiFive7Version1" : SiFive7Base<SiFive7BaseConfig<...>>; defm "SiFive7Version2" : SiFive7Base<SiFive7BaseConfig<...>>; ``` In this scheme, VLDSX0Pred is defined within the same multiclass transaction that the `LMULWriteResMXVariant` is defined in. For some reason, TableGen does not allow `Values` to reference records that were created in the same parent record construction. If the `SchedVar` is not a `def`, then it will not be able to find the record `NAME # VLDSX0Pred`. Making it a def, allows TableGen to find `NAME # VLDSX0Pred` in scope. The simplest example of this is: ``` class A {} class B<A a> { A x = a;} class C<B b> { B y = b;} multiclass D { def MyA : A; defvar aa = !cast<A>(NAME # MyA); // This works def : B<aa>; // This does not work because constructing B by value cannot find `NAME # MyA` // error: Undefined reference to record: 'MyA' def : C<B<aa>>; // To fix it, define it like such: def MyB : B<aa>; defvar bb = !cast<B>(NAME # MyB); def : C<bb>; } defm "" : D; ``` In summary, in order to use a class based approach to creating scheduler resources to promote resusability, `SchedVar`s must be created using defs instead of being instantiated by value so that it can resolve records that were part of the instantiation of the parent record being created. In order to do this without refactoring the top level `let` statement that all scheduler model files use, we add an unused field `SchedModel : SchedMachineModel` to `SchedVar`, similiar to what has been done in `SchedPredicate`.
-rw-r--r--llvm/include/llvm/Target/TargetSchedule.td2
-rw-r--r--llvm/lib/Target/RISCV/RISCVScheduleV.td21
2 files changed, 15 insertions, 8 deletions
diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td
index e2781a5d1ea5..48c9387977c0 100644
--- a/llvm/include/llvm/Target/TargetSchedule.td
+++ b/llvm/include/llvm/Target/TargetSchedule.td
@@ -399,6 +399,8 @@ def NoSchedPred : MCSchedPredicate<TruePred>;
class SchedVar<SchedPredicateBase pred, list<SchedReadWrite> selected> {
SchedPredicateBase Predicate = pred;
list<SchedReadWrite> Selected = selected;
+ // SchedModel silences warnings but is ignored.
+ SchedMachineModel SchedModel = ?;
}
// SchedModel silences warnings but is ignored.
diff --git a/llvm/lib/Target/RISCV/RISCVScheduleV.td b/llvm/lib/Target/RISCV/RISCVScheduleV.td
index d15cb611ae66..0be681de3daf 100644
--- a/llvm/lib/Target/RISCV/RISCVScheduleV.td
+++ b/llvm/lib/Target/RISCV/RISCVScheduleV.td
@@ -88,20 +88,25 @@ multiclass LMULWriteResMXVariant<string name, SchedPredicateBase Pred,
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")]>;
+ // 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);
+
// Tie behavior to predicate
- def NAME # nameMX # "_Variant" : SchedWriteVariant<[
- SchedVar<Pred, [!cast<SchedWriteRes>(NAME # nameMX # "_Pred")]>,
- SchedVar<NoSchedPred, [!cast<SchedWriteRes>(NAME # nameMX # "_NoPred")]>
- ]>;
+ def NAME # nameMX # "_Variant"
+ : SchedWriteVariant<[PredSchedVar, NoPredSchedVar]>;
def : SchedAlias<
!cast<SchedReadWrite>(nameMX),
!cast<SchedReadWrite>(NAME # nameMX # "_Variant")>;
if IsWorstCase then {
- def NAME # name # "_WorstCase_Variant" : SchedWriteVariant<[
- SchedVar<Pred, [!cast<SchedWriteRes>(NAME # nameMX # "_Pred")]>,
- SchedVar<NoSchedPred, [!cast<SchedWriteRes>(NAME # nameMX # "_NoPred")]>
- ]>;
+ def NAME # name # "_WorstCase_Variant"
+ : SchedWriteVariant<[PredSchedVar, NoPredSchedVar]>;
def : SchedAlias<
!cast<SchedReadWrite>(name # "_WorstCase"),
!cast<SchedReadWrite>(NAME # name # "_WorstCase_Variant")>;