diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-19 05:13:13 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-19 05:13:13 +0800 |
| commit | df7095e67ea06f7d6a81d99e70c804ce54ef950d (patch) | |
| tree | b61459583ac9972b196d5e639f02593374eae41f /backend/lib/Target/RISCV | |
| parent | 307fc0961972ac5264d6f3459978fbec95cad3a9 (diff) | |
| download | rcc-project-df7095e67ea06f7d6a81d99e70c804ce54ef950d.tar.gz rcc-project-df7095e67ea06f7d6a81d99e70c804ce54ef950d.tar.xz | |
[GlobalISel] Generate prelegalizer combiner rules
Diffstat (limited to 'backend/lib/Target/RISCV')
| -rw-r--r-- | backend/lib/Target/RISCV/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/GISel/RISCVGISelCombiner.cpp | 56 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCV.h | 3 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVGISelCombiner.rccdesc | 173 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVPipeline.cpp | 10 |
5 files changed, 250 insertions, 5 deletions
diff --git a/backend/lib/Target/RISCV/CMakeLists.txt b/backend/lib/Target/RISCV/CMakeLists.txt index 3972a92..2e1e224 100644 --- a/backend/lib/Target/RISCV/CMakeLists.txt +++ b/backend/lib/Target/RISCV/CMakeLists.txt @@ -19,6 +19,7 @@ set( "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelControlFlow.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelShift.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelFloating.rccdesc" + "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelCombiner.rccdesc" ) set(RCCBackendRISCVTableGenArguments) foreach(RCCBackendRISCVDescriptionSource IN LISTS RCCBackendRISCVDescriptionSources) @@ -40,6 +41,10 @@ set( RCCBackendRISCVGeneratedGlobalISel "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenGlobalISel.inc" ) +set( + RCCBackendRISCVGeneratedGlobalISelCombiner + "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenGlobalISelCombiner.inc" +) add_custom_command( OUTPUT @@ -47,6 +52,7 @@ add_custom_command( "${RCCBackendRISCVGeneratedInstructionHeader}" "${RCCBackendRISCVGeneratedTables}" "${RCCBackendRISCVGeneratedGlobalISel}" + "${RCCBackendRISCVGeneratedGlobalISelCombiner}" COMMAND "$<TARGET_FILE:RCCBackendTableGenTool>" ${RCCBackendRISCVTableGenArguments} @@ -54,6 +60,7 @@ add_custom_command( --instruction-header "${RCCBackendRISCVGeneratedInstructionHeader}" --tables "${RCCBackendRISCVGeneratedTables}" --global-isel "${RCCBackendRISCVGeneratedGlobalISel}" + --global-isel-combiner "${RCCBackendRISCVGeneratedGlobalISelCombiner}" DEPENDS RCCBackendTableGenTool ${RCCBackendRISCVDescriptionSources} COMMENT "Generating RCC RV64GC target tables" VERBATIM @@ -66,6 +73,7 @@ add_custom_target( "${RCCBackendRISCVGeneratedInstructionHeader}" "${RCCBackendRISCVGeneratedTables}" "${RCCBackendRISCVGeneratedGlobalISel}" + "${RCCBackendRISCVGeneratedGlobalISelCombiner}" ) set_source_files_properties( @@ -73,6 +81,7 @@ set_source_files_properties( "${RCCBackendRISCVGeneratedInstructionHeader}" "${RCCBackendRISCVGeneratedTables}" "${RCCBackendRISCVGeneratedGlobalISel}" + "${RCCBackendRISCVGeneratedGlobalISelCombiner}" PROPERTIES GENERATED TRUE HEADER_FILE_ONLY TRUE ) @@ -80,6 +89,7 @@ add_library( RCCBackendRISCV GISel/RISCVCallLowering.cpp GISel/RISCVInstructionSelector.cpp + GISel/RISCVGISelCombiner.cpp GISel/RISCVLegalizerInfo.cpp GISel/RISCVRegisterBankInfo.cpp RISCVInstrInfo.cpp @@ -106,6 +116,7 @@ add_library( "${RCCBackendRISCVGeneratedInstructionHeader}" "${RCCBackendRISCVGeneratedTables}" "${RCCBackendRISCVGeneratedGlobalISel}" + "${RCCBackendRISCVGeneratedGlobalISelCombiner}" ) add_library(RCCBackend::RISCV ALIAS RCCBackendRISCV) add_dependencies(RCCBackendRISCV RCCBackendRISCVGeneratedTablesTarget) @@ -155,6 +166,7 @@ rcc_backend_register_format_files( "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVCallLowering.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVCallLowering.h" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVInstructionSelector.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVGISelCombiner.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVLegalizerInfo.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVLegalizerInfo.h" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVRegisterBankInfo.cpp" @@ -199,6 +211,7 @@ rcc_backend_register_format_files( rcc_backend_register_tidy_files( "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVCallLowering.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVInstructionSelector.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVGISelCombiner.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVLegalizerInfo.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GISel/RISCVRegisterBankInfo.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVInstrInfo.cpp" diff --git a/backend/lib/Target/RISCV/GISel/RISCVGISelCombiner.cpp b/backend/lib/Target/RISCV/GISel/RISCVGISelCombiner.cpp new file mode 100644 index 0000000..bf67c0a --- /dev/null +++ b/backend/lib/Target/RISCV/GISel/RISCVGISelCombiner.cpp @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "RISCV.h" +#include "rcc/CodeGen/GlobalISel/GIMatchTableExecutor.h" +#include "rcc/CodeGen/MachineFunction.h" +#include "rcc/CodeGen/MachineInstr.h" +#include "rcc/CodeGen/MachineRegisterInfo.h" +#include "rcc/CodeGen/TargetDescription.h" + +#include <string> + +namespace rcc::riscv { +namespace { + +#define GET_GLOBALISEL_COMBINER_TABLE +#include "RISCVGenGlobalISelCombiner.inc" +#undef GET_GLOBALISEL_COMBINER_TABLE + +class RISCVGISelCombinerExecutor final : public GIMatchTableExecutor { +protected: + [[nodiscard]] Expected<bool> + matchesTargetPredicate(std::string_view Name, const MachineInstr &Instruction, + const MachineFunction &Function, + const TargetDescription &Target) const override { + if (Name != "sext_cheaper_than_zext") + return GIMatchTableExecutor::matchesTargetPredicate(Name, Instruction, Function, Target); + const MachineOperand *Destination = Instruction.operandAt(0); + const MachineOperand *Source = Instruction.operandAt(1); + const Register *DestinationReg = + Destination == nullptr ? nullptr : Destination->getIf<Register>(); + const Register *SourceReg = Source == nullptr ? nullptr : Source->getIf<Register>(); + if (DestinationReg == nullptr || SourceReg == nullptr || !DestinationReg->isVirtual() || + !SourceReg->isVirtual()) + return false; + auto DestinationType = Function.registerInfo().getType(*DestinationReg); + auto SourceType = Function.registerInfo().getType(*SourceReg); + if (!DestinationType || !SourceType) + return false; + return DestinationType->isCategoryNeutralScalar() && SourceType->isCategoryNeutralScalar() && + DestinationType->scalarBitWidth() == 64 && SourceType->scalarBitWidth() == 32; + } +}; + +} // namespace + +const GIMatchTable &giselCombinerTable() noexcept { + static constexpr GIMatchTable Table = generatedGlobalISelCombinerMatchTable(); + return Table; +} + +const GIMatchTableExecutor &giselCombinerExecutor() noexcept { + static const RISCVGISelCombinerExecutor Executor; + return Executor; +} + +} // namespace rcc::riscv diff --git a/backend/lib/Target/RISCV/RISCV.h b/backend/lib/Target/RISCV/RISCV.h index 1a81f59..4699091 100644 --- a/backend/lib/Target/RISCV/RISCV.h +++ b/backend/lib/Target/RISCV/RISCV.h @@ -3,6 +3,7 @@ #ifndef RCC_LIB_TARGET_RISCV_RISCV_H #define RCC_LIB_TARGET_RISCV_RISCV_H +#include "rcc/CodeGen/GlobalISel/GIMatchTableExecutor.h" #include "rcc/CodeGen/MachineCombinerPattern.h" #include "rcc/CodeGen/MachineOptimizationPipeline.h" #include "rcc/CodeGen/TargetFrameLowering.h" @@ -28,6 +29,8 @@ createRISCVInstructionSelector(const RISCVSubtarget &Subtarget, [[nodiscard]] const TargetFrameLowering &frameLowering() noexcept; [[nodiscard]] const TargetSchedulingModel &schedulingModel() noexcept; [[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; diff --git a/backend/lib/Target/RISCV/RISCVGISelCombiner.rccdesc b/backend/lib/Target/RISCV/RISCVGISelCombiner.rccdesc new file mode 100644 index 0000000..5f8585b --- /dev/null +++ b/backend/lib/Target/RISCV/RISCVGISelCombiner.rccdesc @@ -0,0 +1,173 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +combiner_rules: + - + id: combine_nneg_zext + priority: 500 + match: + opcode: G_ZEXT + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + target_predicates: [sext_cheaper_than_zext] + flags: [nneg] + def_use: + - + operand: 1 + opcode: G_TRUNC + captures: + - { id: source, operand: 1 } + - { id: trunc_result, operand: 0 } + apply: + action: mutate_root + opcode: G_SEXT_INREG + operands: + - { operand: 0 } + - { captured_operand: source } + - { captured_type_bits: trunc_result } + clear_flags: [nneg] + erase_operand_definitions: [1] + - + id: combine_shl_zero + priority: 100 + match: + opcode: G_SHL + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] + - + id: combine_lshr_zero + priority: 100 + match: + opcode: G_LSHR + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] + - + id: combine_ashr_zero + priority: 100 + match: + opcode: G_ASHR + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] + - + id: combine_sdiv_zero + priority: 100 + match: + opcode: G_SDIV + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] + - + id: combine_udiv_zero + priority: 100 + match: + opcode: G_UDIV + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] + - + id: combine_srem_zero + priority: 100 + match: + opcode: G_SREM + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] + - + id: combine_urem_zero + priority: 100 + match: + opcode: G_UREM + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] + - + id: combine_mul_zero + priority: 100 + match: + opcode: G_MUL + def_use: + - + operand: 1 + opcode: G_CONSTANT + captures: + - { id: zero, operand: 0 } + operand_def_constants: + - index: 1 + ranges: [{ min: 0, max: 0 }] + apply: + action: replace_root_with_capture + capture: zero + erase_operand_definitions: [1] diff --git a/backend/lib/Target/RISCV/RISCVPipeline.cpp b/backend/lib/Target/RISCV/RISCVPipeline.cpp index 00a4398..c24c57f 100644 --- a/backend/lib/Target/RISCV/RISCVPipeline.cpp +++ b/backend/lib/Target/RISCV/RISCVPipeline.cpp @@ -6,10 +6,10 @@ #include "GISel/RISCVRegisterBankInfo.h" #include "RISCV.h" #include "RISCVInstrInfo.h" +#include "rcc/CodeGen/GlobalISel/Combiner.h" #include "rcc/CodeGen/GlobalISel/InstructionSelect.h" #include "rcc/CodeGen/GlobalISel/Legalizer.h" #include "rcc/CodeGen/GlobalISel/RegBankSelect.h" -#include "rcc/CodeGen/MachineCombiner.h" #include "rcc/CodeGen/MachineFunction.h" #include "rcc/CodeGen/MachineOptimizationPipeline.h" #include "rcc/CodeGen/MachinePseudoExpansion.h" @@ -41,8 +41,8 @@ template <typename PassT, typename... ArgumentT> [[nodiscard]] Expected<void> addInitialPipeline(MachineFunctionPassManager &Pipeline, const RISCVSubtarget &Subtarget, RISCVPipelineOptions Options) { - auto Added = addPass<MachineCombinerPass>(Pipeline, machineCombinerInfo(), - MachineCombinerStage::PreLegalizer); + auto Added = addPass<GlobalISelCombinerPass>( + Pipeline, giselCombinerTable(), giselCombinerExecutor(), "riscv-prelegalizer-combiner"); if (!Added) return std::unexpected(Added.error()); Added = addPass<Legalizer>(Pipeline, Subtarget.getLegalizerInfo(), Options.Optimization, @@ -99,8 +99,8 @@ Expected<void> addCanonicalPipeline(MachineFunctionPassManager &Pipeline, const MachineFunction &Function, const RISCVSubtarget &Subtarget, RISCVPipelineOptions Options) { if (!Function.properties().has(MachineFunctionProperty::Legalized)) { - auto Added = addPass<MachineCombinerPass>(Pipeline, machineCombinerInfo(), - MachineCombinerStage::PreLegalizer); + auto Added = addPass<GlobalISelCombinerPass>( + Pipeline, giselCombinerTable(), giselCombinerExecutor(), "riscv-prelegalizer-combiner"); if (!Added) return std::unexpected(Added.error()); Added = addPass<Legalizer>(Pipeline, Subtarget.getLegalizerInfo(), Options.Optimization, |
