aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/Target')
-rw-r--r--backend/lib/Target/RISCV/CMakeLists.txt10
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp16
-rw-r--r--backend/lib/Target/RISCV/RISCV.h9
-rw-r--r--backend/lib/Target/RISCV/RISCVInstrInfoI.rccdesc10
-rw-r--r--backend/lib/Target/RISCV/RISCVMacroFusion.rccdesc139
-rw-r--r--backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp6
-rw-r--r--backend/lib/Target/RISCV/RISCVPipeline.cpp27
-rw-r--r--backend/lib/Target/RISCV/RISCVScheduling.cpp44
-rw-r--r--backend/lib/Target/RISCV/RISCVSubtarget.cpp25
9 files changed, 250 insertions, 36 deletions
diff --git a/backend/lib/Target/RISCV/CMakeLists.txt b/backend/lib/Target/RISCV/CMakeLists.txt
index 2e1e224..00de7bd 100644
--- a/backend/lib/Target/RISCV/CMakeLists.txt
+++ b/backend/lib/Target/RISCV/CMakeLists.txt
@@ -20,6 +20,7 @@ set(
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelShift.rccdesc"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelFloating.rccdesc"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelCombiner.rccdesc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/RISCVMacroFusion.rccdesc"
)
set(RCCBackendRISCVTableGenArguments)
foreach(RCCBackendRISCVDescriptionSource IN LISTS RCCBackendRISCVDescriptionSources)
@@ -45,6 +46,10 @@ set(
RCCBackendRISCVGeneratedGlobalISelCombiner
"${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenGlobalISelCombiner.inc"
)
+set(
+ RCCBackendRISCVGeneratedMacroFusion
+ "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenMacroFusion.inc"
+)
add_custom_command(
OUTPUT
@@ -53,6 +58,7 @@ add_custom_command(
"${RCCBackendRISCVGeneratedTables}"
"${RCCBackendRISCVGeneratedGlobalISel}"
"${RCCBackendRISCVGeneratedGlobalISelCombiner}"
+ "${RCCBackendRISCVGeneratedMacroFusion}"
COMMAND
"$<TARGET_FILE:RCCBackendTableGenTool>"
${RCCBackendRISCVTableGenArguments}
@@ -61,6 +67,7 @@ add_custom_command(
--tables "${RCCBackendRISCVGeneratedTables}"
--global-isel "${RCCBackendRISCVGeneratedGlobalISel}"
--global-isel-combiner "${RCCBackendRISCVGeneratedGlobalISelCombiner}"
+ --macro-fusion "${RCCBackendRISCVGeneratedMacroFusion}"
DEPENDS RCCBackendTableGenTool ${RCCBackendRISCVDescriptionSources}
COMMENT "Generating RCC RV64GC target tables"
VERBATIM
@@ -74,6 +81,7 @@ add_custom_target(
"${RCCBackendRISCVGeneratedTables}"
"${RCCBackendRISCVGeneratedGlobalISel}"
"${RCCBackendRISCVGeneratedGlobalISelCombiner}"
+ "${RCCBackendRISCVGeneratedMacroFusion}"
)
set_source_files_properties(
@@ -82,6 +90,7 @@ set_source_files_properties(
"${RCCBackendRISCVGeneratedTables}"
"${RCCBackendRISCVGeneratedGlobalISel}"
"${RCCBackendRISCVGeneratedGlobalISelCombiner}"
+ "${RCCBackendRISCVGeneratedMacroFusion}"
PROPERTIES GENERATED TRUE HEADER_FILE_ONLY TRUE
)
@@ -117,6 +126,7 @@ add_library(
"${RCCBackendRISCVGeneratedTables}"
"${RCCBackendRISCVGeneratedGlobalISel}"
"${RCCBackendRISCVGeneratedGlobalISelCombiner}"
+ "${RCCBackendRISCVGeneratedMacroFusion}"
)
add_library(RCCBackend::RISCV ALIAS RCCBackendRISCV)
add_dependencies(RCCBackendRISCV RCCBackendRISCVGeneratedTablesTarget)
diff --git a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 094f9cb..ca702ed 100644
--- a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -5,9 +5,9 @@
#include "RISCVInstrInfo.h"
#include "RISCVRegisterBankInfo.h"
#include "rcc/CodeGen/GenericOpcodes.h"
-#include "rcc/CodeGen/GlobalObject.h"
#include "rcc/CodeGen/GlobalISel/GISelValueTracking.h"
#include "rcc/CodeGen/GlobalISel/InstructionSelector.h"
+#include "rcc/CodeGen/GlobalObject.h"
#include "rcc/CodeGen/LowLevelType.h"
#include "rcc/CodeGen/MachineBasicBlock.h"
#include "rcc/CodeGen/MachineFunction.h"
@@ -727,8 +727,8 @@ public:
}
private:
- [[nodiscard]] Expected<const MachineMemOperand *>
- createGOTLoad(MachineFunction &Function, LowLevelType Type) const {
+ [[nodiscard]] Expected<const MachineMemOperand *> createGOTLoad(MachineFunction &Function,
+ LowLevelType Type) const {
auto Size = MemorySize::fixed(Type.minimumBitWidth() / 8U);
if (!Size)
return std::unexpected(Size.error());
@@ -745,9 +745,9 @@ private:
return Function.createMemOperand(std::move(Description));
}
- [[nodiscard]] Expected<void>
- selectGlobalAddress(MachineInstr &Instruction, MachineFunction &Function,
- const TargetDescription &Target) const {
+ [[nodiscard]] Expected<void> selectGlobalAddress(MachineInstr &Instruction,
+ MachineFunction &Function,
+ const TargetDescription &Target) const {
const MachineOperand *DestinationOperand = Instruction.operandAt(0);
const MachineOperand *SymbolOperand = Instruction.operandAt(1);
const Register *Destination =
@@ -775,8 +775,8 @@ private:
}
const bool TaggedGlobals = Subtarget.features().has(RISCVSubtargetOption::TaggedGlobals);
- const bool UseGOT = Subtarget.relocationModel() == RelocationModel::PositionIndependent ||
- TaggedGlobals;
+ const bool UseGOT =
+ Subtarget.relocationModel() == RelocationModel::PositionIndependent || TaggedGlobals;
const auto ReplaceWithPseudo = [&](InstructionOpcode OpcodeValue) -> Expected<void> {
auto SetOpcode = Instruction.setOpcode(instructionOpcode(OpcodeValue));
if (!SetOpcode)
diff --git a/backend/lib/Target/RISCV/RISCV.h b/backend/lib/Target/RISCV/RISCV.h
index 4699091..4eeaf64 100644
--- a/backend/lib/Target/RISCV/RISCV.h
+++ b/backend/lib/Target/RISCV/RISCV.h
@@ -27,13 +27,18 @@ createRISCVInstructionSelector(const RISCVSubtarget &Subtarget,
const RISCVRegisterBankInfo &RegisterBanks);
[[nodiscard]] const TargetRegisterAllocationInfo &registerAllocationInfo() noexcept;
[[nodiscard]] const TargetFrameLowering &frameLowering() noexcept;
-[[nodiscard]] const TargetSchedulingModel &schedulingModel() noexcept;
+[[nodiscard]] std::unique_ptr<TargetSchedulingHooks>
+createSchedulingHooks(const RISCVSubtargetFeatures &Features);
+[[nodiscard]] Expected<TargetSchedulingModel>
+createSchedulingModel(const TargetSchedulingHooks &Hooks);
[[nodiscard]] const TargetMachineCombinerInfo &machineCombinerInfo() noexcept;
[[nodiscard]] const GIMatchTable &giselCombinerTable() noexcept;
[[nodiscard]] const GIMatchTableExecutor &giselCombinerExecutor() noexcept;
[[nodiscard]] const TargetMemoryFoldingInfo &memoryFoldingInfo() noexcept;
[[nodiscard]] const TargetPseudoExpansionInfo &pseudoExpansionInfo() noexcept;
-[[nodiscard]] MachineOptimizationPipelineTargetInfo optimizationPipelineInfo() noexcept;
+[[nodiscard]] MachineOptimizationPipelineTargetInfo
+optimizationPipelineInfo(const RISCVSubtarget &Subtarget,
+ bool EmitSchedulerDebugOutput = false) noexcept;
} // namespace riscv
} // namespace rcc
diff --git a/backend/lib/Target/RISCV/RISCVInstrInfoI.rccdesc b/backend/lib/Target/RISCV/RISCVInstrInfoI.rccdesc
index 7bb30e5..13ea700 100644
--- a/backend/lib/Target/RISCV/RISCVInstrInfoI.rccdesc
+++ b/backend/lib/Target/RISCV/RISCVInstrInfoI.rccdesc
@@ -188,7 +188,7 @@ instructions:
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS1 }
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS2 }
num_explicit_defs: 1
- flags: [produces_code]
+ flags: [produces_code, commutable]
scheduling_class: ALU
encoding_category: R
assembly_format: RD_RS1_RS2
@@ -233,7 +233,7 @@ instructions:
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS1 }
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS2 }
num_explicit_defs: 1
- flags: [produces_code]
+ flags: [produces_code, commutable]
scheduling_class: ALU
encoding_category: R
assembly_format: RD_RS1_RS2
@@ -248,7 +248,7 @@ instructions:
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS1 }
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS2 }
num_explicit_defs: 1
- flags: [produces_code]
+ flags: [produces_code, commutable]
scheduling_class: ALU
encoding_category: R
assembly_format: RD_RS1_RS2
@@ -263,7 +263,7 @@ instructions:
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS1 }
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS2 }
num_explicit_defs: 1
- flags: [produces_code]
+ flags: [produces_code, commutable]
scheduling_class: ALU
encoding_category: R
assembly_format: RD_RS1_RS2
@@ -666,7 +666,7 @@ instructions:
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS1 }
- { kinds: [register], role: use, register_class: GPR, register_bank: GPR, name: RS2 }
num_explicit_defs: 1
- flags: [produces_code]
+ flags: [produces_code, commutable]
scheduling_class: ALU
encoding_category: R
assembly_format: RD_RS1_RS2
diff --git a/backend/lib/Target/RISCV/RISCVMacroFusion.rccdesc b/backend/lib/Target/RISCV/RISCVMacroFusion.rccdesc
new file mode 100644
index 0000000..2c432a2
--- /dev/null
+++ b/backend/lib/Target/RISCV/RISCVMacroFusion.rccdesc
@@ -0,0 +1,139 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+macro_fusion_rules:
+ -
+ id: TuneLUIADDIFusion
+ feature: fusion-lui-addi
+ first_opcodes: [LUI]
+ second_opcodes: [ADDI, ADDIW]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneAUIPCADDIFusion
+ feature: fusion-auipc-addi
+ first_opcodes: [AUIPC]
+ second_opcodes: [ADDI]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneZExtHFusion
+ feature: fusion-zexth
+ first_opcodes: [SLLI]
+ second_opcodes: [SRLI]
+ immediates:
+ - { instruction: first, operand: 2, min: 48, max: 48 }
+ - { instruction: second, operand: 2, min: 48, max: 48 }
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneZExtWFusion
+ feature: fusion-zextw
+ first_opcodes: [SLLI]
+ second_opcodes: [SRLI]
+ immediates:
+ - { instruction: first, operand: 2, min: 32, max: 32 }
+ - { instruction: second, operand: 2, min: 32, max: 32 }
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneShiftedZExtWFusion
+ feature: fusion-shifted-zextw
+ first_opcodes: [SLLI]
+ second_opcodes: [SRLI]
+ immediates:
+ - { instruction: first, operand: 2, min: 32, max: 32 }
+ - { instruction: second, operand: 2, min: 0, max: 31 }
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneLDADDFusion
+ feature: fusion-ld-add
+ first_opcodes: [ADD]
+ second_opcodes: [LD]
+ immediates:
+ - { instruction: second, operand: 2, min: 0, max: 0 }
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneADDLoadFusion
+ feature: fusion-add-load
+ first_opcodes: [ADD, ADD_UW]
+ second_opcodes: [LB, LH, LW, LD, LBU, LHU, LWU]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneAUIPCLoadFusion
+ feature: fusion-auipc-load
+ first_opcodes: [AUIPC]
+ second_opcodes: [LB, LH, LW, LD, LBU, LHU, LWU]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneLUILoadFusion
+ feature: fusion-lui-load
+ first_opcodes: [LUI]
+ second_opcodes: [LB, LH, LW, LD, LBU, LHU, LWU]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneBFExtFusion
+ feature: fusion-bfext
+ first_opcodes: [SLLI]
+ second_opcodes: [SRLI]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneADDILoadFusion
+ feature: fusion-addi-load
+ first_opcodes: [ADDI]
+ second_opcodes: [LB, LH, LW, LD, LBU, LHU, LWU]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneSHXADDLoadFusion
+ feature: fusion-shxadd-load
+ first_opcodes: [SH1ADD, SH2ADD, SH3ADD, SH1ADD_UW, SH2ADD_UW, SH3ADD_UW]
+ second_opcodes: [LB, LH, LW, LD, LBU, LHU, LWU]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneFusionLogicRegReg
+ feature: fusion-logic-reg-reg
+ first_opcodes: [AND, OR, XOR]
+ second_opcodes: [AND, OR, XOR]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, commutable_second_use: 2, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneFusionLogicRegImm
+ feature: fusion-logic-reg-imm
+ first_opcodes: [AND, OR, XOR]
+ second_opcodes: [ANDI, ORI, XORI]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneFusionLogicImmReg
+ feature: fusion-logic-imm-reg
+ first_opcodes: [ANDI, ORI, XORI]
+ second_opcodes: [AND, OR, XOR]
+ link: { first_definition: 0, second_use: 1, second_definition: 0, commutable_second_use: 2, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneFusionMulAdd
+ feature: fusion-mul-add
+ first_opcodes: [MUL, MULW]
+ second_opcodes: [ADD, ADDW]
+ opcode_pairs:
+ - { first: MUL, second: ADD }
+ - { first: MULW, second: ADDW }
+ register_not_equal:
+ - { instruction: second, left: 0, right: 2 }
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
+ -
+ id: TuneFusionAddMem
+ feature: fusion-add-mem
+ first_opcodes: [ADD]
+ second_opcodes: [LB, LBU, LH, LHU, LW, LWU, LD, FLW, FLD, SB, SH, SW, SD, FSW, FSD]
+ immediates:
+ - { instruction: second, operand: 2, min: 0, max: 0 }
+ register_not_equal:
+ - { instruction: first, left: 0, right: 1 }
+ - { instruction: first, left: 0, right: 2 }
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: false, second_destination_tied: false }
+ -
+ id: TuneFusionShiftBitExtract
+ feature: fusion-shift-bit-extract
+ first_opcodes: [SLLI, SLLIW]
+ second_opcodes: [SRLI, SRLIW, SRAI, SRAIW]
+ opcode_pairs:
+ - { first: SLLI, second: SRLI }
+ - { first: SLLI, second: SRAI }
+ - { first: SLLIW, second: SRLIW }
+ - { first: SLLIW, second: SRAIW }
+ immediate_relations:
+ - { kind: less_equal, first_operand: 2, second_operand: 2 }
+ link: { first_definition: 0, second_use: 1, second_definition: 0, one_non_debug_use: true, second_destination_tied: true }
diff --git a/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp b/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp
index 5bacc9c..7571832 100644
--- a/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp
+++ b/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp
@@ -5,14 +5,16 @@
namespace rcc::riscv {
-MachineOptimizationPipelineTargetInfo optimizationPipelineInfo() noexcept {
+MachineOptimizationPipelineTargetInfo
+optimizationPipelineInfo(const RISCVSubtarget &Subtarget, bool EmitSchedulerDebugOutput) noexcept {
return {
.InstrInfo = instrInfo(),
.Combiner = machineCombinerInfo(),
.MemoryFolding = memoryFoldingInfo(),
.FrameLowering = frameLowering(),
.PseudoExpansion = pseudoExpansionInfo(),
- .SchedulingModel = schedulingModel(),
+ .SchedulingModel = Subtarget.schedulingModel(),
+ .SchedulerOptions = {.EmitDebugOutput = EmitSchedulerDebugOutput},
};
}
diff --git a/backend/lib/Target/RISCV/RISCVPipeline.cpp b/backend/lib/Target/RISCV/RISCVPipeline.cpp
index c24c57f..2af1d43 100644
--- a/backend/lib/Target/RISCV/RISCVPipeline.cpp
+++ b/backend/lib/Target/RISCV/RISCVPipeline.cpp
@@ -55,8 +55,11 @@ template <typename PassT, typename... ArgumentT>
return addPass<InstructionSelect>(Pipeline, Subtarget.getInstructionSelector());
}
-[[nodiscard]] Expected<void> addSSAExitPipeline(MachineFunctionPassManager &Pipeline) {
- auto Added = addSelectedSSAOptimizationPipeline(Pipeline, optimizationPipelineInfo());
+[[nodiscard]] Expected<void> addSSAExitPipeline(MachineFunctionPassManager &Pipeline,
+ const RISCVSubtarget &Subtarget,
+ RISCVPipelineOptions Options) {
+ auto Added = addSelectedSSAOptimizationPipeline(
+ Pipeline, optimizationPipelineInfo(Subtarget, Options.DebugMachineScheduler));
if (!Added)
return std::unexpected(Added.error());
Added = addPass<PHIEliminationPass>(Pipeline, instrInfo());
@@ -65,11 +68,14 @@ template <typename PassT, typename... ArgumentT>
return addPass<TwoAddressInstructionPass>(Pipeline, instrInfo());
}
-[[nodiscard]] Expected<void> addRegisterAllocationPipeline(MachineFunctionPassManager &Pipeline) {
+[[nodiscard]] Expected<void> addRegisterAllocationPipeline(MachineFunctionPassManager &Pipeline,
+ const RISCVSubtarget &Subtarget,
+ RISCVPipelineOptions Options) {
auto Added = addPass<PreRATargetPseudoExpansionPass>(Pipeline, pseudoExpansionInfo());
if (!Added)
return std::unexpected(Added.error());
- Added = addPreRegisterAllocationOptimizationPipeline(Pipeline, optimizationPipelineInfo());
+ Added = addPreRegisterAllocationOptimizationPipeline(
+ Pipeline, optimizationPipelineInfo(Subtarget, Options.DebugMachineScheduler));
if (!Added)
return std::unexpected(Added.error());
return addPass<PBQPAllocatorPass>(Pipeline, registerAllocationInfo());
@@ -81,14 +87,14 @@ template <typename PassT, typename... ArgumentT>
auto Added = addInitialPipeline(Pipeline, Subtarget, Options);
if (!Added)
return std::unexpected(Added.error());
- Added = addSSAExitPipeline(Pipeline);
+ Added = addSSAExitPipeline(Pipeline, Subtarget, Options);
if (!Added)
return std::unexpected(Added.error());
- Added = addRegisterAllocationPipeline(Pipeline);
+ Added = addRegisterAllocationPipeline(Pipeline, Subtarget, Options);
if (!Added)
return std::unexpected(Added.error());
return addPostRegisterAllocationPipeline(
- Pipeline, optimizationPipelineInfo(),
+ Pipeline, optimizationPipelineInfo(Subtarget, Options.DebugMachineScheduler),
MachineOptimizationPipelineOptions{.UseTargetCopyInstructions =
Options.UseTargetCopyInstructions});
}
@@ -119,7 +125,8 @@ Expected<void> addCanonicalPipeline(MachineFunctionPassManager &Pipeline,
return std::unexpected(Added.error());
}
if (!Function.properties().has(MachineFunctionProperty::TiedOpsRewritten)) {
- auto Added = addSelectedSSAOptimizationPipeline(Pipeline, optimizationPipelineInfo());
+ auto Added = addSelectedSSAOptimizationPipeline(
+ Pipeline, optimizationPipelineInfo(Subtarget, Options.DebugMachineScheduler));
if (!Added)
return std::unexpected(Added.error());
if (!Function.properties().has(MachineFunctionProperty::NoPHIs)) {
@@ -134,13 +141,13 @@ Expected<void> addCanonicalPipeline(MachineFunctionPassManager &Pipeline,
return std::unexpected(Added.error());
}
if (!Function.properties().has(MachineFunctionProperty::NoVRegs)) {
- auto Added = addRegisterAllocationPipeline(Pipeline);
+ auto Added = addRegisterAllocationPipeline(Pipeline, Subtarget, Options);
if (!Added)
return std::unexpected(Added.error());
}
if (!Function.properties().has(MachineFunctionProperty::NoExecutablePseudos)) {
auto Added = addPostRegisterAllocationPipeline(
- Pipeline, optimizationPipelineInfo(),
+ Pipeline, optimizationPipelineInfo(Subtarget, Options.DebugMachineScheduler),
MachineOptimizationPipelineOptions{.UseTargetCopyInstructions =
Options.UseTargetCopyInstructions});
if (!Added)
diff --git a/backend/lib/Target/RISCV/RISCVScheduling.cpp b/backend/lib/Target/RISCV/RISCVScheduling.cpp
index a58b913..b7947d4 100644
--- a/backend/lib/Target/RISCV/RISCVScheduling.cpp
+++ b/backend/lib/Target/RISCV/RISCVScheduling.cpp
@@ -1,11 +1,15 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "RISCV.h"
+#include "rcc/CodeGen/MacroFusion.h"
+#include "rcc/CodeGen/ScheduleDAG.h"
#include "rcc/Target/RISCV/RISCVTarget.h"
+#include <array>
#include <cstdint>
-#include <cstdlib>
+#include <memory>
#include <optional>
+#include <span>
#include <string>
#include <utility>
#include <vector>
@@ -13,6 +17,28 @@
namespace rcc::riscv {
namespace {
+#define GET_MACRO_FUSION_RULES
+#include "RISCVGenMacroFusion.inc"
+
+class RISCVSchedulingHooks final : public TargetSchedulingHooks {
+public:
+ explicit RISCVSchedulingHooks(const RISCVSubtargetFeatures &Features) {
+ for (const MacroFusionRule &Rule : generatedMacroFusionRules()) {
+ if (Features.hasFeature(Rule.Feature))
+ MacroFusionRules.push_back(Rule);
+ }
+ }
+
+ [[nodiscard]] Expected<void> mutateScheduleDAG(ScheduleDAG &DAG, const MachineFunction &,
+ const TargetDescription &Target, ScheduleDAGMode,
+ bool EmitDebugOutput) const override {
+ return applyMacroFusion(DAG, MacroFusionRules, Target, EmitDebugOutput);
+ }
+
+private:
+ std::vector<MacroFusionRule> MacroFusionRules;
+};
+
enum class Resource : std::uint32_t {
Core = 1,
IntegerALU = 2,
@@ -72,7 +98,7 @@ enum class PressureSet : std::uint32_t {
return {};
}
-[[nodiscard]] TargetSchedulingModelDesc createDescription() {
+[[nodiscard]] TargetSchedulingModelDesc createDescription(const TargetSchedulingHooks &Hooks) {
TargetSchedulingModelDesc Description;
Description.IssueWidth = 2;
Description.DispatchLimit = 2;
@@ -121,17 +147,19 @@ enum class PressureSet : std::uint32_t {
registerClass(RegisterClass::FPR32), registerClass(RegisterClass::FPR32C)},
32},
};
+ Description.Hooks = &Hooks;
return Description;
}
} // namespace
-const TargetSchedulingModel &schedulingModel() noexcept {
- static const Expected<TargetSchedulingModel> Model =
- TargetSchedulingModel::create(createDescription());
- if (!Model)
- std::abort();
- return *Model;
+std::unique_ptr<TargetSchedulingHooks>
+createSchedulingHooks(const RISCVSubtargetFeatures &Features) {
+ return std::make_unique<RISCVSchedulingHooks>(Features);
+}
+
+Expected<TargetSchedulingModel> createSchedulingModel(const TargetSchedulingHooks &Hooks) {
+ return TargetSchedulingModel::create(createDescription(Hooks));
}
} // namespace rcc::riscv
diff --git a/backend/lib/Target/RISCV/RISCVSubtarget.cpp b/backend/lib/Target/RISCV/RISCVSubtarget.cpp
index 4b3064d..c30c898 100644
--- a/backend/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/backend/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -7,10 +7,13 @@
#include "GISel/RISCVRegisterBankInfo.h"
#include "RISCV.h"
#include "rcc/CodeGen/GlobalISel/InstructionSelector.h"
+#include "rcc/CodeGen/TargetSchedulingModel.h"
#include <array>
#include <cstddef>
+#include <cstdlib>
#include <string_view>
+#include <utility>
namespace rcc::riscv {
namespace {
@@ -50,6 +53,7 @@ constexpr std::array OptionNames{
OptionName{"fusion-addi-load", RISCVSubtargetOption::FusionAddImmediateLoad},
OptionName{"fusion-auipc-addi", RISCVSubtargetOption::FusionAUIPCAddImmediate},
OptionName{"fusion-auipc-load", RISCVSubtargetOption::FusionAUIPCLoad},
+ OptionName{"fusion-bfext", RISCVSubtargetOption::FusionBitfieldExtract},
OptionName{"fusion-ld-add", RISCVSubtargetOption::FusionLoadDoubleAdd},
OptionName{"fusion-logic-imm-reg", RISCVSubtargetOption::FusionLogicImmediateRegister},
OptionName{"fusion-logic-reg-imm", RISCVSubtargetOption::FusionLogicRegisterImmediate},
@@ -58,6 +62,7 @@ constexpr std::array OptionNames{
OptionName{"fusion-lui-load", RISCVSubtargetOption::FusionLUILoad},
OptionName{"fusion-mul-add", RISCVSubtargetOption::FusionMultiplyAdd},
OptionName{"fusion-shift-bit-extract", RISCVSubtargetOption::FusionShiftBitExtract},
+ OptionName{"fusion-shxadd-load", RISCVSubtargetOption::FusionShiftedAddLoad},
OptionName{"fusion-shifted-zextw", RISCVSubtargetOption::FusionShiftedZeroExtendWord},
OptionName{"fusion-zexth", RISCVSubtargetOption::FusionZeroExtendHalf},
OptionName{"fusion-zextw", RISCVSubtargetOption::FusionZeroExtendWord},
@@ -171,9 +176,23 @@ bool RISCVSubtargetFeatures::has(RISCVSubtargetOption Option) const noexcept {
return (Options & optionBit(Option)) != 0;
}
+bool RISCVSubtargetFeatures::hasFeature(std::string_view Feature) const noexcept {
+ if (const OptionName *Option = findOption(Feature))
+ return has(Option->Option);
+ if (const ExtensionName *Extension = findExtension(Feature))
+ return has(Extension->Extension);
+ return false;
+}
+
RISCVSubtarget::RISCVSubtarget(RISCVSubtargetFeatures Features, RelocationModel Relocation,
CodeModel Code)
- : Features(Features), Relocation(Relocation), Code(Code) {}
+ : Features(Features), Relocation(Relocation), Code(Code),
+ SchedulingHooks(createSchedulingHooks(Features)) {
+ auto Model = createSchedulingModel(*SchedulingHooks);
+ if (!Model)
+ std::abort();
+ SchedulingModel = std::make_unique<TargetSchedulingModel>(std::move(*Model));
+}
RISCVSubtarget::~RISCVSubtarget() = default;
@@ -201,4 +220,8 @@ const RISCVRegisterBankInfo *RISCVSubtarget::getRegBankInfo() const {
return RegBankInfo.get();
}
+const TargetSchedulingModel &RISCVSubtarget::schedulingModel() const noexcept {
+ return *SchedulingModel;
+}
+
} // namespace rcc::riscv