[llvm] [AArch64] SME definitions for C1-Ultra scheduling model (PR #194850)
Nashe Mncube via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 08:59:40 PDT 2026
================
@@ -93,9 +117,201 @@ def : WriteRes<WriteLDHi, []> { let Latency = 4; }
// Define customized scheduler read/write types specific to C1 Ultra.
//===----------------------------------------------------------------------===//
+// The approach for modelling SME instructions should not be taken as accurate.
+// This is due to limitations of tablegen and the actual behaviour we want to
+// to model. The CME is a co-processor. Accurate modelling would allow for us
+// to model core-to-processor communication latencies. This is out of the scope
+// of what we can achieve at the present. As a consequence we model instructions
+// that run on the CME as by only modelling their execution latency once issued
+// rather than modelling the more complex relationship between the C1-Ultra and
+// the CME co-processor and how that will affect execution latencies. Developers
+// must therefore take latencies for SME instructions as inaccurate.
+//
+// We have several classes of SME instructions that we need to model.
+//
+// 1. SVE instructions added by SME and available when not in streaming SVE mode
+// 2. SVE instructions added by SME but not sent to CME when in streaming SVE mode
+// 3. FP/SVE/ASIMD instructions sent to CME when in streaming SVE mode
+// 4. SME instructions sent to CME and only available in streaming SVE mode
+//
+// To model instructions of type (1) and (2) is fairly easy in that we know
+// that these instructions aren't "dependent" on streaming SVE mode to model their
+// scheduling information. To model these we use a predicate on these instructions
+// which checks if the target supports SME (SMESchedPred).
+//
+// To model instructions of type (3) we recognise that llvm-mca doesn't include
+// information of whether we are in streaming SVE mode. However, for the sake of
+// completeness we model this class of instructions by adding
+// an llvm-mca attribute (mca-streaming-sched) which is interpreted as the core
+// being in streaming SVE mode. This allows us to at least have some data on how
+// these instructions may be scheduled when in streaming SVE mode using llvm-mca
+// if the core supports SME and this attribute is enabled. Otherwise, we default
+// to the plain non-streaming SVE mode scheduling information.
+//
+// Similarly, to model instructions of type (4) we just extend the scheduling model
+// to add definitions for this class of instructions which are "gated" via the
+// SMESchedPred predicate and mca-streaming-sched attribute. The purpose of
+// having these definitions is that information on how these instructions are
+// scheduled on the CME coprocessor is useful for analysis.
+
+// SME2 related read write types
// Define generic 0 micro-op types.
def C1UWrite_0c : SchedWriteRes<[]> { let Latency = 0; }
+class C1UCMEWrite<int LatencyCycles, list<ProcResourceKind> Resources>
+ : SchedWriteRes<Resources> {
+ let Latency = LatencyCycles;
+}
+
+class C1UCMEWriteRC<int LatencyCycles, list<ProcResourceKind> Resources,
+ list<int> ReleaseCycles>
+ : SchedWriteRes<Resources> {
+ let Latency = LatencyCycles;
+ let ReleaseAtCycles = ReleaseCycles;
+}
+
+class C1UStreamingOnlySchedWrite<SchedWrite StreamingWrite>
+ : SchedWriteVariant<[
+ SchedVar<SMEMCStreamingSchedPred, [StreamingWrite]>,
+ SchedVar<NoSchedPred, [C1UWrite_0c]>
+ ]>;
+
+// Detailed CME scheduling derived from the SME2 software optimization guide.
+def C1UWrite_1c_CMEPERMS : C1UCMEWrite<1, [C1UUnitCMEPERMS]>;
+def C1UWrite_1c_CMEPERMS_1rc : C1UCMEWriteRC<1, [C1UUnitCMEPERMS], [1]>;
+def C1UWrite_1c_CMEPERMS_2rc : C1UCMEWriteRC<1, [C1UUnitCMEPERMS], [2]>;
+def C1UWrite_1c_CMERNMRET : C1UCMEWrite<1, [C1UUnitCMERNMRET]>;
+def C1UWrite_1c_CMEMML0_4rc : C1UCMEWriteRC<1, [C1UUnitCMEMML0], [4]>;
+def C1UWrite_2c_1L_CMELD : C1UCMEWrite<2, [C1UUnitL, C1UUnitCMELD]>;
+def C1UWrite_2c_1I_1L_CMELD : C1UCMEWrite<2, [C1UUnitI, C1UUnitL,
+ C1UUnitCMELD]>;
+def C1UWrite_2c_1V01_1L_CMELD : C1UCMEWrite<2, [C1UUnitV01, C1UUnitL,
+ C1UUnitCMELD]>;
+def C1UWrite_2c_1I_1V01_1L_CMELD
+ : C1UCMEWrite<2, [C1UUnitI, C1UUnitV01, C1UUnitL, C1UUnitCMELD]>;
+def C1UWrite_2c_1SA_CMEST : C1UCMEWrite<2, [C1UUnitSA, C1UUnitCMEST]>;
+def C1UWrite_2c_1SA_1V01_CMEST : C1UCMEWrite<2, [C1UUnitSA, C1UUnitV01,
+ C1UUnitCMEST]>;
+def C1UWrite_2c_1SA_1V01_1I_CMEST
+ : C1UCMEWrite<2, [C1UUnitSA, C1UUnitV01, C1UUnitI, C1UUnitCMEST]>;
+def C1UWrite_2c_2SA_2V01_CMEST : C1UCMEWrite<2, [C1UUnitSA, C1UUnitSA,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitCMEST]>;
+def C1UWrite_2c_3SA_3V01_CMEST : C1UCMEWrite<2, [C1UUnitSA, C1UUnitSA,
+ C1UUnitSA, C1UUnitV01,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitCMEST]>;
+def C1UWrite_2c_3SA_6V01_CMEST : C1UCMEWrite<2, [C1UUnitSA, C1UUnitSA,
+ C1UUnitSA, C1UUnitV01,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitV01, C1UUnitCMEST]>;
+def C1UWrite_2c_4SA_4V01_CMEST : C1UCMEWrite<2, [C1UUnitSA, C1UUnitSA,
+ C1UUnitSA, C1UUnitSA,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitCMEST]>;
+def C1UWrite_2c_5SA_5V01_CMEST : C1UCMEWrite<2, [C1UUnitSA, C1UUnitSA,
+ C1UUnitSA, C1UUnitSA,
+ C1UUnitSA, C1UUnitV01,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitV01, C1UUnitV01,
+ C1UUnitCMEST]>;
+def C1UWrite_4c_CMEPERMS : C1UCMEWrite<4, [C1UUnitCMEPERMS]>;
+def C1UWrite_4c_CMEPERMS_2rc : C1UCMEWriteRC<4, [C1UUnitCMEPERMS], [2]>;
+//def C1UWrite_5c_CMEPERMS : C1UCMEWrite<5, [C1UUnitCMEPERMS]>;
+def C1UWrite_5c_CMEPERMS_2rc : C1UCMEWriteRC<5, [C1UUnitCMEPERMS], [2]>;
----------------
nasherm wrote:
Done
https://github.com/llvm/llvm-project/pull/194850
More information about the llvm-commits
mailing list