Skip to content

Commit b458744

Browse files
asi-scdnpetrov-sc
authored andcommitted
[RISCV] Add scheduling model for Syntacore SCR3 (llvm#95427)
Syntacore SCR3 is a microcontroller-class processor core. Overview: https://syntacore.com/products/scr3 Co-authored-by: Dmitrii Petrov <[email protected]>
1 parent 7d1766a commit b458744

File tree

5 files changed

+340
-2
lines changed

5 files changed

+340
-2
lines changed

llvm/lib/Target/RISCV/RISCV.td

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ include "RISCVSchedSiFive7.td"
5151
include "RISCVSchedSiFiveP400.td"
5252
include "RISCVSchedSiFiveP600.td"
5353
include "RISCVSchedSyntacoreSCR1.td"
54+
include "RISCVSchedSyntacoreSCR3.td"
5455
include "RISCVSchedXiangShanNanHu.td"
5556

5657
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVProcessors.td

+2-2
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ def SYNTACORE_SCR1_MAX : RISCVProcessorModel<"syntacore-scr1-max",
327327
[TuneNoDefaultUnroll]>;
328328

329329
def SYNTACORE_SCR3_RV32 : RISCVProcessorModel<"syntacore-scr3-rv32",
330-
NoSchedModel,
330+
SyntacoreSCR3RV32Model,
331331
[Feature32Bit,
332332
FeatureStdExtI,
333333
FeatureStdExtZicsr,
@@ -337,7 +337,7 @@ def SYNTACORE_SCR3_RV32 : RISCVProcessorModel<"syntacore-scr3-rv32",
337337
[TuneNoDefaultUnroll, FeaturePostRAScheduler]>;
338338

339339
def SYNTACORE_SCR3_RV64 : RISCVProcessorModel<"syntacore-scr3-rv64",
340-
NoSchedModel,
340+
SyntacoreSCR3RV64Model,
341341
[Feature64Bit,
342342
FeatureStdExtI,
343343
FeatureStdExtZicsr,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
//==- RISCVSchedSyntacoreSCR3.td - Syntacore SCR3 Scheduling Definitions -*- tablegen -*-=//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
//===----------------------------------------------------------------------===//
10+
11+
// This model covers SYNTACORE_SCR3_RV32IMC and SYNTACORE_RV64IMAC
12+
// configurations (syntacore-scr3-rv32/64).
13+
// Overview: https://syntacore.com/products/scr3
14+
15+
// SCR3 is single-issue in-order processor
16+
class SyntacoreSCR3Model : SchedMachineModel {
17+
let MicroOpBufferSize = 0;
18+
let IssueWidth = 1;
19+
let LoadLatency = 2;
20+
let MispredictPenalty = 3;
21+
let CompleteModel = 0;
22+
let UnsupportedFeatures = [HasStdExtD, HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,
23+
HasStdExtZknd, HasStdExtZkne, HasStdExtZknh,
24+
HasStdExtZksed, HasStdExtZksh, HasStdExtZkr,
25+
HasVInstructions];
26+
}
27+
28+
// Branching
29+
multiclass SCR3_Branching<ProcResourceKind BRU> {
30+
def : WriteRes<WriteJmp, [BRU]>;
31+
def : WriteRes<WriteJal, [BRU]>;
32+
def : WriteRes<WriteJalr, [BRU]>;
33+
}
34+
35+
// Single-cycle integer arithmetic and logic
36+
multiclass SCR3_IntALU<ProcResourceKind ALU> {
37+
def : WriteRes<WriteIALU, [ALU]>;
38+
def : WriteRes<WriteIALU32, [ALU]>;
39+
def : WriteRes<WriteShiftImm, [ALU]>;
40+
def : WriteRes<WriteShiftImm32, [ALU]>;
41+
def : WriteRes<WriteShiftReg, [ALU]>;
42+
def : WriteRes<WriteShiftReg32, [ALU]>;
43+
}
44+
45+
// Integer multiplication
46+
multiclass SCR3_IntMul<ProcResourceKind MUL> {
47+
let Latency = 2 in {
48+
def : WriteRes<WriteIMul, [MUL]>;
49+
def : WriteRes<WriteIMul32, [MUL]>;
50+
}
51+
}
52+
53+
// Integer division
54+
multiclass SCR3_IntDiv<ProcResourceKind DIV, int DivLatency> {
55+
let Latency = DivLatency, ReleaseAtCycles = [DivLatency] in {
56+
def : WriteRes<WriteIDiv, [DIV]>;
57+
def : WriteRes<WriteIDiv32, [DIV]>;
58+
def : WriteRes<WriteIRem, [DIV]>;
59+
def : WriteRes<WriteIRem32, [DIV]>;
60+
}
61+
}
62+
63+
// Load/store instructions on SCR3 have latency 2
64+
multiclass SCR3_Memory<ProcResourceKind LSU> {
65+
let Latency = 2 in {
66+
def : WriteRes<WriteSTB, [LSU]>;
67+
def : WriteRes<WriteSTH, [LSU]>;
68+
def : WriteRes<WriteSTW, [LSU]>;
69+
def : WriteRes<WriteSTD, [LSU]>;
70+
def : WriteRes<WriteLDB, [LSU]>;
71+
def : WriteRes<WriteLDH, [LSU]>;
72+
def : WriteRes<WriteLDW, [LSU]>;
73+
def : WriteRes<WriteLDD, [LSU]>;
74+
}
75+
}
76+
77+
// Atomic memory
78+
multiclass SCR3_AtomicMemory<ProcResourceKind LSU> {
79+
let Latency = 20 in {
80+
def : WriteRes<WriteAtomicLDW, [LSU]>;
81+
def : WriteRes<WriteAtomicLDD, [LSU]>;
82+
def : WriteRes<WriteAtomicW, [LSU]>;
83+
def : WriteRes<WriteAtomicD, [LSU]>;
84+
def : WriteRes<WriteAtomicSTW, [LSU]>;
85+
def : WriteRes<WriteAtomicSTD, [LSU]>;
86+
}
87+
}
88+
89+
// Others
90+
multiclass SCR3_Other {
91+
def : WriteRes<WriteCSR, []>;
92+
def : WriteRes<WriteNop, []>;
93+
94+
def : InstRW<[WriteIALU], (instrs COPY)>;
95+
}
96+
97+
98+
multiclass SCR3_Unsupported {
99+
defm : UnsupportedSchedD;
100+
defm : UnsupportedSchedF;
101+
defm : UnsupportedSchedSFB;
102+
defm : UnsupportedSchedV;
103+
defm : UnsupportedSchedXsfvcp;
104+
defm : UnsupportedSchedZabha;
105+
defm : UnsupportedSchedZba;
106+
defm : UnsupportedSchedZbb;
107+
defm : UnsupportedSchedZbc;
108+
defm : UnsupportedSchedZbs;
109+
defm : UnsupportedSchedZbkb;
110+
defm : UnsupportedSchedZbkx;
111+
defm : UnsupportedSchedZfa;
112+
defm : UnsupportedSchedZfh;
113+
defm : UnsupportedSchedZvk;
114+
}
115+
116+
// Bypasses (none)
117+
multiclass SCR3_NoReadAdvances {
118+
def : ReadAdvance<ReadJmp, 0>;
119+
def : ReadAdvance<ReadJalr, 0>;
120+
def : ReadAdvance<ReadCSR, 0>;
121+
def : ReadAdvance<ReadStoreData, 0>;
122+
def : ReadAdvance<ReadMemBase, 0>;
123+
def : ReadAdvance<ReadIALU, 0>;
124+
def : ReadAdvance<ReadIALU32, 0>;
125+
def : ReadAdvance<ReadShiftImm, 0>;
126+
def : ReadAdvance<ReadShiftImm32, 0>;
127+
def : ReadAdvance<ReadShiftReg, 0>;
128+
def : ReadAdvance<ReadShiftReg32, 0>;
129+
def : ReadAdvance<ReadIDiv, 0>;
130+
def : ReadAdvance<ReadIDiv32, 0>;
131+
def : ReadAdvance<ReadIRem, 0>;
132+
def : ReadAdvance<ReadIRem32, 0>;
133+
def : ReadAdvance<ReadIMul, 0>;
134+
def : ReadAdvance<ReadIMul32, 0>;
135+
def : ReadAdvance<ReadAtomicWA, 0>;
136+
def : ReadAdvance<ReadAtomicWD, 0>;
137+
def : ReadAdvance<ReadAtomicDA, 0>;
138+
def : ReadAdvance<ReadAtomicDD, 0>;
139+
def : ReadAdvance<ReadAtomicLDW, 0>;
140+
def : ReadAdvance<ReadAtomicLDD, 0>;
141+
def : ReadAdvance<ReadAtomicSTW, 0>;
142+
def : ReadAdvance<ReadAtomicSTD, 0>;
143+
}
144+
145+
def SyntacoreSCR3RV32Model : SyntacoreSCR3Model;
146+
147+
let SchedModel = SyntacoreSCR3RV32Model in {
148+
let BufferSize = 0 in {
149+
def SCR3RV32_ALU : ProcResource<1>;
150+
def SCR3RV32_MUL : ProcResource<1>;
151+
def SCR3RV32_DIV : ProcResource<1>;
152+
def SCR3RV32_LSU : ProcResource<1>;
153+
def SCR3RV32_CFU : ProcResource<1>;
154+
}
155+
156+
defm : SCR3_Branching<SCR3RV32_CFU>;
157+
defm : SCR3_IntALU<SCR3RV32_ALU>;
158+
defm : SCR3_IntMul<SCR3RV32_MUL>;
159+
defm : SCR3_IntDiv<SCR3RV32_DIV, /* div latency = */ 8>;
160+
defm : SCR3_Memory<SCR3RV32_LSU>;
161+
defm : SCR3_AtomicMemory<SCR3RV32_LSU>;
162+
defm : SCR3_Other;
163+
164+
defm : SCR3_Unsupported;
165+
defm : SCR3_NoReadAdvances;
166+
}
167+
168+
def SyntacoreSCR3RV64Model : SyntacoreSCR3Model;
169+
170+
let SchedModel = SyntacoreSCR3RV64Model in {
171+
let BufferSize = 0 in {
172+
def SCR3RV64_ALU : ProcResource<1>;
173+
def SCR3RV64_MUL : ProcResource<1>;
174+
def SCR3RV64_DIV : ProcResource<1>;
175+
def SCR3RV64_LSU : ProcResource<1>;
176+
def SCR3RV64_CFU : ProcResource<1>;
177+
}
178+
179+
defm : SCR3_Branching<SCR3RV64_CFU>;
180+
defm : SCR3_IntALU<SCR3RV64_ALU>;
181+
defm : SCR3_IntMul<SCR3RV64_MUL>;
182+
defm : SCR3_IntDiv<SCR3RV64_DIV, /* div latency = */ 11>;
183+
defm : SCR3_Memory<SCR3RV64_LSU>;
184+
defm : SCR3_AtomicMemory<SCR3RV64_LSU>;
185+
defm : SCR3_Other;
186+
187+
defm : SCR3_Unsupported;
188+
defm : SCR3_NoReadAdvances;
189+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
2+
# RUN: llvm-mca -mtriple=riscv64-unknown-unknown -mcpu=syntacore-scr3-rv64 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV64
3+
# RUN: llvm-mca -mtriple=riscv32-unknown-unknown -mcpu=syntacore-scr3-rv32 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV32
4+
5+
div a0, a0, a0
6+
mul t0, a0, t0
7+
add t1, a0, t0
8+
add t2, t2, t2
9+
div a1, a1, a1
10+
mul s0, a1, s0
11+
add s1, s0, s1
12+
add s2, s2, s2
13+
14+
# CHECK: Iterations: 1
15+
# CHECK-NEXT: Instructions: 8
16+
17+
# RV32-NEXT: Total Cycles: 25
18+
# RV64-NEXT: Total Cycles: 31
19+
20+
# CHECK-NEXT: Total uOps: 8
21+
22+
# CHECK: Dispatch Width: 1
23+
24+
# RV32-NEXT: uOps Per Cycle: 0.32
25+
# RV32-NEXT: IPC: 0.32
26+
# RV32-NEXT: Block RThroughput: 16.0
27+
28+
# RV64-NEXT: uOps Per Cycle: 0.26
29+
# RV64-NEXT: IPC: 0.26
30+
# RV64-NEXT: Block RThroughput: 22.0
31+
32+
# CHECK: Instruction Info:
33+
# CHECK-NEXT: [1]: #uOps
34+
# CHECK-NEXT: [2]: Latency
35+
# CHECK-NEXT: [3]: RThroughput
36+
# CHECK-NEXT: [4]: MayLoad
37+
# CHECK-NEXT: [5]: MayStore
38+
# CHECK-NEXT: [6]: HasSideEffects (U)
39+
40+
# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
41+
42+
# RV32-NEXT: 1 8 8.00 div a0, a0, a0
43+
# RV64-NEXT: 1 11 11.00 div a0, a0, a0
44+
45+
# CHECK-NEXT: 1 2 1.00 mul t0, a0, t0
46+
# CHECK-NEXT: 1 1 1.00 add t1, a0, t0
47+
# CHECK-NEXT: 1 1 1.00 add t2, t2, t2
48+
49+
# RV32-NEXT: 1 8 8.00 div a1, a1, a1
50+
# RV64-NEXT: 1 11 11.00 div a1, a1, a1
51+
52+
# CHECK-NEXT: 1 2 1.00 mul s0, a1, s0
53+
# CHECK-NEXT: 1 1 1.00 add s1, s1, s0
54+
# CHECK-NEXT: 1 1 1.00 add s2, s2, s2
55+
56+
# CHECK: Resources:
57+
58+
# RV32-NEXT: [0] - SCR3RV32_ALU
59+
# RV32-NEXT: [1] - SCR3RV32_CFU
60+
# RV32-NEXT: [2] - SCR3RV32_DIV
61+
# RV32-NEXT: [3] - SCR3RV32_LSU
62+
# RV32-NEXT: [4] - SCR3RV32_MUL
63+
64+
# RV64-NEXT: [0] - SCR3RV64_ALU
65+
# RV64-NEXT: [1] - SCR3RV64_CFU
66+
# RV64-NEXT: [2] - SCR3RV64_DIV
67+
# RV64-NEXT: [3] - SCR3RV64_LSU
68+
# RV64-NEXT: [4] - SCR3RV64_MUL
69+
70+
# CHECK: Resource pressure per iteration:
71+
# CHECK-NEXT: [0] [1] [2] [3] [4]
72+
73+
# RV32-NEXT: 4.00 - 16.00 - 2.00
74+
# RV64-NEXT: 4.00 - 22.00 - 2.00
75+
76+
# CHECK: Resource pressure by instruction:
77+
# CHECK-NEXT: [0] [1] [2] [3] [4] Instructions:
78+
79+
# RV32-NEXT: - - 8.00 - - div a0, a0, a0
80+
# RV64-NEXT: - - 11.00 - - div a0, a0, a0
81+
82+
# CHECK-NEXT: - - - - 1.00 mul t0, a0, t0
83+
# CHECK-NEXT: 1.00 - - - - add t1, a0, t0
84+
# CHECK-NEXT: 1.00 - - - - add t2, t2, t2
85+
86+
# RV32-NEXT: - - 8.00 - - div a1, a1, a1
87+
# RV64-NEXT: - - 11.00 - - div a1, a1, a1
88+
89+
# CHECK-NEXT: - - - - 1.00 mul s0, a1, s0
90+
# CHECK-NEXT: 1.00 - - - - add s1, s1, s0
91+
# CHECK-NEXT: 1.00 - - - - add s2, s2, s2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
2+
# RUN: llvm-mca -mtriple=riscv64-unknown-unknown -mcpu=syntacore-scr3-rv64 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV64
3+
# RUN: llvm-mca -mtriple=riscv32-unknown-unknown -mcpu=syntacore-scr3-rv32 --iterations=1 < %s | FileCheck %s --check-prefixes=CHECK,RV32
4+
5+
lw a0, 0(s0)
6+
lw a1, 0(s0)
7+
lw a2, 0(s0)
8+
lw a3, 0(s0)
9+
10+
# CHECK: Iterations: 1
11+
# CHECK-NEXT: Instructions: 4
12+
# CHECK-NEXT: Total Cycles: 6
13+
# CHECK-NEXT: Total uOps: 4
14+
15+
# CHECK: Dispatch Width: 1
16+
# CHECK-NEXT: uOps Per Cycle: 0.67
17+
# CHECK-NEXT: IPC: 0.67
18+
# CHECK-NEXT: Block RThroughput: 4.0
19+
20+
# CHECK: Instruction Info:
21+
# CHECK-NEXT: [1]: #uOps
22+
# CHECK-NEXT: [2]: Latency
23+
# CHECK-NEXT: [3]: RThroughput
24+
# CHECK-NEXT: [4]: MayLoad
25+
# CHECK-NEXT: [5]: MayStore
26+
# CHECK-NEXT: [6]: HasSideEffects (U)
27+
28+
# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
29+
# CHECK-NEXT: 1 2 1.00 * lw a0, 0(s0)
30+
# CHECK-NEXT: 1 2 1.00 * lw a1, 0(s0)
31+
# CHECK-NEXT: 1 2 1.00 * lw a2, 0(s0)
32+
# CHECK-NEXT: 1 2 1.00 * lw a3, 0(s0)
33+
34+
# CHECK: Resources:
35+
36+
# RV32-NEXT: [0] - SCR3RV32_ALU
37+
# RV32-NEXT: [1] - SCR3RV32_CFU
38+
# RV32-NEXT: [2] - SCR3RV32_DIV
39+
# RV32-NEXT: [3] - SCR3RV32_LSU
40+
# RV32-NEXT: [4] - SCR3RV32_MUL
41+
42+
# RV64-NEXT: [0] - SCR3RV64_ALU
43+
# RV64-NEXT: [1] - SCR3RV64_CFU
44+
# RV64-NEXT: [2] - SCR3RV64_DIV
45+
# RV64-NEXT: [3] - SCR3RV64_LSU
46+
# RV64-NEXT: [4] - SCR3RV64_MUL
47+
48+
# CHECK: Resource pressure per iteration:
49+
# CHECK-NEXT: [0] [1] [2] [3] [4]
50+
# CHECK-NEXT: - - - 4.00 -
51+
52+
# CHECK: Resource pressure by instruction:
53+
# CHECK-NEXT: [0] [1] [2] [3] [4] Instructions:
54+
# CHECK-NEXT: - - - 1.00 - lw a0, 0(s0)
55+
# CHECK-NEXT: - - - 1.00 - lw a1, 0(s0)
56+
# CHECK-NEXT: - - - 1.00 - lw a2, 0(s0)
57+
# CHECK-NEXT: - - - 1.00 - lw a3, 0(s0)

0 commit comments

Comments
 (0)