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 { + def : WriteRes; + def : WriteRes; + def : WriteRes; +} + +// Single-cycle integer arithmetic and logic +multiclass SCR3_IntALU { + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; +} + +// Integer multiplication +multiclass SCR3_IntMul { + let Latency = 2 in { + def : WriteRes; + def : WriteRes; + } +} + +// Integer division +multiclass SCR3_IntDiv { + let Latency = DivLatency, ReleaseAtCycles = [DivLatency] in { + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + } +} + +// Load/store instructions on SCR3 have latency 2 +multiclass SCR3_Memory { + let Latency = 2 in { + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + } +} + +// Atomic memory +multiclass SCR3_AtomicMemory { + let Latency = 20 in { + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + def : WriteRes; + } +} + +// Others +multiclass SCR3_Other { + def : WriteRes; + def : WriteRes; + + 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; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; + def : ReadAdvance; +} + +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; + defm : SCR3_IntALU; + defm : SCR3_IntMul; + defm : SCR3_IntDiv; + defm : SCR3_Memory; + defm : SCR3_AtomicMemory; + 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; + defm : SCR3_IntALU; + defm : SCR3_IntMul; + defm : SCR3_IntDiv; + defm : SCR3_Memory; + defm : SCR3_AtomicMemory; + 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)