diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -215,8 +215,7 @@ include "RISCVCallingConv.td" include "RISCVInstrInfo.td" include "RISCVRegisterBanks.td" -include "RISCVSchedRocket32.td" -include "RISCVSchedRocket64.td" +include "RISCVSchedRocket.td" //===----------------------------------------------------------------------===// // RISC-V processors supported. @@ -226,20 +225,20 @@ def : ProcessorModel<"generic-rv64", NoSchedModel, [Feature64Bit]>; -def : ProcessorModel<"rocket-rv32", Rocket32Model, []>; +def : ProcessorModel<"rocket-rv32", RocketModel, []>; -def : ProcessorModel<"rocket-rv64", Rocket64Model, [Feature64Bit]>; +def : ProcessorModel<"rocket-rv64", RocketModel, [Feature64Bit]>; -def : ProcessorModel<"sifive-e31", Rocket32Model, [FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; +def : ProcessorModel<"sifive-e31", RocketModel, [FeatureStdExtA, + FeatureStdExtC, + FeatureStdExtM]>; -def : ProcessorModel<"sifive-u54", Rocket64Model, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC]>; +def : ProcessorModel<"sifive-u54", RocketModel, [Feature64Bit, + FeatureStdExtA, + FeatureStdExtC, + FeatureStdExtD, + FeatureStdExtF, + FeatureStdExtM]>; //===----------------------------------------------------------------------===// // Define the RISC-V target. diff --git a/llvm/lib/Target/RISCV/RISCVSchedRocket.td b/llvm/lib/Target/RISCV/RISCVSchedRocket.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVSchedRocket.td @@ -0,0 +1,233 @@ +//==- RISCVSchedRocket.td - Rocket 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 +// +//===----------------------------------------------------------------------===// + +// ===---------------------------------------------------------------------===// +// The following definitions describe the simpler per-operand machine model. +// This works with MachineScheduler. See MCSchedule.h for details. + +// Rocket machine model for scheduling and other instruction cost heuristics. +def RocketModel : SchedMachineModel { + let MicroOpBufferSize = 0; // Rocket is in-order. + let IssueWidth = 1; // 1 micro-op is dispatched per cycle. + let LoadLatency = 3; + let MispredictPenalty = 3; + let UnsupportedFeatures = [HasStdExtV, HasStdExtZvamo, HasStdExtZvlsseg]; +} + +//===----------------------------------------------------------------------===// +// Define each kind of processor resource and number available. + +// Modeling each pipeline as a ProcResource using the BufferSize = 0 since +// Rocket is in-order. + +let BufferSize = 0 in { +def RocketUnitALU : ProcResource<1>; // Int ALU +def RocketUnitIMul : ProcResource<1>; // Int Multiply +def RocketUnitMem : ProcResource<1>; // Load/Store +def RocketUnitB : ProcResource<1>; // Branch + +def RocketUnitFPALU : ProcResource<1>; // FP ALU +} + +let BufferSize = 1 in { +def RocketUnitIDiv : ProcResource<1>; // Int Division +def RocketUnitFPDivSqrt : ProcResource<1>; // FP Divide/Sqrt +} + +//===----------------------------------------------------------------------===// + +let SchedModel = RocketModel in { + +// Branching +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// Integer arithmetic and logic +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// Integer multiplication +let Latency = 4 in { +def : WriteRes; +def : WriteRes; +} + +// Integer division +// Worst case latency is used. +def : WriteRes { + let Latency = 34; + let ResourceCycles = [34]; +} +def : WriteRes { + let Latency = 33; + let ResourceCycles = [33]; +} + +// Memory +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +let Latency = 3 in { +def : WriteRes; +def : WriteRes; +} + +let Latency = 2 in { +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// Atomic memory +def : WriteRes; +def : WriteRes; + +def : WriteRes; +def : WriteRes; +} + +def : WriteRes; +def : WriteRes; + +// Single precision. +let Latency = 4 in { +def : WriteRes; +def : WriteRes; +def : WriteRes; +} + +// Double precision +let Latency = 6 in { +def : WriteRes; +def : WriteRes; +def : WriteRes; +} + +// Conversions +let Latency = 2 in { +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +} + +// FP multiplication +let Latency = 5 in { +def : WriteRes; +def : WriteRes; +def : WriteRes; +} + +let Latency = 7 in { +def : WriteRes; +def : WriteRes; +def : WriteRes; +} + +// FP division +// FP division unit on Rocket is not pipelined, so set resource cycles to latency. +let Latency = 20, ResourceCycles = [20] in { +def : WriteRes; +def : WriteRes; +} + +// FP square root unit on Rocket is not pipelined, so set resource cycles to latency. +def : WriteRes { let Latency = 20; + let ResourceCycles = [20]; } +def : WriteRes { let Latency = 25; + let ResourceCycles = [25]; } + +// Others +def : WriteRes; +def : WriteRes; + +def : InstRW<[WriteIALU], (instrs COPY)>; + +//===----------------------------------------------------------------------===// +// Bypass and advance +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 : 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 : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +} diff --git a/llvm/lib/Target/RISCV/RISCVSchedRocket32.td b/llvm/lib/Target/RISCV/RISCVSchedRocket32.td deleted file mode 100644 --- a/llvm/lib/Target/RISCV/RISCVSchedRocket32.td +++ /dev/null @@ -1,227 +0,0 @@ -//==- RISCVSchedRocket32.td - Rocket 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 -// -//===----------------------------------------------------------------------===// - -// ===---------------------------------------------------------------------===// -// The following definitions describe the simpler per-operand machine model. -// This works with MachineScheduler. See MCSchedule.h for details. - -// Rocket machine model for scheduling and other instruction cost heuristics. -def Rocket32Model : SchedMachineModel { - let MicroOpBufferSize = 0; // Explicitly set to zero since Rocket is in-order. - let IssueWidth = 1; // 1 micro-ops are dispatched per cycle. - let LoadLatency = 3; - let MispredictPenalty = 3; - let CompleteModel = 1; - let UnsupportedFeatures = [HasStdExtV, HasStdExtZvlsseg, HasStdExtZvamo]; -} - -//===----------------------------------------------------------------------===// -// Define each kind of processor resource and number available. - -// Modeling each pipeline as a ProcResource using the BufferSize = 0 since -// Rocket is in-order. - -let BufferSize = 0 in { -def Rocket32UnitALU : ProcResource<1>; // Int ALU -def Rocket32UnitIMul : ProcResource<1>; // Int Multiply -def Rocket32UnitMem : ProcResource<1>; // Load/Store -def Rocket32UnitB : ProcResource<1>; // Branch - -def Rocket32UnitFPALU : ProcResource<1>; // FP ALU -} - -let BufferSize = 1 in { -def Rocket32UnitIDiv : ProcResource<1>; // Int Division -def Rocket32UnitFPDivSqrt : ProcResource<1>; // FP Divide/Sqrt' -} - -//===----------------------------------------------------------------------===// -// Subtarget-specific SchedWrite types which both map the ProcResources and -// set the latency. - -let SchedModel = Rocket32Model in { - -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -def : WriteRes; -def : WriteRes; - -// Multiplies on Rocket differ by implementation; placeholder until -// we can determine how to read from command line -def : WriteRes { let Latency = 4; } - -// 32-bit divides have worse case latency of 34 cycle -def : WriteRes { - let Latency = 34; - let ResourceCycles = [34]; -} - -// Memory -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -let Latency = 3 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 2 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; - -def : WriteRes; -def : WriteRes; -} - -def : WriteRes; - -// Most FP single precision operations are 4 cycles -let Latency = 4 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -// Most FP double precision operations are 6 cycles -let Latency = 6 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 2 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 5 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 7 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -// FP Divide unit on Rocket is not pipelined, so set resource cycles to latency -let Latency = 20, ResourceCycles = [20] in { -def : WriteRes; -def : WriteRes; -} - -// FP Sqrt unit on Rocket is not pipelined, so set resource cycles to latency -def : WriteRes { let Latency = 20; - let ResourceCycles = [20];} -def : WriteRes { let Latency = 25; - let ResourceCycles = [25];} - -def : WriteRes; - -def : InstRW<[WriteIALU], (instrs COPY)>; - -let Unsupported = 1 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -//===----------------------------------------------------------------------===// -// Subtarget-specific SchedRead types with cycles. -// Dummy definitions for RocketCore. -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 : 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 : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -} diff --git a/llvm/lib/Target/RISCV/RISCVSchedRocket64.td b/llvm/lib/Target/RISCV/RISCVSchedRocket64.td deleted file mode 100644 --- a/llvm/lib/Target/RISCV/RISCVSchedRocket64.td +++ /dev/null @@ -1,228 +0,0 @@ -//==- RISCVSchedRocket64.td - Rocket 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 -// -//===----------------------------------------------------------------------===// - -// ===---------------------------------------------------------------------===// -// The following definitions describe the simpler per-operand machine model. -// This works with MachineScheduler. See MCSchedule.h for details. - -// Rocket machine model for scheduling and other instruction cost heuristics. -def Rocket64Model : SchedMachineModel { - let MicroOpBufferSize = 0; // Explicitly set to zero since Rocket is in-order. - let IssueWidth = 1; // 1 micro-ops are dispatched per cycle. - let LoadLatency = 3; - let MispredictPenalty = 3; - let UnsupportedFeatures = [HasStdExtV, HasStdExtZvlsseg, HasStdExtZvamo]; -} - -//===----------------------------------------------------------------------===// -// Define each kind of processor resource and number available. - -// Modeling each pipeline as a ProcResource using the BufferSize = 0 since -// Rocket is in-order. - -let BufferSize = 0 in { -def Rocket64UnitALU : ProcResource<1>; // Int ALU -def Rocket64UnitIMul : ProcResource<1>; // Int Multiply -def Rocket64UnitMem : ProcResource<1>; // Load/Store -def Rocket64UnitB : ProcResource<1>; // Branch - -def Rocket64UnitFPALU : ProcResource<1>; // FP ALU -} - -let BufferSize = 1 in { -def Rocket64UnitIDiv : ProcResource<1>; // Int Division -def Rocket64UnitFPDivSqrt : ProcResource<1>; // FP Divide/Sqrt -} - -//===----------------------------------------------------------------------===// -// Subtarget-specific SchedWrite types which both map the ProcResources and -// set the latency. - -let SchedModel = Rocket64Model in { - -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -let Latency = 4 in { -def : WriteRes; -def : WriteRes; -} - -// Integer divide varies based on operand magnitude and sign; worse case latency is 34. -def : WriteRes { - let Latency = 34; - let ResourceCycles = [34]; -} -def : WriteRes { - let Latency = 33; - let ResourceCycles = [33]; -} - -// Memory -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -let Latency = 3 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 2 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -def : WriteRes; -def : WriteRes; - -def : WriteRes; -def : WriteRes; -} - -def : WriteRes; -def : WriteRes; - -// Most FP single precision operations are 4 cycles -let Latency = 4 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 6 in { -// Most FP double precision operations are 6 cycles -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -// Conversion instructions -let Latency = 2 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; - -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 5 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -let Latency = 7 in { -def : WriteRes; -def : WriteRes; -def : WriteRes; -} - -// FP Divide unit on Rocket is not pipelined, so set resource cycles to latency -let Latency = 20, ResourceCycles = [20] in { -def : WriteRes; -def : WriteRes; -} - -// FP Sqrt unit on Rocket is not pipelined, so set resource cycles to latency -def : WriteRes { let Latency = 20; - let ResourceCycles = [20]; } -def : WriteRes { let Latency = 25; - let ResourceCycles = [25]; } - -def : WriteRes; - -def : InstRW<[WriteIALU], (instrs COPY)>; - -//===----------------------------------------------------------------------===// -// Subtarget-specific SchedRead types with cycles. -// Dummy definitions for RocketCore. -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 : 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 : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -def : ReadAdvance; -}