From 787f3a7a20958bfa6f231abccc617f4d8de25c4d Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 1 Aug 2026 17:36:40 +0800 Subject: [CodeGen] Add MIR function and block attributes --- backend/include/rcc/CodeGen/MachineBasicBlock.h | 10 + .../rcc/CodeGen/MachineBasicBlockAttributes.h | 208 +++++++++++++++++++++ backend/include/rcc/CodeGen/MachineFunction.h | 10 + .../rcc/CodeGen/MachineFunctionAttributes.h | 100 ++++++++++ backend/include/rcc/CodeGen/MachineIRTypes.h | 25 +++ backend/include/rcc/CodeGen/MachineMemOperand.h | 18 -- 6 files changed, 353 insertions(+), 18 deletions(-) create mode 100644 backend/include/rcc/CodeGen/MachineBasicBlockAttributes.h create mode 100644 backend/include/rcc/CodeGen/MachineFunctionAttributes.h (limited to 'backend/include') diff --git a/backend/include/rcc/CodeGen/MachineBasicBlock.h b/backend/include/rcc/CodeGen/MachineBasicBlock.h index ba59160..d82477a 100644 --- a/backend/include/rcc/CodeGen/MachineBasicBlock.h +++ b/backend/include/rcc/CodeGen/MachineBasicBlock.h @@ -3,6 +3,7 @@ #ifndef RCC_CODEGEN_MACHINEBASICBLOCK_H #define RCC_CODEGEN_MACHINEBASICBLOCK_H +#include "rcc/CodeGen/MachineBasicBlockAttributes.h" #include "rcc/CodeGen/MachineIRTypes.h" #include "rcc/CodeGen/Register.h" #include "rcc/CodeGen/StableID.h" @@ -124,6 +125,14 @@ public: return LayoutIndex; } + [[nodiscard]] MachineBasicBlockAttributes &attributes() noexcept { + return Attributes; + } + + [[nodiscard]] const MachineBasicBlockAttributes &attributes() const noexcept { + return Attributes; + } + private: MachineBasicBlock(MachineFunction &OwnerFunction, MachineBlockStableID StableID) : OwnerFunction(&OwnerFunction), StableID(StableID) {} @@ -138,6 +147,7 @@ private: std::vector Predecessors; std::vector Successors; std::vector LiveIns; + MachineBasicBlockAttributes Attributes; std::optional DenseNumber; std::optional LayoutIndex; diff --git a/backend/include/rcc/CodeGen/MachineBasicBlockAttributes.h b/backend/include/rcc/CodeGen/MachineBasicBlockAttributes.h new file mode 100644 index 0000000..7b132d2 --- /dev/null +++ b/backend/include/rcc/CodeGen/MachineBasicBlockAttributes.h @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_MACHINEBASICBLOCKATTRIBUTES_H +#define RCC_CODEGEN_MACHINEBASICBLOCKATTRIBUTES_H + +#include "rcc/CodeGen/MachineIRTypes.h" +#include "rcc/Support/Error.h" + +#include +#include +#include +#include + +namespace rcc { + +enum class MachineBasicBlockAttribute : std::uint8_t { + MachineBlockAddressTaken, + IRBlockAddressTaken, + LandingPad, + InlineAsmBrIndirectTarget, + EHFuncletEntry, + EHScopeEntry, + Count, +}; + +[[nodiscard]] std::string_view +getMachineBasicBlockAttributeName(MachineBasicBlockAttribute Attribute) noexcept; + +enum class MachineBasicBlockSectionKind : std::uint8_t { + Numbered, + Exception, + Cold, +}; + +class MachineBasicBlockSectionID final { +public: + constexpr MachineBasicBlockSectionID() noexcept = default; + + [[nodiscard]] static constexpr MachineBasicBlockSectionID + numbered(std::uint32_t Number) noexcept { + return MachineBasicBlockSectionID(MachineBasicBlockSectionKind::Numbered, Number); + } + + [[nodiscard]] static constexpr MachineBasicBlockSectionID exception() noexcept { + return MachineBasicBlockSectionID(MachineBasicBlockSectionKind::Exception, 0); + } + + [[nodiscard]] static constexpr MachineBasicBlockSectionID cold() noexcept { + return MachineBasicBlockSectionID(MachineBasicBlockSectionKind::Cold, 0); + } + + [[nodiscard]] constexpr MachineBasicBlockSectionKind kind() const noexcept { + return Kind; + } + + [[nodiscard]] constexpr std::uint32_t number() const noexcept { + return Number; + } + + [[nodiscard]] constexpr bool isDefault() const noexcept { + return Kind == MachineBasicBlockSectionKind::Numbered && Number == 0; + } + + friend constexpr bool operator==(MachineBasicBlockSectionID Left, + MachineBasicBlockSectionID Right) noexcept = default; + +private: + constexpr MachineBasicBlockSectionID(MachineBasicBlockSectionKind Kind, + std::uint32_t Number) noexcept + : Kind(Kind), Number(Number) {} + + MachineBasicBlockSectionKind Kind = MachineBasicBlockSectionKind::Numbered; + std::uint32_t Number = 0; +}; + +struct MachineBasicBlockProfileID final { + std::uint32_t BaseID = 0; + std::uint32_t CloneID = 0; + + friend constexpr bool operator==(MachineBasicBlockProfileID Left, + MachineBasicBlockProfileID Right) noexcept = default; +}; + +class MachineBasicBlockAttributes final { +public: + MachineBasicBlockAttributes() = default; + + [[nodiscard]] static Expected fromRawFlags(std::uint8_t RawFlags); + + [[nodiscard]] bool has(MachineBasicBlockAttribute Attribute) const noexcept { + if (!isValidAttribute(Attribute)) + return false; + return (Flags & flagFor(Attribute)) != 0; + } + + void set(MachineBasicBlockAttribute Attribute) noexcept { + if (isValidAttribute(Attribute)) + Flags |= flagFor(Attribute); + } + + void clear(MachineBasicBlockAttribute Attribute) noexcept { + if (isValidAttribute(Attribute)) + Flags &= static_cast(~flagFor(Attribute)); + } + + [[nodiscard]] std::uint8_t rawFlags() const noexcept { + return Flags; + } + + [[nodiscard]] std::optional name() const noexcept { + if (!Name) + return std::nullopt; + return *Name; + } + + [[nodiscard]] Expected setName(std::string NewName); + + void clearName() noexcept { + Name.reset(); + } + + [[nodiscard]] std::optional irBlockName() const noexcept { + if (!IRBlockName) + return std::nullopt; + return *IRBlockName; + } + + [[nodiscard]] Expected setIRBlockName(std::string NewName); + + void clearIRBlockName() noexcept { + IRBlockName.reset(); + } + + [[nodiscard]] Alignment alignment() const noexcept { + return BlockAlignment; + } + + void setAlignment(Alignment NewAlignment) noexcept { + BlockAlignment = NewAlignment; + } + + void clearAlignment() noexcept { + BlockAlignment = Alignment{}; + } + + [[nodiscard]] MachineBasicBlockSectionID sectionID() const noexcept { + return SectionID; + } + + void setSectionID(MachineBasicBlockSectionID NewSectionID) noexcept { + SectionID = NewSectionID; + } + + [[nodiscard]] const std::optional &profileID() const noexcept { + return ProfileID; + } + + void setProfileID(MachineBasicBlockProfileID NewProfileID) noexcept { + ProfileID = NewProfileID; + } + + void clearProfileID() noexcept { + ProfileID.reset(); + } + + [[nodiscard]] std::uint32_t callFrameSize() const noexcept { + return CallFrameSize; + } + + void setCallFrameSize(std::uint32_t Size) noexcept { + CallFrameSize = Size; + } + + [[nodiscard]] Expected verify() const; + + friend bool operator==(const MachineBasicBlockAttributes &Left, + const MachineBasicBlockAttributes &Right) = default; + +private: + static constexpr std::uint8_t AttributeCount = + static_cast(MachineBasicBlockAttribute::Count); + static_assert(AttributeCount < 8); + + static constexpr std::uint8_t ValidFlags = + static_cast((std::uint8_t{1} << AttributeCount) - 1); + + [[nodiscard]] static constexpr bool + isValidAttribute(MachineBasicBlockAttribute Attribute) noexcept { + return static_cast(Attribute) < AttributeCount; + } + + [[nodiscard]] static constexpr std::uint8_t + flagFor(MachineBasicBlockAttribute Attribute) noexcept { + return static_cast(std::uint8_t{1} << static_cast(Attribute)); + } + + std::uint8_t Flags = 0; + std::optional Name; + std::optional IRBlockName; + Alignment BlockAlignment; + MachineBasicBlockSectionID SectionID; + std::optional ProfileID; + std::uint32_t CallFrameSize = 0; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_MACHINEBASICBLOCKATTRIBUTES_H diff --git a/backend/include/rcc/CodeGen/MachineFunction.h b/backend/include/rcc/CodeGen/MachineFunction.h index b687573..4ed660d 100644 --- a/backend/include/rcc/CodeGen/MachineFunction.h +++ b/backend/include/rcc/CodeGen/MachineFunction.h @@ -6,6 +6,7 @@ #include "rcc/CodeGen/MachineCompilationStatus.h" #include "rcc/CodeGen/MachineConstantPool.h" #include "rcc/CodeGen/MachineFrameInfo.h" +#include "rcc/CodeGen/MachineFunctionAttributes.h" #include "rcc/CodeGen/MachineFunctionProperties.h" #include "rcc/CodeGen/MachineJumpTableInfo.h" #include "rcc/CodeGen/MachineRegisterInfo.h" @@ -89,6 +90,14 @@ public: return Properties; } + [[nodiscard]] MachineFunctionAttributes &attributes() noexcept { + return Attributes; + } + + [[nodiscard]] const MachineFunctionAttributes &attributes() const noexcept { + return Attributes; + } + [[nodiscard]] const TargetFunctionState &targetState() const noexcept { return TargetState; } @@ -166,6 +175,7 @@ private: MachineConstantPool ConstantPool; MachineJumpTableInfo JumpTables; MachineFunctionProperties Properties; + MachineFunctionAttributes Attributes; TargetFunctionState TargetState; MachineCompilationStatus CompilationStatus; MachineBasicBlock *FirstBlock = nullptr; diff --git a/backend/include/rcc/CodeGen/MachineFunctionAttributes.h b/backend/include/rcc/CodeGen/MachineFunctionAttributes.h new file mode 100644 index 0000000..4344640 --- /dev/null +++ b/backend/include/rcc/CodeGen/MachineFunctionAttributes.h @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_MACHINEFUNCTIONATTRIBUTES_H +#define RCC_CODEGEN_MACHINEFUNCTIONATTRIBUTES_H + +#include "rcc/CodeGen/MachineIRTypes.h" +#include "rcc/Support/Error.h" + +#include +#include +#include + +namespace rcc { + +enum class MachineFunctionAttribute : std::uint8_t { + ExposesReturnsTwice, + HasWinCFI, + HasFakeUses, + CallsEHReturn, + CallsUnwindInit, + HasEHContTarget, + HasEHScopes, + HasEHFunclets, + IsOutlined, + DebugInstrRef, + TracksDebugUserValues, + Count, +}; + +[[nodiscard]] std::string_view +getMachineFunctionAttributeName(MachineFunctionAttribute Attribute) noexcept; + +class MachineFunctionAttributes final { +public: + constexpr MachineFunctionAttributes() noexcept = default; + + [[nodiscard]] static Expected fromRawFlags(std::uint16_t RawFlags); + + [[nodiscard]] constexpr bool has(MachineFunctionAttribute Attribute) const noexcept { + if (!isValidAttribute(Attribute)) + return false; + return (Flags & flagFor(Attribute)) != 0; + } + + constexpr void set(MachineFunctionAttribute Attribute) noexcept { + if (isValidAttribute(Attribute)) + Flags |= flagFor(Attribute); + } + + constexpr void clear(MachineFunctionAttribute Attribute) noexcept { + if (isValidAttribute(Attribute)) + Flags &= static_cast(~flagFor(Attribute)); + } + + [[nodiscard]] constexpr std::uint16_t rawFlags() const noexcept { + return Flags; + } + + [[nodiscard]] std::optional alignment() const noexcept { + return FunctionAlignment; + } + + void setAlignment(Alignment NewAlignment) noexcept { + FunctionAlignment = NewAlignment; + } + + void clearAlignment() noexcept { + FunctionAlignment.reset(); + } + + [[nodiscard]] Expected verify() const; + + friend bool operator==(const MachineFunctionAttributes &Left, + const MachineFunctionAttributes &Right) = default; + +private: + static constexpr std::uint16_t AttributeCount = + static_cast(MachineFunctionAttribute::Count); + static_assert(AttributeCount < 16); + + static constexpr std::uint16_t ValidFlags = + static_cast((std::uint16_t{1} << AttributeCount) - 1); + + [[nodiscard]] static constexpr bool + isValidAttribute(MachineFunctionAttribute Attribute) noexcept { + return static_cast(Attribute) < AttributeCount; + } + + [[nodiscard]] static constexpr std::uint16_t + flagFor(MachineFunctionAttribute Attribute) noexcept { + return static_cast(std::uint16_t{1} << static_cast(Attribute)); + } + + std::uint16_t Flags = 0; + std::optional FunctionAlignment; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_MACHINEFUNCTIONATTRIBUTES_H diff --git a/backend/include/rcc/CodeGen/MachineIRTypes.h b/backend/include/rcc/CodeGen/MachineIRTypes.h index 8906bbe..90aa2b7 100644 --- a/backend/include/rcc/CodeGen/MachineIRTypes.h +++ b/backend/include/rcc/CodeGen/MachineIRTypes.h @@ -83,6 +83,24 @@ using TargetConstantTypeID = MachineIndex; using TargetRelocationKindID = MachineIndex; +class Alignment final { +public: + constexpr Alignment() noexcept = default; + + [[nodiscard]] static Expected create(std::uint64_t Bytes); + + [[nodiscard]] constexpr std::uint64_t bytes() const noexcept { + return Bytes; + } + + friend constexpr bool operator==(Alignment Left, Alignment Right) noexcept = default; + +private: + explicit constexpr Alignment(std::uint64_t Bytes) noexcept : Bytes(Bytes) {} + + std::uint64_t Bytes = 1; +}; + class Opcode final { public: constexpr Opcode() noexcept = default; @@ -215,6 +233,12 @@ enum class MachineInstrFlag : std::uint8_t { BundledWithSucc, NoMerge, Unpredictable, + NoConvergent, + NonNeg, + Disjoint, + NoUSWrap, + SameSign, + InBounds, Count, }; @@ -268,6 +292,7 @@ struct SourceLocation final { }; static_assert(sizeof(Opcode) == sizeof(std::uint32_t)); +static_assert(sizeof(Alignment) == sizeof(std::uint64_t)); static_assert(sizeof(FrameIndex) == sizeof(std::uint32_t)); static_assert(sizeof(MemoryAliasSourceID) == sizeof(std::uint64_t)); static_assert(std::is_trivially_copyable_v); diff --git a/backend/include/rcc/CodeGen/MachineMemOperand.h b/backend/include/rcc/CodeGen/MachineMemOperand.h index e513385..3f1fc64 100644 --- a/backend/include/rcc/CodeGen/MachineMemOperand.h +++ b/backend/include/rcc/CodeGen/MachineMemOperand.h @@ -80,24 +80,6 @@ enum class AtomicOrdering : std::uint8_t { SequentiallyConsistent, }; -class Alignment final { -public: - constexpr Alignment() noexcept = default; - - [[nodiscard]] static Expected create(std::uint64_t Bytes); - - [[nodiscard]] constexpr std::uint64_t bytes() const noexcept { - return Bytes; - } - - friend constexpr bool operator==(Alignment Left, Alignment Right) noexcept = default; - -private: - explicit constexpr Alignment(std::uint64_t Bytes) noexcept : Bytes(Bytes) {} - - std::uint64_t Bytes = 1; -}; - class MemorySize final { public: enum class Kind : std::uint8_t { -- cgit v1.2.3