// 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 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; } [[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 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 #endif // RCC_CODEGEN_TARGETREGISTERINFO_H