[llvm] 2d84e0f - [RISCV] Add scheduling model for Syntacore SCR3 (#95427)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 25 01:35:04 PDT 2024
Author: Anton Sidorenko
Date: 2024-06-25T11:34:59+03:00
New Revision: 2d84e0ffefda62da6193d339633dbb55654f7b5d
URL: https://github.com/llvm/llvm-project/commit/2d84e0ffefda62da6193d339633dbb55654f7b5d
DIFF: https://github.com/llvm/llvm-project/commit/2d84e0ffefda62da6193d339633dbb55654f7b5d.diff
LOG: [RISCV] Add scheduling model for Syntacore SCR3 (#95427)
Syntacore SCR3 is a microcontroller-class processor core. Overview:
https://syntacore.com/products/scr3
Co-authored-by: Dmitrii Petrov <dmitrii.petrov at syntacore.com>
Added:
llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR3.td
llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-ALU.s
llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-LSU.s
Modified:
llvm/lib/Target/RISCV/RISCV.td
llvm/lib/Target/RISCV/RISCVProcessors.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index 09f496574d64a..d96fafbe60807 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -51,6 +51,7 @@ include "RISCVSchedSiFive7.td"
include "RISCVSchedSiFiveP400.td"
include "RISCVSchedSiFiveP600.td"
include "RISCVSchedSyntacoreSCR1.td"
+include "RISCVSchedSyntacoreSCR3.td"
include "RISCVSchedXiangShanNanHu.td"
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td
index 6d71cb6a41423..13a2491116b5d 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -327,7 +327,7 @@ def SYNTACORE_SCR1_MAX : RISCVProcessorModel<"syntacore-scr1-max",
[TuneNoDefaultUnroll]>;
def SYNTACORE_SCR3_RV32 : RISCVProcessorModel<"syntacore-scr3-rv32",
- NoSchedModel,
+ SyntacoreSCR3RV32Model,
[Feature32Bit,
FeatureStdExtI,
FeatureStdExtZicsr,
@@ -337,7 +337,7 @@ def SYNTACORE_SCR3_RV32 : RISCVProcessorModel<"syntacore-scr3-rv32",
[TuneNoDefaultUnroll, FeaturePostRAScheduler]>;
def SYNTACORE_SCR3_RV64 : RISCVProcessorModel<"syntacore-scr3-rv64",
- NoSchedModel,
+ SyntacoreSCR3RV64Model,
[Feature64Bit,
FeatureStdExtI,
FeatureStdExtZicsr,
diff --git a/llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR3.td b/llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR3.td
new file mode 100644
index 0000000000000..607637bc0de59
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR3.td
@@ -0,0 +1,189 @@
+//==- RISCVSchedSyntacoreSCR3.td - Syntacore SCR3 Scheduling Definitions -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+
+// This model covers SYNTACORE_SCR3_RV32IMC and SYNTACORE_RV64IMAC
+// configurations (syntacore-scr3-rv32/64).
+// Overview: https://syntacore.com/products/scr3
+
+// SCR3 is single-issue in-order processor
+class SyntacoreSCR3Model : SchedMachineModel {
+ let MicroOpBufferSize = 0;
+ let IssueWidth = 1;
+ let LoadLatency = 2;
+ let MispredictPenalty = 3;
+ let CompleteModel = 0;
+ let UnsupportedFeatures = [HasStdExtD, HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,
+ HasStdExtZknd, HasStdExtZkne, HasStdExtZknh,
+ HasStdExtZksed, HasStdExtZksh, HasStdExtZkr,
+ HasVInstructions];
+}
+
+// Branching
+multiclass SCR3_Branching<ProcResourceKind BRU> {
+ def : WriteRes<WriteJmp, [BRU]>;
+ def : WriteRes<WriteJal, [BRU]>;
+ def : WriteRes<WriteJalr, [BRU]>;
+}
+
+// Single-cycle integer arithmetic and logic
+multiclass SCR3_IntALU<ProcResourceKind ALU> {
+ def : WriteRes<WriteIALU, [ALU]>;
+ def : WriteRes<WriteIALU32, [ALU]>;
+ def : WriteRes<WriteShiftImm, [ALU]>;
+ def : WriteRes<WriteShiftImm32, [ALU]>;
+ def : WriteRes<WriteShiftReg, [ALU]>;
+ def : WriteRes<WriteShiftReg32, [ALU]>;
+}
+
+// Integer multiplication
+multiclass SCR3_IntMul<ProcResourceKind MUL> {
+ let Latency = 2 in {
+ def : WriteRes<WriteIMul, [MUL]>;
+ def : WriteRes<WriteIMul32, [MUL]>;
+ }
+}
+
+// Integer division
+multiclass SCR3_IntDiv<ProcResourceKind DIV, int DivLatency> {
+ let Latency = DivLatency, ReleaseAtCycles = [DivLatency] in {
+ def : WriteRes<WriteIDiv, [DIV]>;
+ def : WriteRes<WriteIDiv32, [DIV]>;
+ def : WriteRes<WriteIRem, [DIV]>;
+ def : WriteRes<WriteIRem32, [DIV]>;
+ }
+}
+
+// Load/store instructions on SCR3 have latency 2
+multiclass SCR3_Memory<ProcResourceKind LSU> {
+ let Latency = 2 in {
+ def : WriteRes<WriteSTB, [LSU]>;
+ def : WriteRes<WriteSTH, [LSU]>;
+ def : WriteRes<WriteSTW, [LSU]>;
+ def : WriteRes<WriteSTD, [LSU]>;
+ def : WriteRes<WriteLDB, [LSU]>;
+ def : WriteRes<WriteLDH, [LSU]>;
+ def : WriteRes<WriteLDW, [LSU]>;
+ def : WriteRes<WriteLDD, [LSU]>;
+ }
+}
+
+// Atomic memory
+multiclass SCR3_AtomicMemory<ProcResourceKind LSU> {
+ let Latency = 20 in {
+ def : WriteRes<WriteAtomicLDW, [LSU]>;
+ def : WriteRes<WriteAtomicLDD, [LSU]>;
+ def : WriteRes<WriteAtomicW, [LSU]>;
+ def : WriteRes<WriteAtomicD, [LSU]>;
+ def : WriteRes<WriteAtomicSTW, [LSU]>;
+ def : WriteRes<WriteAtomicSTD, [LSU]>;
+ }
+}
+
+// Others
+multiclass SCR3_Other {
+ def : WriteRes<WriteCSR, []>;
+ def : WriteRes<WriteNop, []>;
+
+ def : InstRW<[WriteIALU], (instrs COPY)>;
+}
+
+
+multiclass SCR3_Unsupported {
+ defm : UnsupportedSchedD;
+ defm : UnsupportedSchedF;
+ defm : UnsupportedSchedSFB;
+ defm : UnsupportedSchedV;
+ defm : UnsupportedSchedXsfvcp;
+ defm : UnsupportedSchedZabha;
+ defm : UnsupportedSchedZba;
+ defm : UnsupportedSchedZbb;
+ defm : UnsupportedSchedZbc;
+ defm : UnsupportedSchedZbs;
+ defm : UnsupportedSchedZbkb;
+ defm : UnsupportedSchedZbkx;
+ defm : UnsupportedSchedZfa;
+ defm : UnsupportedSchedZfh;
+ defm : UnsupportedSchedZvk;
+}
+
+// Bypasses (none)
+multiclass SCR3_NoReadAdvances {
+ def : ReadAdvance<ReadJmp, 0>;
+ def : ReadAdvance<ReadJalr, 0>;
+ def : ReadAdvance<ReadCSR, 0>;
+ def : ReadAdvance<ReadStoreData, 0>;
+ def : ReadAdvance<ReadMemBase, 0>;
+ def : ReadAdvance<ReadIALU, 0>;
+ def : ReadAdvance<ReadIALU32, 0>;
+ def : ReadAdvance<ReadShiftImm, 0>;
+ def : ReadAdvance<ReadShiftImm32, 0>;
+ def : ReadAdvance<ReadShiftReg, 0>;
+ def : ReadAdvance<ReadShiftReg32, 0>;
+ def : ReadAdvance<ReadIDiv, 0>;
+ def : ReadAdvance<ReadIDiv32, 0>;
+ def : ReadAdvance<ReadIRem, 0>;
+ def : ReadAdvance<ReadIRem32, 0>;
+ def : ReadAdvance<ReadIMul, 0>;
+ def : ReadAdvance<ReadIMul32, 0>;
+ def : ReadAdvance<ReadAtomicWA, 0>;
+ def : ReadAdvance<ReadAtomicWD, 0>;
+ def : ReadAdvance<ReadAtomicDA, 0>;
+ def : ReadAdvance<ReadAtomicDD, 0>;
+ def : ReadAdvance<ReadAtomicLDW, 0>;
+ def : ReadAdvance<ReadAtomicLDD, 0>;
+ def : ReadAdvance<ReadAtomicSTW, 0>;
+ def : ReadAdvance<ReadAtomicSTD, 0>;
+}
+
+def SyntacoreSCR3RV32Model : SyntacoreSCR3Model;
+
+let SchedModel = SyntacoreSCR3RV32Model in {
+ let BufferSize = 0 in {
+ def SCR3RV32_ALU : ProcResource<1>;
+ def SCR3RV32_MUL : ProcResource<1>;
+ def SCR3RV32_DIV : ProcResource<1>;
+ def SCR3RV32_LSU : ProcResource<1>;
+ def SCR3RV32_CFU : ProcResource<1>;
+ }
+
+ defm : SCR3_Branching<SCR3RV32_CFU>;
+ defm : SCR3_IntALU<SCR3RV32_ALU>;
+ defm : SCR3_IntMul<SCR3RV32_MUL>;
+ defm : SCR3_IntDiv<SCR3RV32_DIV, /* div latency = */ 8>;
+ defm : SCR3_Memory<SCR3RV32_LSU>;
+ defm : SCR3_AtomicMemory<SCR3RV32_LSU>;
+ defm : SCR3_Other;
+
+ defm : SCR3_Unsupported;
+ defm : SCR3_NoReadAdvances;
+}
+
+def SyntacoreSCR3RV64Model : SyntacoreSCR3Model;
+
+let SchedModel = SyntacoreSCR3RV64Model in {
+ let BufferSize = 0 in {
+ def SCR3RV64_ALU : ProcResource<1>;
+ def SCR3RV64_MUL : ProcResource<1>;
+ def SCR3RV64_DIV : ProcResource<1>;
+ def SCR3RV64_LSU : ProcResource<1>;
+ def SCR3RV64_CFU : ProcResource<1>;
+ }
+
+ defm : SCR3_Branching<SCR3RV64_CFU>;
+ defm : SCR3_IntALU<SCR3RV64_ALU>;
+ defm : SCR3_IntMul<SCR3RV64_MUL>;
+ defm : SCR3_IntDiv<SCR3RV64_DIV, /* div latency = */ 11>;
+ defm : SCR3_Memory<SCR3RV64_LSU>;
+ defm : SCR3_AtomicMemory<SCR3RV64_LSU>;
+ defm : SCR3_Other;
+
+ defm : SCR3_Unsupported;
+ defm : SCR3_NoReadAdvances;
+}
diff --git a/llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-ALU.s b/llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-ALU.s
new file mode 100644
index 0000000000000..83866106b47a1
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-ALU.s
@@ -0,0 +1,91 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -mtriple=riscv64-unknown-unknown -mcpu=syntacore-scr3-rv64 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV64
+# RUN: llvm-mca -mtriple=riscv32-unknown-unknown -mcpu=syntacore-scr3-rv32 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV32
+
+div a0, a0, a0
+mul t0, a0, t0
+add t1, a0, t0
+add t2, t2, t2
+div a1, a1, a1
+mul s0, a1, s0
+add s1, s0, s1
+add s2, s2, s2
+
+# CHECK: Iterations: 1
+# CHECK-NEXT: Instructions: 8
+
+# RV32-NEXT: Total Cycles: 25
+# RV64-NEXT: Total Cycles: 31
+
+# CHECK-NEXT: Total uOps: 8
+
+# CHECK: Dispatch Width: 1
+
+# RV32-NEXT: uOps Per Cycle: 0.32
+# RV32-NEXT: IPC: 0.32
+# RV32-NEXT: Block RThroughput: 16.0
+
+# RV64-NEXT: uOps Per Cycle: 0.26
+# RV64-NEXT: IPC: 0.26
+# RV64-NEXT: Block RThroughput: 22.0
+
+# CHECK: Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects (U)
+
+# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
+
+# RV32-NEXT: 1 8 8.00 div a0, a0, a0
+# RV64-NEXT: 1 11 11.00 div a0, a0, a0
+
+# CHECK-NEXT: 1 2 1.00 mul t0, a0, t0
+# CHECK-NEXT: 1 1 1.00 add t1, a0, t0
+# CHECK-NEXT: 1 1 1.00 add t2, t2, t2
+
+# RV32-NEXT: 1 8 8.00 div a1, a1, a1
+# RV64-NEXT: 1 11 11.00 div a1, a1, a1
+
+# CHECK-NEXT: 1 2 1.00 mul s0, a1, s0
+# CHECK-NEXT: 1 1 1.00 add s1, s1, s0
+# CHECK-NEXT: 1 1 1.00 add s2, s2, s2
+
+# CHECK: Resources:
+
+# RV32-NEXT: [0] - SCR3RV32_ALU
+# RV32-NEXT: [1] - SCR3RV32_CFU
+# RV32-NEXT: [2] - SCR3RV32_DIV
+# RV32-NEXT: [3] - SCR3RV32_LSU
+# RV32-NEXT: [4] - SCR3RV32_MUL
+
+# RV64-NEXT: [0] - SCR3RV64_ALU
+# RV64-NEXT: [1] - SCR3RV64_CFU
+# RV64-NEXT: [2] - SCR3RV64_DIV
+# RV64-NEXT: [3] - SCR3RV64_LSU
+# RV64-NEXT: [4] - SCR3RV64_MUL
+
+# CHECK: Resource pressure per iteration:
+# CHECK-NEXT: [0] [1] [2] [3] [4]
+
+# RV32-NEXT: 4.00 - 16.00 - 2.00
+# RV64-NEXT: 4.00 - 22.00 - 2.00
+
+# CHECK: Resource pressure by instruction:
+# CHECK-NEXT: [0] [1] [2] [3] [4] Instructions:
+
+# RV32-NEXT: - - 8.00 - - div a0, a0, a0
+# RV64-NEXT: - - 11.00 - - div a0, a0, a0
+
+# CHECK-NEXT: - - - - 1.00 mul t0, a0, t0
+# CHECK-NEXT: 1.00 - - - - add t1, a0, t0
+# CHECK-NEXT: 1.00 - - - - add t2, t2, t2
+
+# RV32-NEXT: - - 8.00 - - div a1, a1, a1
+# RV64-NEXT: - - 11.00 - - div a1, a1, a1
+
+# CHECK-NEXT: - - - - 1.00 mul s0, a1, s0
+# CHECK-NEXT: 1.00 - - - - add s1, s1, s0
+# CHECK-NEXT: 1.00 - - - - add s2, s2, s2
diff --git a/llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-LSU.s b/llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-LSU.s
new file mode 100644
index 0000000000000..dc8ff80198ea5
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/RISCV/SyntacoreSCR/SCR3-LSU.s
@@ -0,0 +1,57 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -mtriple=riscv64-unknown-unknown -mcpu=syntacore-scr3-rv64 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV64
+# RUN: llvm-mca -mtriple=riscv32-unknown-unknown -mcpu=syntacore-scr3-rv32 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV32
+
+lw a0, 0(s0)
+lw a1, 0(s0)
+lw a2, 0(s0)
+lw a3, 0(s0)
+
+# CHECK: Iterations: 1
+# CHECK-NEXT: Instructions: 4
+# CHECK-NEXT: Total Cycles: 6
+# CHECK-NEXT: Total uOps: 4
+
+# CHECK: Dispatch Width: 1
+# CHECK-NEXT: uOps Per Cycle: 0.67
+# CHECK-NEXT: IPC: 0.67
+# CHECK-NEXT: Block RThroughput: 4.0
+
+# CHECK: Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects (U)
+
+# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
+# CHECK-NEXT: 1 2 1.00 * lw a0, 0(s0)
+# CHECK-NEXT: 1 2 1.00 * lw a1, 0(s0)
+# CHECK-NEXT: 1 2 1.00 * lw a2, 0(s0)
+# CHECK-NEXT: 1 2 1.00 * lw a3, 0(s0)
+
+# CHECK: Resources:
+
+# RV32-NEXT: [0] - SCR3RV32_ALU
+# RV32-NEXT: [1] - SCR3RV32_CFU
+# RV32-NEXT: [2] - SCR3RV32_DIV
+# RV32-NEXT: [3] - SCR3RV32_LSU
+# RV32-NEXT: [4] - SCR3RV32_MUL
+
+# RV64-NEXT: [0] - SCR3RV64_ALU
+# RV64-NEXT: [1] - SCR3RV64_CFU
+# RV64-NEXT: [2] - SCR3RV64_DIV
+# RV64-NEXT: [3] - SCR3RV64_LSU
+# RV64-NEXT: [4] - SCR3RV64_MUL
+
+# CHECK: Resource pressure per iteration:
+# CHECK-NEXT: [0] [1] [2] [3] [4]
+# CHECK-NEXT: - - - 4.00 -
+
+# CHECK: Resource pressure by instruction:
+# CHECK-NEXT: [0] [1] [2] [3] [4] Instructions:
+# CHECK-NEXT: - - - 1.00 - lw a0, 0(s0)
+# CHECK-NEXT: - - - 1.00 - lw a1, 0(s0)
+# CHECK-NEXT: - - - 1.00 - lw a2, 0(s0)
+# CHECK-NEXT: - - - 1.00 - lw a3, 0(s0)
More information about the llvm-commits
mailing list