aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/MacroFusion.h
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-22 18:49:08 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-22 18:49:08 +0800
commit8a4bb6e3b0bffa0ed79b51347b12ee4293b622a7 (patch)
tree51278f18d8954e7abb5820cb9d529e3d5e5f322b /backend/include/rcc/CodeGen/MacroFusion.h
parent9ca9fb23124e8c5d714e9668210855a23dd2a72f (diff)
downloadrcc-project-8a4bb6e3b0bffa0ed79b51347b12ee4293b622a7.tar.gz
rcc-project-8a4bb6e3b0bffa0ed79b51347b12ee4293b622a7.tar.xz
[CodeGen] Generate RISC-V macro fusion rules
Diffstat (limited to 'backend/include/rcc/CodeGen/MacroFusion.h')
-rw-r--r--backend/include/rcc/CodeGen/MacroFusion.h77
1 files changed, 77 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/MacroFusion.h b/backend/include/rcc/CodeGen/MacroFusion.h
new file mode 100644
index 0000000..c3d811d
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MacroFusion.h
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MACROFUSION_H
+#define RCC_CODEGEN_MACROFUSION_H
+
+#include "rcc/CodeGen/MachineIRTypes.h"
+#include "rcc/Support/Error.h"
+
+#include <cstdint>
+#include <limits>
+#include <span>
+#include <string_view>
+
+namespace rcc {
+
+class MachineInstr;
+class ScheduleDAG;
+class TargetDescription;
+
+enum class MacroFusionInstruction : std::uint8_t {
+ First,
+ Second,
+};
+
+struct MacroFusionOpcodePair final {
+ Opcode First;
+ Opcode Second;
+};
+
+struct MacroFusionImmediatePredicate final {
+ MacroFusionInstruction Instruction = MacroFusionInstruction::First;
+ std::uint32_t OperandIndex = 0;
+ std::int64_t Minimum = 0;
+ std::int64_t Maximum = 0;
+};
+
+struct MacroFusionRegisterInequality final {
+ MacroFusionInstruction Instruction = MacroFusionInstruction::First;
+ std::uint32_t LeftOperand = 0;
+ std::uint32_t RightOperand = 0;
+};
+
+struct MacroFusionImmediateRelation final {
+ std::uint32_t FirstOperand = 0;
+ std::uint32_t SecondOperand = 0;
+};
+
+struct MacroFusionRule final {
+ static constexpr std::uint32_t NoOperand = std::numeric_limits<std::uint32_t>::max();
+
+ std::string_view Name;
+ std::string_view Feature;
+ std::span<const Opcode> FirstOpcodes;
+ std::span<const Opcode> SecondOpcodes;
+ std::span<const MacroFusionOpcodePair> OpcodePairs;
+ std::span<const MacroFusionImmediatePredicate> ImmediatePredicates;
+ std::span<const MacroFusionRegisterInequality> RegisterInequalities;
+ std::span<const MacroFusionImmediateRelation> ImmediateRelations;
+ std::uint32_t FirstDefinitionOperand = 0;
+ std::uint32_t SecondUseOperand = 1;
+ std::uint32_t SecondDefinitionOperand = 0;
+ std::uint32_t CommutableSecondUseOperand = NoOperand;
+ bool RequireSingleNonDebugUse = false;
+ bool RequireSecondDestinationTie = false;
+};
+
+[[nodiscard]] bool matchesMacroFusion(const MacroFusionRule &Rule, const MachineInstr *First,
+ const MachineInstr &Second) noexcept;
+
+[[nodiscard]] Expected<void> applyMacroFusion(ScheduleDAG &DAG,
+ std::span<const MacroFusionRule> Rules,
+ const TargetDescription &Target,
+ bool EmitDebugOutput);
+
+} // namespace rcc
+
+#endif // RCC_CODEGEN_MACROFUSION_H