[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