aboutsummaryrefslogtreecommitdiff
path: root/backend/include
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 17:36:40 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 17:36:40 +0800
commit787f3a7a20958bfa6f231abccc617f4d8de25c4d (patch)
tree775d2913f48fc5f3a6e44bc6da986da9e52754ef /backend/include
parent77d76b73a614820bf45024b053db376f35b06d10 (diff)
downloadrcc-project-787f3a7a20958bfa6f231abccc617f4d8de25c4d.tar.gz
rcc-project-787f3a7a20958bfa6f231abccc617f4d8de25c4d.tar.xz
[CodeGen] Add MIR function and block attributes
Diffstat (limited to 'backend/include')
-rw-r--r--backend/include/rcc/CodeGen/MachineBasicBlock.h10
-rw-r--r--backend/include/rcc/CodeGen/MachineBasicBlockAttributes.h208
-rw-r--r--backend/include/rcc/CodeGen/MachineFunction.h10
-rw-r--r--backend/include/rcc/CodeGen/MachineFunctionAttributes.h100
-rw-r--r--backend/include/rcc/CodeGen/MachineIRTypes.h25
-rw-r--r--backend/include/rcc/CodeGen/MachineMemOperand.h18
6 files changed, 353 insertions, 18 deletions
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<MachineBasicBlock *> Predecessors;
std::vector<MachineSuccessor> Successors;
std::vector<MachineBasicBlockLiveIn> LiveIns;
+ MachineBasicBlockAttributes Attributes;
std::optional<std::uint32_t> DenseNumber;
std::optional<std::uint32_t> 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 <cstdint>
+#include <optional>
+#include <string>
+#include <string_view>
+
+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<MachineBasicBlockAttributes> 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<std::uint8_t>(~flagFor(Attribute));
+ }
+
+ [[nodiscard]] std::uint8_t rawFlags() const noexcept {
+ return Flags;
+ }
+
+ [[nodiscard]] std::optional<std::string_view> name() const noexcept {
+ if (!Name)
+ return std::nullopt;
+ return *Name;
+ }
+
+ [[nodiscard]] Expected<void> setName(std::string NewName);
+
+ void clearName() noexcept {
+ Name.reset();
+ }
+
+ [[nodiscard]] std::optional<std::string_view> irBlockName() const noexcept {
+ if (!IRBlockName)
+ return std::nullopt;
+ return *IRBlockName;
+ }
+
+ [[nodiscard]] Expected<void> 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<MachineBasicBlockProfileID> &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<void> verify() const;
+
+ friend bool operator==(const MachineBasicBlockAttributes &Left,
+ const MachineBasicBlockAttributes &Right) = default;
+
+private:
+ static constexpr std::uint8_t AttributeCount =
+ static_cast<std::uint8_t>(MachineBasicBlockAttribute::Count);
+ static_assert(AttributeCount < 8);
+
+ static constexpr std::uint8_t ValidFlags =
+ static_cast<std::uint8_t>((std::uint8_t{1} << AttributeCount) - 1);
+
+ [[nodiscard]] static constexpr bool
+ isValidAttribute(MachineBasicBlockAttribute Attribute) noexcept {
+ return static_cast<std::uint8_t>(Attribute) < AttributeCount;
+ }
+
+ [[nodiscard]] static constexpr std::uint8_t
+ flagFor(MachineBasicBlockAttribute Attribute) noexcept {
+ return static_cast<std::uint8_t>(std::uint8_t{1} << static_cast<std::uint8_t>(Attribute));
+ }
+
+ std::uint8_t Flags = 0;
+ std::optional<std::string> Name;
+ std::optional<std::string> IRBlockName;
+ Alignment BlockAlignment;
+ MachineBasicBlockSectionID SectionID;
+ std::optional<MachineBasicBlockProfileID> 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 <cstdint>
+#include <optional>
+#include <string_view>
+
+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<MachineFunctionAttributes> 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<std::uint16_t>(~flagFor(Attribute));
+ }
+
+ [[nodiscard]] constexpr std::uint16_t rawFlags() const noexcept {
+ return Flags;
+ }
+
+ [[nodiscard]] std::optional<Alignment> alignment() const noexcept {
+ return FunctionAlignment;
+ }
+
+ void setAlignment(Alignment NewAlignment) noexcept {
+ FunctionAlignment = NewAlignment;
+ }
+
+ void clearAlignment() noexcept {
+ FunctionAlignment.reset();
+ }
+
+ [[nodiscard]] Expected<void> verify() const;
+
+ friend bool operator==(const MachineFunctionAttributes &Left,
+ const MachineFunctionAttributes &Right) = default;
+
+private:
+ static constexpr std::uint16_t AttributeCount =
+ static_cast<std::uint16_t>(MachineFunctionAttribute::Count);
+ static_assert(AttributeCount < 16);
+
+ static constexpr std::uint16_t ValidFlags =
+ static_cast<std::uint16_t>((std::uint16_t{1} << AttributeCount) - 1);
+
+ [[nodiscard]] static constexpr bool
+ isValidAttribute(MachineFunctionAttribute Attribute) noexcept {
+ return static_cast<std::uint16_t>(Attribute) < AttributeCount;
+ }
+
+ [[nodiscard]] static constexpr std::uint16_t
+ flagFor(MachineFunctionAttribute Attribute) noexcept {
+ return static_cast<std::uint16_t>(std::uint16_t{1} << static_cast<std::uint16_t>(Attribute));
+ }
+
+ std::uint16_t Flags = 0;
+ std::optional<Alignment> 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<detail::TargetConstantTypeIDTag, std::
using TargetFunctionStateTypeID = MachineIndex<detail::TargetFunctionStateTypeIDTag, std::uint64_t>;
using TargetRelocationKindID = MachineIndex<detail::TargetRelocationKindIDTag>;
+class Alignment final {
+public:
+ constexpr Alignment() noexcept = default;
+
+ [[nodiscard]] static Expected<Alignment> 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<Opcode>);
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<Alignment> 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 {