From 432efe39315ed5ad0162f9c08dbf10941bc21dc1 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Mon, 3 Aug 2026 19:24:30 +0800 Subject: [CodeGen] Add target MIR text schema --- backend/include/rcc/CodeGen/MachineFrameInfo.h | 41 +++-- backend/include/rcc/CodeGen/MachineMemOperand.h | 1 + backend/include/rcc/CodeGen/MachineRegisterInfo.h | 3 + backend/include/rcc/CodeGen/TargetDescription.h | 23 ++- backend/include/rcc/CodeGen/TargetMIRTextInfo.h | 208 ++++++++++++++++++++++ backend/include/rcc/CodeGen/TargetRegisterInfo.h | 16 ++ 6 files changed, 272 insertions(+), 20 deletions(-) create mode 100644 backend/include/rcc/CodeGen/TargetMIRTextInfo.h (limited to 'backend/include/rcc') diff --git a/backend/include/rcc/CodeGen/MachineFrameInfo.h b/backend/include/rcc/CodeGen/MachineFrameInfo.h index b837ff3..7c42bc2 100644 --- a/backend/include/rcc/CodeGen/MachineFrameInfo.h +++ b/backend/include/rcc/CodeGen/MachineFrameInfo.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -38,46 +39,58 @@ public: return StackID(DefaultStackValue); } - [[nodiscard]] static constexpr StackID safeStack() noexcept { - return StackID(SafeStackValue); - } - - [[nodiscard]] static constexpr StackID shadowCallStack() noexcept { - return StackID(ShadowCallStackValue); + [[nodiscard]] static constexpr StackID sgprSpillStack() noexcept { + return StackID(SGPRSpillStackValue); } [[nodiscard]] static constexpr StackID scalableVectorStack() noexcept { return StackID(ScalableVectorStackValue); } - [[nodiscard]] static Expected targetStack(std::uint32_t Value); + [[nodiscard]] static constexpr StackID wasmLocalStack() noexcept { + return StackID(WasmLocalStackValue); + } + + [[nodiscard]] static constexpr StackID scalablePredicateVectorStack() noexcept { + return StackID(ScalablePredicateVectorStackValue); + } + + [[nodiscard]] static constexpr StackID noAllocStack() noexcept { + return StackID(NoAllocStackValue); + } + + [[nodiscard]] static Expected fromValue(std::uint32_t Value); [[nodiscard]] constexpr std::uint32_t value() const noexcept { return Value; } - [[nodiscard]] constexpr bool isTargetStack() const noexcept { - return Value >= FirstTargetStackValue; + [[nodiscard]] constexpr bool isSpecialStack() const noexcept { + return Value != DefaultStackValue; } [[nodiscard]] constexpr bool isValid() const noexcept { - return Value <= ScalableVectorStackValue || isTargetStack(); + return Value <= ScalablePredicateVectorStackValue || Value == NoAllocStackValue; } friend constexpr bool operator==(StackID Left, StackID Right) noexcept = default; private: static constexpr std::uint32_t DefaultStackValue = 0; - static constexpr std::uint32_t SafeStackValue = 1; - static constexpr std::uint32_t ShadowCallStackValue = 2; - static constexpr std::uint32_t ScalableVectorStackValue = 3; - static constexpr std::uint32_t FirstTargetStackValue = 256; + static constexpr std::uint32_t SGPRSpillStackValue = 1; + static constexpr std::uint32_t ScalableVectorStackValue = 2; + static constexpr std::uint32_t WasmLocalStackValue = 3; + static constexpr std::uint32_t ScalablePredicateVectorStackValue = 4; + static constexpr std::uint32_t NoAllocStackValue = 255; explicit constexpr StackID(std::uint32_t Value) noexcept : Value(Value) {} std::uint32_t Value = DefaultStackValue; }; +[[nodiscard]] std::optional parseStackIDName(std::string_view Name) noexcept; +[[nodiscard]] std::string_view getStackIDName(StackID ID) noexcept; + struct StackObjectLifetimeRange final { MachineInstrStableID Begin; MachineInstrStableID End; diff --git a/backend/include/rcc/CodeGen/MachineMemOperand.h b/backend/include/rcc/CodeGen/MachineMemOperand.h index 3f1fc64..b6cb07f 100644 --- a/backend/include/rcc/CodeGen/MachineMemOperand.h +++ b/backend/include/rcc/CodeGen/MachineMemOperand.h @@ -182,6 +182,7 @@ struct MachineMemOperandDesc final { std::int64_t Offset = 0; std::optional OffsetRange; std::optional AliasSource; + std::uint16_t TargetFlags = 0; friend bool operator==(const MachineMemOperandDesc &Left, const MachineMemOperandDesc &Right) = default; diff --git a/backend/include/rcc/CodeGen/MachineRegisterInfo.h b/backend/include/rcc/CodeGen/MachineRegisterInfo.h index da0f530..b6485e3 100644 --- a/backend/include/rcc/CodeGen/MachineRegisterInfo.h +++ b/backend/include/rcc/CodeGen/MachineRegisterInfo.h @@ -83,6 +83,7 @@ struct VirtualRegisterInfo final { std::optional Bank; std::optional RegClass; std::vector AllocationHints; + std::uint8_t TargetFlags = 0; bool IsTombstone = false; }; @@ -123,6 +124,8 @@ public: [[nodiscard]] Expected setRegisterClass(Register Reg, RegisterClassID RegClass); [[nodiscard]] Expected clearRegisterClass(Register Reg); [[nodiscard]] Expected addAllocationHint(Register Reg, PhysicalRegister Hint); + [[nodiscard]] Expected setTargetRegisterFlags(Register Reg, std::uint8_t Flags); + [[nodiscard]] Expected clearTargetRegisterFlags(Register Reg); void clearAllVirtualRegisterTypes() noexcept; [[nodiscard]] Expected diff --git a/backend/include/rcc/CodeGen/TargetDescription.h b/backend/include/rcc/CodeGen/TargetDescription.h index 51a820a..c2a4133 100644 --- a/backend/include/rcc/CodeGen/TargetDescription.h +++ b/backend/include/rcc/CodeGen/TargetDescription.h @@ -4,6 +4,7 @@ #define RCC_CODEGEN_TARGETDESCRIPTION_H #include "rcc/CodeGen/InstructionDescriptor.h" +#include "rcc/CodeGen/TargetMIRTextInfo.h" #include "rcc/CodeGen/TargetRegisterInfo.h" #include "rcc/Support/Error.h" @@ -15,6 +16,8 @@ namespace rcc { class MachineBasicBlock; +class MachineCFIInfo; +class MachineFrameInfo; class MachineInstr; class MachineMemOperand; class MachineRegisterInfo; @@ -29,7 +32,8 @@ public: ~TargetDescription() = default; [[nodiscard]] static Expected create(InstructionSet Instructions, - TargetRegisterInfo Registers); + TargetRegisterInfo Registers, + TargetMIRTextInfoDesc MIRText = {}); [[nodiscard]] const InstructionSet &instructions() const noexcept { return Instructions; @@ -39,6 +43,10 @@ public: return Registers; } + [[nodiscard]] const TargetMIRTextInfo &mirText() const noexcept { + return MIRText; + } + [[nodiscard]] const InstructionDescriptor * instructionDescriptor(Opcode InstructionOpcode) const noexcept { return Instructions.descriptor(InstructionOpcode); @@ -61,11 +69,11 @@ public: std::span Ties) const; [[nodiscard]] Expected validateMemOperands(Opcode InstructionOpcode, - std::span MemOperands) const { - return Instructions.validateMemOperands(InstructionOpcode, MemOperands); - } + std::span MemOperands) const; [[nodiscard]] Expected validateInstruction(const MachineInstr &Instruction, const MachineRegisterInfo &RegInfo) const; + [[nodiscard]] Expected validateCFIInfo(const MachineCFIInfo &Info) const; + [[nodiscard]] Expected validateFrameInfo(const MachineFrameInfo &Info) const; [[nodiscard]] Expected validateRegisterInfo(const MachineRegisterInfo &RegInfo) const; [[nodiscard]] Expected validateBlockLiveIns(const MachineBasicBlock &Block) const; @@ -75,8 +83,10 @@ public: } private: - TargetDescription(InstructionSet Instructions, TargetRegisterInfo Registers) - : Instructions(std::move(Instructions)), Registers(std::move(Registers)) {} + TargetDescription(InstructionSet Instructions, TargetRegisterInfo Registers, + TargetMIRTextInfo MIRText) + : Instructions(std::move(Instructions)), Registers(std::move(Registers)), + MIRText(std::move(MIRText)) {} [[nodiscard]] Expected validateTargetOperand(const OperandDescriptor *Descriptor, const MachineOperand &Operand, @@ -91,6 +101,7 @@ private: InstructionSet Instructions; TargetRegisterInfo Registers; + TargetMIRTextInfo MIRText; }; } // namespace rcc diff --git a/backend/include/rcc/CodeGen/TargetMIRTextInfo.h b/backend/include/rcc/CodeGen/TargetMIRTextInfo.h new file mode 100644 index 0000000..4fdbb3a --- /dev/null +++ b/backend/include/rcc/CodeGen/TargetMIRTextInfo.h @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_TARGETMIRTEXTINFO_H +#define RCC_CODEGEN_TARGETMIRTEXTINFO_H + +#include "rcc/CodeGen/MachineFrameInfo.h" +#include "rcc/CodeGen/MachineIRTypes.h" +#include "rcc/CodeGen/Register.h" +#include "rcc/CodeGen/RegisterMask.h" +#include "rcc/Support/Error.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rcc { + +class TargetRegisterInfo; + +struct MIRRegisterMaskDesc final { + std::string Name; + std::shared_ptr Mask; +}; + +struct MIRTargetIndexDesc final { + std::string Name; + TargetIndex Index; +}; + +struct MIROperandFlagDesc final { + std::string Name; + std::uint32_t Value = 0; +}; + +struct MIRMachineMemOperandFlagDesc final { + std::string Name; + std::uint16_t Value = 0; +}; + +struct MIRVirtualRegisterFlagDesc final { + std::string Name; + std::uint8_t Value = 0; +}; + +struct MIRIntrinsicDesc final { + std::string Name; + IntrinsicID ID; +}; + +struct MIRCFIRegisterMappingDesc final { + PhysicalRegister Register; + std::uint32_t DwarfRegister = 0; + bool IsCanonical = true; +}; + +struct TargetMIRTextInfoDesc final { + std::vector RegisterMasks; + std::vector TargetIndices; + std::uint32_t DirectOperandFlagMask = 0; + std::vector DirectOperandFlags; + std::vector BitmaskOperandFlags; + std::vector MachineMemOperandFlags; + std::vector VirtualRegisterFlags; + std::vector Intrinsics; + std::vector CFIRegisters; + std::vector SupportedStackIDs{ + StackID::defaultStack(), + StackID::noAllocStack(), + }; + std::optional FunctionStateType; +}; + +class TargetMIRTextInfo final { +public: + TargetMIRTextInfo(const TargetMIRTextInfo &) = delete; + TargetMIRTextInfo &operator=(const TargetMIRTextInfo &) = delete; + TargetMIRTextInfo(TargetMIRTextInfo &&) noexcept = default; + TargetMIRTextInfo &operator=(TargetMIRTextInfo &&) noexcept = default; + ~TargetMIRTextInfo() = default; + + [[nodiscard]] static Expected create(TargetMIRTextInfoDesc Description, + const TargetRegisterInfo &Registers); + + [[nodiscard]] std::span registerMasks() const noexcept { + return Description.RegisterMasks; + } + + [[nodiscard]] std::span targetIndices() const noexcept { + return Description.TargetIndices; + } + + [[nodiscard]] std::span directOperandFlags() const noexcept { + return Description.DirectOperandFlags; + } + + [[nodiscard]] std::span bitmaskOperandFlags() const noexcept { + return Description.BitmaskOperandFlags; + } + + [[nodiscard]] std::span + machineMemOperandFlags() const noexcept { + return Description.MachineMemOperandFlags; + } + + [[nodiscard]] std::span virtualRegisterFlags() const noexcept { + return Description.VirtualRegisterFlags; + } + + [[nodiscard]] std::span intrinsics() const noexcept { + return Description.Intrinsics; + } + + [[nodiscard]] std::shared_ptr + registerMask(std::string_view Name) const noexcept; + [[nodiscard]] std::optional + registerMaskName(const RegisterMask &Mask) const noexcept; + + [[nodiscard]] std::optional targetIndex(std::string_view Name) const noexcept; + [[nodiscard]] std::optional targetIndexName(TargetIndex Index) const noexcept; + + [[nodiscard]] std::optional + directOperandFlag(std::string_view Name) const noexcept; + [[nodiscard]] std::optional + bitmaskOperandFlag(std::string_view Name) const noexcept; + [[nodiscard]] Expected> operandFlagNames(std::uint32_t Flags) const; + [[nodiscard]] Expected validateOperandFlags(std::uint32_t Flags) const; + + [[nodiscard]] std::optional + machineMemOperandFlag(std::string_view Name) const noexcept; + [[nodiscard]] Expected> + machineMemOperandFlagNames(std::uint16_t Flags) const; + [[nodiscard]] Expected validateMachineMemOperandFlags(std::uint16_t Flags) const; + + [[nodiscard]] std::optional + virtualRegisterFlag(std::string_view Name) const noexcept; + [[nodiscard]] Expected> + virtualRegisterFlagNames(std::uint8_t Flags) const; + [[nodiscard]] Expected validateVirtualRegisterFlags(std::uint8_t Flags) const; + + [[nodiscard]] std::optional intrinsic(std::string_view Name) const noexcept; + [[nodiscard]] std::optional intrinsicName(IntrinsicID ID) const noexcept; + + [[nodiscard]] std::optional + dwarfRegister(PhysicalRegister Register) const noexcept; + [[nodiscard]] std::optional + physicalRegister(std::uint32_t DwarfRegister) const noexcept; + + [[nodiscard]] std::span supportedStackIDs() const noexcept { + return Description.SupportedStackIDs; + } + + [[nodiscard]] bool supportsStackID(StackID ID) const noexcept { + return SupportedStackIDs.contains(ID.value()); + } + + [[nodiscard]] std::uint32_t directOperandFlagMask() const noexcept { + return Description.DirectOperandFlagMask; + } + + [[nodiscard]] std::uint32_t serializableOperandFlagMask() const noexcept { + return SerializableOperandFlagMask; + } + + [[nodiscard]] std::uint16_t serializableMachineMemOperandFlagMask() const noexcept { + return SerializableMachineMemOperandFlagMask; + } + + [[nodiscard]] std::uint8_t serializableVirtualRegisterFlagMask() const noexcept { + return SerializableVirtualRegisterFlagMask; + } + + [[nodiscard]] std::optional functionStateType() const noexcept { + return Description.FunctionStateType; + } + +private: + explicit TargetMIRTextInfo(TargetMIRTextInfoDesc Description) + : Description(std::move(Description)) {} + + TargetMIRTextInfoDesc Description; + std::unordered_map RegisterMaskNameToIndex; + std::unordered_map TargetIndexNameToIndex; + std::unordered_map TargetIndexToIndex; + std::unordered_map DirectOperandFlagNameToIndex; + std::unordered_map DirectOperandFlagToIndex; + std::unordered_map BitmaskOperandFlagNameToIndex; + std::unordered_map MachineMemOperandFlagNameToIndex; + std::unordered_map VirtualRegisterFlagNameToIndex; + std::unordered_map IntrinsicNameToIndex; + std::unordered_map IntrinsicToIndex; + std::unordered_map RegisterToDwarf; + std::unordered_map DwarfToRegister; + std::unordered_set SupportedStackIDs; + std::uint32_t SerializableOperandFlagMask = 0; + std::uint16_t SerializableMachineMemOperandFlagMask = 0; + std::uint8_t SerializableVirtualRegisterFlagMask = 0; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_TARGETMIRTEXTINFO_H diff --git a/backend/include/rcc/CodeGen/TargetRegisterInfo.h b/backend/include/rcc/CodeGen/TargetRegisterInfo.h index 5d7de2c..9357eb2 100644 --- a/backend/include/rcc/CodeGen/TargetRegisterInfo.h +++ b/backend/include/rcc/CodeGen/TargetRegisterInfo.h @@ -129,8 +129,18 @@ public: [[nodiscard]] const PhysicalRegisterDesc *physicalRegister(PhysicalRegister Reg) const noexcept; [[nodiscard]] const PhysicalRegisterDesc *physicalRegister(std::string_view Name) const noexcept; [[nodiscard]] const SubRegIndexDesc *subRegIndex(SubRegIndex Index) const noexcept; + [[nodiscard]] const SubRegIndexDesc *subRegIndex(std::string_view Name) const noexcept; [[nodiscard]] const RegisterClassDesc *registerClass(RegisterClassID ID) const noexcept; + [[nodiscard]] const RegisterClassDesc *registerClass(std::string_view Name) const noexcept; [[nodiscard]] const RegisterBankDesc *registerBank(RegisterBankID ID) const noexcept; + [[nodiscard]] const RegisterBankDesc *registerBank(std::string_view Name) const noexcept; + + [[nodiscard]] std::optional + physicalRegisterMIRName(PhysicalRegister Reg) const noexcept; + [[nodiscard]] std::optional + registerClassMIRName(RegisterClassID ID) const noexcept; + [[nodiscard]] std::optional + registerBankMIRName(RegisterBankID ID) const noexcept; [[nodiscard]] bool isKnownPhysicalRegister(PhysicalRegister Reg) const noexcept { return physicalRegister(Reg) != nullptr; @@ -177,14 +187,20 @@ private: std::unordered_map RegisterToIndex; std::unordered_map RegisterNameToIndex; std::unordered_map SubRegIndexToIndex; + std::unordered_map SubRegNameToIndex; std::unordered_map ClassToIndex; + std::unordered_map ClassNameToIndex; std::unordered_map BankToIndex; + std::unordered_map BankNameToIndex; std::unordered_map SubRegisterMap; std::unordered_map CompositionMap; std::unordered_map SubRegClassMap; std::unordered_set SubclassRelations; std::vector> Aliases; std::vector> SuperRegisters; + std::vector RegisterMIRNames; + std::vector ClassMIRNames; + std::vector BankMIRNames; }; } // namespace rcc -- cgit v1.2.3