diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-22 19:16:18 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-22 19:16:18 +0800 |
| commit | 75f1223070749b0df3002226ebbb474c68c71f90 (patch) | |
| tree | e3b386180f6ea394381862d5ff9b5394ac0a6481 /backend/lib/Target/RISCV | |
| parent | 36b0be1ec1558f88d4f031a1817c3a4c2cba07a6 (diff) | |
| download | rcc-project-75f1223070749b0df3002226ebbb474c68c71f90.tar.gz rcc-project-75f1223070749b0df3002226ebbb474c68c71f90.tar.xz | |
[RISCV] Generate MC pseudo lowering
Diffstat (limited to 'backend/lib/Target/RISCV')
| -rw-r--r-- | backend/lib/Target/RISCV/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc | 30 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc | 35 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp | 9 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp | 187 |
5 files changed, 78 insertions, 193 deletions
diff --git a/backend/lib/Target/RISCV/CMakeLists.txt b/backend/lib/Target/RISCV/CMakeLists.txt index 00de7bd..dccced9 100644 --- a/backend/lib/Target/RISCV/CMakeLists.txt +++ b/backend/lib/Target/RISCV/CMakeLists.txt @@ -21,6 +21,7 @@ set( "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelFloating.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelCombiner.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVMacroFusion.rccdesc" + "${CMAKE_CURRENT_SOURCE_DIR}/RISCVMCPseudoLowering.rccdesc" ) set(RCCBackendRISCVTableGenArguments) foreach(RCCBackendRISCVDescriptionSource IN LISTS RCCBackendRISCVDescriptionSources) @@ -50,6 +51,10 @@ set( RCCBackendRISCVGeneratedMacroFusion "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenMacroFusion.inc" ) +set( + RCCBackendRISCVGeneratedMCPseudoLowering + "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenMCPseudoLowering.inc" +) add_custom_command( OUTPUT @@ -59,6 +64,7 @@ add_custom_command( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" COMMAND "$<TARGET_FILE:RCCBackendTableGenTool>" ${RCCBackendRISCVTableGenArguments} @@ -68,6 +74,7 @@ add_custom_command( --global-isel "${RCCBackendRISCVGeneratedGlobalISel}" --global-isel-combiner "${RCCBackendRISCVGeneratedGlobalISelCombiner}" --macro-fusion "${RCCBackendRISCVGeneratedMacroFusion}" + --mc-pseudo-lowering "${RCCBackendRISCVGeneratedMCPseudoLowering}" DEPENDS RCCBackendTableGenTool ${RCCBackendRISCVDescriptionSources} COMMENT "Generating RCC RV64GC target tables" VERBATIM @@ -82,6 +89,7 @@ add_custom_target( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" ) set_source_files_properties( @@ -91,6 +99,7 @@ set_source_files_properties( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" PROPERTIES GENERATED TRUE HEADER_FILE_ONLY TRUE ) @@ -127,6 +136,7 @@ add_library( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" ) add_library(RCCBackend::RISCV ALIAS RCCBackendRISCV) add_dependencies(RCCBackendRISCV RCCBackendRISCVGeneratedTablesTarget) diff --git a/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc b/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc index 14bcf26..3e458df 100644 --- a/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc +++ b/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc @@ -227,9 +227,9 @@ instructions: - { kinds: [register], role: def, register_class: GPR, register_bank: GPR } num_explicit_defs: 1 implicit_uses: [{ register: FFLAGS }] - flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects] - owner: post_ra_expansion - deadline: post_ra_finalized + flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects, terminal_emission] + owner: asm_printer + deadline: emission - id: 1246 @@ -239,9 +239,9 @@ instructions: - { kinds: [register], role: use, register_class: GPR, register_bank: GPR } num_explicit_defs: 0 implicit_defs: [{ register: FFLAGS }] - flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects] - owner: post_ra_expansion - deadline: post_ra_finalized + flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects, terminal_emission] + owner: asm_printer + deadline: emission - id: 1217 symbol: PseudoLOAD_STACK_ARG @@ -342,10 +342,10 @@ instructions: operands: [] num_explicit_defs: 0 allow_extra_implicit_operands: true - flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, return, barrier] + flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, return, barrier, terminal_emission] size: 4 - owner: post_ra_expansion - deadline: post_ra_finalized + owner: asm_printer + deadline: emission - id: 1225 @@ -404,10 +404,10 @@ instructions: operands: - { kinds: [basic_block], name: TARGET } num_explicit_defs: 0 - flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, barrier] + flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, barrier, terminal_emission] size: 4 - owner: post_ra_expansion - deadline: post_ra_finalized + owner: asm_printer + deadline: emission - id: 1267 symbol: PseudoLLA @@ -441,7 +441,7 @@ instructions: - { kinds: [register], role: use, register_class: GPRJALRNonX7, register_bank: GPR, name: RS1 } - { kinds: [immediate], immediate_predicate: SIMM12, name: IMM } num_explicit_defs: 0 - flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, indirect_branch, barrier] + flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, indirect_branch, barrier, terminal_emission] size: 4 - owner: post_ra_expansion - deadline: post_ra_finalized + owner: asm_printer + deadline: emission diff --git a/backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc b/backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc new file mode 100644 index 0000000..a505281 --- /dev/null +++ b/backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc @@ -0,0 +1,35 @@ +mc_pseudo_expansions: + - + pseudo: PseudoBR + opcode: JAL + operands: + - { register: X0 } + - { operand: 0 } + - + pseudo: PseudoBRIND + opcode: JALR + operands: + - { register: X0 } + - { operand: 0 } + - { operand: 1 } + - + pseudo: PseudoRET + opcode: JALR + operands: + - { register: X0 } + - { register: X1 } + - { immediate: 0 } + - + pseudo: ReadFFLAGS + opcode: CSRRS + operands: + - { operand: 0 } + - { immediate: 1 } + - { register: X0 } + - + pseudo: WriteFFLAGS + opcode: CSRRW + operands: + - { register: X0 } + - { immediate: 1 } + - { operand: 0 } diff --git a/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp b/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp index 61cb587..85c06ad 100644 --- a/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp +++ b/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp @@ -240,6 +240,10 @@ constexpr std::uint32_t KnownTargetFlags = CallTargetFlag | PCRelativeHighTarget "RISC-V MC lowering encountered a non-encoding operand"); } +#define GET_MC_PSEUDO_LOWERING +#include "RISCVGenMCPseudoLowering.inc" +#undef GET_MC_PSEUDO_LOWERING + [[nodiscard]] const AssemblyFormatInfo *assemblyFormat(AssemblyFormatID ID) noexcept { const auto Formats = assemblyFormats(); const auto Position = std::ranges::find(Formats, ID, &AssemblyFormatInfo::ID); @@ -866,6 +870,11 @@ Expected<mc::MCInst> RISCVMCTargetLowering::lowerInstruction(const MachineInstr Expected<void> RISCVMCTargetLowering::emitTerminalInstruction(const MachineInstr &Instruction, MachineMCContext &Context, mc::MCStreamer &Streamer) const { + auto Pseudo = lowerGeneratedMCPseudo(Instruction, Context); + if (!Pseudo) + return std::unexpected(Pseudo.error()); + if (*Pseudo) + return Streamer.emitInstruction(**Pseudo); if (Instruction.opcode() != opcode(GenericOpcode::INLINEASM) && Instruction.opcode() != opcode(GenericOpcode::INLINEASM_BR)) { return TargetMCInstLowering::emitTerminalInstruction(Instruction, Context, Streamer); diff --git a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp index 257fa3a..19e52d9 100644 --- a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp +++ b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp @@ -243,7 +243,15 @@ copyRegisters(const MachineInstr &Instruction) { auto Def = Pending->addDef(Destination); if (!Def) return std::unexpected(Def.error()); - auto Use = Pending->addUse(Source); + RegisterOperandFlags SourceFlags; + const RegisterOperandFlags OriginalSourceFlags = Instruction.operandAt(1)->registerFlags(); + if (OriginalSourceFlags.has(RegisterOperandFlag::Kill)) + SourceFlags.set(RegisterOperandFlag::Kill); + if (*DestinationBank == GPR && *SourceBank == GPR && + OriginalSourceFlags.has(RegisterOperandFlag::Renamable)) { + SourceFlags.set(RegisterOperandFlag::Renamable); + } + auto Use = Pending->addUse(Source, SourceFlags); if (!Use) return std::unexpected(Use.error()); if (DuplicateSource) { @@ -440,53 +448,6 @@ copyRegisters(const MachineInstr &Instruction) { return {}; } -[[nodiscard]] Expected<bool> expandFFLAGSAccess(MachineInstr &Instruction, - MachineFunction &Function, - const TargetDescription &Target, bool IsRead) { - const MachineOperand *ValueOperand = Instruction.operandAt(0); - const Register *Value = ValueOperand == nullptr ? nullptr : ValueOperand->getIf<Register>(); - if (Value == nullptr || !Value->isPhysical()) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V FFLAGS pseudo retains a nonphysical value register"); - } - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Zero) - return std::unexpected(Zero.error()); - - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr( - instructionOpcode(IsRead ? InstructionOpcode::CSRRS : InstructionOpcode::CSRRW)); - if (!Pending) - return std::unexpected(Pending.error()); - Expected<void> Added = IsRead ? Pending->addOperand(ValueOperand->cloneDetached()) - : Pending->addDef(Register::fromPhysical(*Zero)); - if (!Added) - return std::unexpected(Added.error()); - Added = Pending->addImmediate(1); - if (!Added) - return std::unexpected(Added.error()); - Added = IsRead ? Pending->addUse(Register::fromPhysical(*Zero)) - : Pending->addOperand(ValueOperand->cloneDetached()); - if (!Added) - return std::unexpected(Added.error()); - auto Implicit = copyExtraImplicitOperands(Instruction, 1, *Pending, std::nullopt, std::nullopt); - if (!Implicit) - return std::unexpected(Implicit.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - [[nodiscard]] Expected<bool> expandCall(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target, bool IsTail) { MachineBasicBlock *Block = Instruction.parent(); @@ -585,126 +546,6 @@ copyRegisters(const MachineInstr &Instruction) { return true; } -[[nodiscard]] Expected<bool> expandReturn(MachineInstr &Instruction, MachineFunction &Function, - const TargetDescription &Target) { - auto Zero = physicalRegister(PhysicalRegisterID::X0); - auto Link = physicalRegister(PhysicalRegisterID::X1); - if (!Zero || !Link) - return makeUnexpected(ErrorCode::InternalError, "RISC-V return registers are unavailable"); - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JALR_RET)); - if (!Pending) - return std::unexpected(Pending.error()); - auto Def = Pending->addDef(Register::fromPhysical(*Zero)); - if (!Def) - return std::unexpected(Def.error()); - auto Use = Pending->addUse(Register::fromPhysical(*Link)); - if (!Use) - return std::unexpected(Use.error()); - auto Immediate = Pending->addImmediate(0); - if (!Immediate) - return std::unexpected(Immediate.error()); - auto Implicit = copyExtraImplicitOperands(Instruction, 0, *Pending, std::nullopt, *Link); - if (!Implicit) - return std::unexpected(Implicit.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - -[[nodiscard]] Expected<bool> expandBranch(MachineInstr &Instruction, MachineFunction &Function, - const TargetDescription &Target) { - const MachineOperand *TargetOperand = Instruction.operandAt(0); - const BasicBlockOperand *TargetBlock = - TargetOperand == nullptr ? nullptr : TargetOperand->getIf<BasicBlockOperand>(); - if (TargetBlock == nullptr || TargetBlock->Block == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V PseudoBR has no basic-block target"); - } - - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Zero) - return std::unexpected(Zero.error()); - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JAL)); - if (!Pending) - return std::unexpected(Pending.error()); - auto Def = Pending->addDef(Register::fromPhysical(*Zero)); - if (!Def) - return std::unexpected(Def.error()); - auto Destination = Pending->addBasicBlock(*TargetBlock->Block); - if (!Destination) - return std::unexpected(Destination.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - -[[nodiscard]] Expected<bool> expandIndirectBranch(MachineInstr &Instruction, - MachineFunction &Function, - const TargetDescription &Target) { - const MachineOperand *Address = Instruction.operandAt(0); - const MachineOperand *Offset = Instruction.operandAt(1); - if (Address == nullptr || Address->getIf<Register>() == nullptr || Offset == nullptr || - Offset->getIf<std::int64_t>() == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V PseudoBRIND has malformed operands"); - } - - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Zero) - return std::unexpected(Zero.error()); - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JALR)); - if (!Pending) - return std::unexpected(Pending.error()); - auto Added = Pending->addDef(Register::fromPhysical(*Zero)); - if (!Added) - return std::unexpected(Added.error()); - Added = Pending->addOperand(Address->cloneDetached()); - if (!Added) - return std::unexpected(Added.error()); - Added = Pending->addOperand(Offset->cloneDetached()); - if (!Added) - return std::unexpected(Added.error()); - auto Implicit = copyExtraImplicitOperands(Instruction, 2, *Pending, std::nullopt, std::nullopt); - if (!Implicit) - return std::unexpected(Implicit.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - class RISCVPseudoExpansionInfo final : public TargetPseudoExpansionInfo { public: [[nodiscard]] Expected<bool> preparePostRAPseudo(MachineInstr &Instruction, @@ -735,16 +576,6 @@ public: return expandCall(Instruction, Function, Target, false); if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoTAIL)) return expandCall(Instruction, Function, Target, true); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoRET)) - return expandReturn(Instruction, Function, Target); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBR)) - return expandBranch(Instruction, Function, Target); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBRIND)) - return expandIndirectBranch(Instruction, Function, Target); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::ReadFFLAGS)) - return expandFFLAGSAccess(Instruction, Function, Target, true); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::WriteFFLAGS)) - return expandFFLAGSAccess(Instruction, Function, Target, false); return false; } }; |
