aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 05:13:13 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 05:13:13 +0800
commitdf7095e67ea06f7d6a81d99e70c804ce54ef950d (patch)
treeb61459583ac9972b196d5e639f02593374eae41f /backend/lib/Target/RISCV
parent307fc0961972ac5264d6f3459978fbec95cad3a9 (diff)
downloadrcc-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.txt13
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVGISelCombiner.cpp56
-rw-r--r--backend/lib/Target/RISCV/RISCV.h3
-rw-r--r--backend/lib/Target/RISCV/RISCVGISelCombiner.rccdesc173
-rw-r--r--backend/lib/Target/RISCV/RISCVPipeline.cpp10
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,