From 924dcd36ebed84f04729de05ec08b311a36a04c1 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 1 Aug 2026 16:07:24 +0800 Subject: [CodeGen] Add target register descriptions Introduce an immutable register topology for units, subregisters, classes, banks, and preserved masks. Bind instruction descriptors to this topology through TargetDescription so builders, cloning, and verification share one target-aware contract. Add the test-only TestTarget model and positive and negative target fact coverage. --- backend/include/rcc/CodeGen/TargetRegisterInfo.h | 192 +++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 backend/include/rcc/CodeGen/TargetRegisterInfo.h (limited to 'backend/include/rcc/CodeGen/TargetRegisterInfo.h') diff --git a/backend/include/rcc/CodeGen/TargetRegisterInfo.h b/backend/include/rcc/CodeGen/TargetRegisterInfo.h new file mode 100644 index 0000000..5d7de2c --- /dev/null +++ b/backend/include/rcc/CodeGen/TargetRegisterInfo.h @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_TARGETREGISTERINFO_H +#define RCC_CODEGEN_TARGETREGISTERINFO_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 { + +struct RegisterUnitDesc final { + RegisterUnitID ID; + std::string Name; +}; + +struct RegisterUnitLane final { + RegisterUnitID Unit; + LaneMask Lanes; +}; + +struct PhysicalRegisterDesc final { + PhysicalRegister Reg; + std::string Name; + std::uint32_t Encoding = 0; + std::vector Units; + bool IsConstant = false; + bool IsArtificial = false; +}; + +struct SubRegIndexDesc final { + SubRegIndex ID; + std::string Name; + LaneMask Lanes; + std::uint32_t SizeInBits = 0; + std::uint32_t OffsetInBits = 0; +}; + +struct PhysicalSubRegisterDesc final { + PhysicalRegister SuperReg; + SubRegIndex Index; + PhysicalRegister SubReg; +}; + +struct SubRegIndexComposition final { + SubRegIndex First; + SubRegIndex Second; + SubRegIndex Result; +}; + +struct RegisterClassDesc final { + RegisterClassID ID; + std::string Name; + std::vector Registers; + std::vector AllocationOrder; + std::uint32_t SizeInBits = 0; + std::uint32_t SpillSizeInBits = 0; + std::uint32_t SpillAlignmentInBits = 0; + LaneMask Lanes; + std::vector SupportedSubRegs; + std::vector SuperClasses; + RegisterBankID DefaultBank; + bool Allocatable = true; + std::uint32_t CopyCost = 1; + bool CoveredBySubRegs = false; +}; + +struct SubRegClassMapping final { + RegisterClassID SourceClass; + SubRegIndex Index; + RegisterClassID ResultClass; +}; + +struct RegisterBankDesc final { + RegisterBankID ID; + std::string Name; + std::uint32_t MaximumSizeInBits = 0; + std::vector RegisterClasses; +}; + +struct TargetRegisterInfoDesc final { + std::vector RegisterUnits; + std::vector PhysicalRegisters; + std::vector SubRegIndices; + std::vector PhysicalSubRegisters; + std::vector SubRegCompositions; + std::vector RegisterClasses; + std::vector SubRegClassMappings; + std::vector RegisterBanks; +}; + +class TargetRegisterInfo final { +public: + [[nodiscard]] static Expected create(TargetRegisterInfoDesc Description); + + [[nodiscard]] std::span registerUnits() const noexcept { + return Description.RegisterUnits; + } + + [[nodiscard]] std::span physicalRegisters() const noexcept { + return Description.PhysicalRegisters; + } + + [[nodiscard]] std::span subRegIndices() const noexcept { + return Description.SubRegIndices; + } + + [[nodiscard]] std::span registerClasses() const noexcept { + return Description.RegisterClasses; + } + + [[nodiscard]] std::span registerBanks() const noexcept { + return Description.RegisterBanks; + } + + [[nodiscard]] const RegisterUnitDesc *registerUnit(RegisterUnitID ID) const noexcept; + [[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 RegisterClassDesc *registerClass(RegisterClassID ID) const noexcept; + [[nodiscard]] const RegisterBankDesc *registerBank(RegisterBankID ID) const noexcept; + + [[nodiscard]] bool isKnownPhysicalRegister(PhysicalRegister Reg) const noexcept { + return physicalRegister(Reg) != nullptr; + } + + [[nodiscard]] LaneMask registerLaneMask(PhysicalRegister Reg) const noexcept; + [[nodiscard]] bool isValidLaneMask(PhysicalRegister Reg, LaneMask Lanes) const noexcept; + [[nodiscard]] bool regsOverlap(PhysicalRegister Left, PhysicalRegister Right) const noexcept; + [[nodiscard]] std::span aliases(PhysicalRegister Reg) const noexcept; + + [[nodiscard]] std::optional subRegister(PhysicalRegister SuperReg, + SubRegIndex Index) const noexcept; + [[nodiscard]] bool isSubRegister(PhysicalRegister SuperReg, + PhysicalRegister SubReg) const noexcept; + [[nodiscard]] std::span + superRegisters(PhysicalRegister Reg) const noexcept; + [[nodiscard]] std::optional composeSubRegIndices(SubRegIndex First, + SubRegIndex Second) const noexcept; + + [[nodiscard]] bool registerClassContains(RegisterClassID Class, + PhysicalRegister Reg) const noexcept; + [[nodiscard]] bool isSubclass(RegisterClassID Candidate, RegisterClassID Required) const noexcept; + [[nodiscard]] bool registerClassesOverlap(RegisterClassID Left, + RegisterClassID Right) const noexcept; + [[nodiscard]] std::optional subRegClass(RegisterClassID Source, + SubRegIndex Index) const noexcept; + + [[nodiscard]] bool bankCoversClass(RegisterBankID Bank, RegisterClassID Class) const noexcept; + [[nodiscard]] bool bankContainsRegister(RegisterBankID Bank, PhysicalRegister Reg) const noexcept; + [[nodiscard]] bool registerBanksOverlap(RegisterBankID Left, RegisterBankID Right) const noexcept; + + [[nodiscard]] Expected validateRegisterMask(const RegisterMask &Mask) const; + +private: + explicit TargetRegisterInfo(TargetRegisterInfoDesc Description) + : Description(std::move(Description)) {} + + [[nodiscard]] static std::uint64_t pairKey(std::uint32_t First, std::uint32_t Second) noexcept { + return (static_cast(First) << 32U) | Second; + } + + TargetRegisterInfoDesc Description; + std::unordered_map UnitToIndex; + std::unordered_map RegisterToIndex; + std::unordered_map RegisterNameToIndex; + std::unordered_map SubRegIndexToIndex; + std::unordered_map ClassToIndex; + std::unordered_map BankToIndex; + std::unordered_map SubRegisterMap; + std::unordered_map CompositionMap; + std::unordered_map SubRegClassMap; + std::unordered_set SubclassRelations; + std::vector> Aliases; + std::vector> SuperRegisters; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_TARGETREGISTERINFO_H -- cgit v1.2.3