aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-03 19:24:30 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-03 19:24:30 +0800
commit432efe39315ed5ad0162f9c08dbf10941bc21dc1 (patch)
tree46622290cabfaeb8f4db1729aca6f0725739e08c /backend/include/rcc
parent6580ac1c05bd1cbccd2dcd71fd9c2a384ae3db56 (diff)
downloadrcc-project-432efe39315ed5ad0162f9c08dbf10941bc21dc1.tar.gz
rcc-project-432efe39315ed5ad0162f9c08dbf10941bc21dc1.tar.xz
[CodeGen] Add target MIR text schema
Diffstat (limited to 'backend/include/rcc')
-rw-r--r--backend/include/rcc/CodeGen/MachineFrameInfo.h41
-rw-r--r--backend/include/rcc/CodeGen/MachineMemOperand.h1
-rw-r--r--backend/include/rcc/CodeGen/MachineRegisterInfo.h3
-rw-r--r--backend/include/rcc/CodeGen/TargetDescription.h23
-rw-r--r--backend/include/rcc/CodeGen/TargetMIRTextInfo.h208
-rw-r--r--backend/include/rcc/CodeGen/TargetRegisterInfo.h16
6 files changed, 272 insertions, 20 deletions
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 <cstdint>
#include <optional>
#include <span>
+#include <string_view>
#include <utility>
#include <variant>
#include <vector>
@@ -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<StackID> 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<StackID> 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<StackID> 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<MemoryOffsetRange> OffsetRange;
std::optional<MemoryAliasSourceID> 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<RegisterBankID> Bank;
std::optional<RegisterClassID> RegClass;
std::vector<PhysicalRegister> AllocationHints;
+ std::uint8_t TargetFlags = 0;
bool IsTombstone = false;
};
@@ -123,6 +124,8 @@ public:
[[nodiscard]] Expected<void> setRegisterClass(Register Reg, RegisterClassID RegClass);
[[nodiscard]] Expected<void> clearRegisterClass(Register Reg);
[[nodiscard]] Expected<void> addAllocationHint(Register Reg, PhysicalRegister Hint);
+ [[nodiscard]] Expected<void> setTargetRegisterFlags(Register Reg, std::uint8_t Flags);
+ [[nodiscard]] Expected<void> clearTargetRegisterFlags(Register Reg);
void clearAllVirtualRegisterTypes() noexcept;
[[nodiscard]] Expected<void>
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<TargetDescription> 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<const MachineOperandTie> Ties) const;
[[nodiscard]] Expected<void>
validateMemOperands(Opcode InstructionOpcode,
- std::span<const MachineMemOperand *const> MemOperands) const {
- return Instructions.validateMemOperands(InstructionOpcode, MemOperands);
- }
+ std::span<const MachineMemOperand *const> MemOperands) const;
[[nodiscard]] Expected<void> validateInstruction(const MachineInstr &Instruction,
const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void> validateCFIInfo(const MachineCFIInfo &Info) const;
+ [[nodiscard]] Expected<void> validateFrameInfo(const MachineFrameInfo &Info) const;
[[nodiscard]] Expected<void> validateRegisterInfo(const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void> 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<void> 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 <cstdint>
+#include <memory>
+#include <optional>
+#include <span>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+namespace rcc {
+
+class TargetRegisterInfo;
+
+struct MIRRegisterMaskDesc final {
+ std::string Name;
+ std::shared_ptr<const RegisterMask> 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<MIRRegisterMaskDesc> RegisterMasks;
+ std::vector<MIRTargetIndexDesc> TargetIndices;
+ std::uint32_t DirectOperandFlagMask = 0;
+ std::vector<MIROperandFlagDesc> DirectOperandFlags;
+ std::vector<MIROperandFlagDesc> BitmaskOperandFlags;
+ std::vector<MIRMachineMemOperandFlagDesc> MachineMemOperandFlags;
+ std::vector<MIRVirtualRegisterFlagDesc> VirtualRegisterFlags;
+ std::vector<MIRIntrinsicDesc> Intrinsics;
+ std::vector<MIRCFIRegisterMappingDesc> CFIRegisters;
+ std::vector<StackID> SupportedStackIDs{
+ StackID::defaultStack(),
+ StackID::noAllocStack(),
+ };
+ std::optional<TargetFunctionStateTypeID> 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<TargetMIRTextInfo> create(TargetMIRTextInfoDesc Description,
+ const TargetRegisterInfo &Registers);
+
+ [[nodiscard]] std::span<const MIRRegisterMaskDesc> registerMasks() const noexcept {
+ return Description.RegisterMasks;
+ }
+
+ [[nodiscard]] std::span<const MIRTargetIndexDesc> targetIndices() const noexcept {
+ return Description.TargetIndices;
+ }
+
+ [[nodiscard]] std::span<const MIROperandFlagDesc> directOperandFlags() const noexcept {
+ return Description.DirectOperandFlags;
+ }
+
+ [[nodiscard]] std::span<const MIROperandFlagDesc> bitmaskOperandFlags() const noexcept {
+ return Description.BitmaskOperandFlags;
+ }
+
+ [[nodiscard]] std::span<const MIRMachineMemOperandFlagDesc>
+ machineMemOperandFlags() const noexcept {
+ return Description.MachineMemOperandFlags;
+ }
+
+ [[nodiscard]] std::span<const MIRVirtualRegisterFlagDesc> virtualRegisterFlags() const noexcept {
+ return Description.VirtualRegisterFlags;
+ }
+
+ [[nodiscard]] std::span<const MIRIntrinsicDesc> intrinsics() const noexcept {
+ return Description.Intrinsics;
+ }
+
+ [[nodiscard]] std::shared_ptr<const RegisterMask>
+ registerMask(std::string_view Name) const noexcept;
+ [[nodiscard]] std::optional<std::string_view>
+ registerMaskName(const RegisterMask &Mask) const noexcept;
+
+ [[nodiscard]] std::optional<TargetIndex> targetIndex(std::string_view Name) const noexcept;
+ [[nodiscard]] std::optional<std::string_view> targetIndexName(TargetIndex Index) const noexcept;
+
+ [[nodiscard]] std::optional<std::uint32_t>
+ directOperandFlag(std::string_view Name) const noexcept;
+ [[nodiscard]] std::optional<std::uint32_t>
+ bitmaskOperandFlag(std::string_view Name) const noexcept;
+ [[nodiscard]] Expected<std::vector<std::string_view>> operandFlagNames(std::uint32_t Flags) const;
+ [[nodiscard]] Expected<void> validateOperandFlags(std::uint32_t Flags) const;
+
+ [[nodiscard]] std::optional<std::uint16_t>
+ machineMemOperandFlag(std::string_view Name) const noexcept;
+ [[nodiscard]] Expected<std::vector<std::string_view>>
+ machineMemOperandFlagNames(std::uint16_t Flags) const;
+ [[nodiscard]] Expected<void> validateMachineMemOperandFlags(std::uint16_t Flags) const;
+
+ [[nodiscard]] std::optional<std::uint8_t>
+ virtualRegisterFlag(std::string_view Name) const noexcept;
+ [[nodiscard]] Expected<std::vector<std::string_view>>
+ virtualRegisterFlagNames(std::uint8_t Flags) const;
+ [[nodiscard]] Expected<void> validateVirtualRegisterFlags(std::uint8_t Flags) const;
+
+ [[nodiscard]] std::optional<IntrinsicID> intrinsic(std::string_view Name) const noexcept;
+ [[nodiscard]] std::optional<std::string_view> intrinsicName(IntrinsicID ID) const noexcept;
+
+ [[nodiscard]] std::optional<std::uint32_t>
+ dwarfRegister(PhysicalRegister Register) const noexcept;
+ [[nodiscard]] std::optional<PhysicalRegister>
+ physicalRegister(std::uint32_t DwarfRegister) const noexcept;
+
+ [[nodiscard]] std::span<const StackID> 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<TargetFunctionStateTypeID> functionStateType() const noexcept {
+ return Description.FunctionStateType;
+ }
+
+private:
+ explicit TargetMIRTextInfo(TargetMIRTextInfoDesc Description)
+ : Description(std::move(Description)) {}
+
+ TargetMIRTextInfoDesc Description;
+ std::unordered_map<std::string, std::size_t> RegisterMaskNameToIndex;
+ std::unordered_map<std::string, std::size_t> TargetIndexNameToIndex;
+ std::unordered_map<TargetIndex, std::size_t> TargetIndexToIndex;
+ std::unordered_map<std::string, std::size_t> DirectOperandFlagNameToIndex;
+ std::unordered_map<std::uint32_t, std::size_t> DirectOperandFlagToIndex;
+ std::unordered_map<std::string, std::size_t> BitmaskOperandFlagNameToIndex;
+ std::unordered_map<std::string, std::size_t> MachineMemOperandFlagNameToIndex;
+ std::unordered_map<std::string, std::size_t> VirtualRegisterFlagNameToIndex;
+ std::unordered_map<std::string, std::size_t> IntrinsicNameToIndex;
+ std::unordered_map<IntrinsicID, std::size_t> IntrinsicToIndex;
+ std::unordered_map<PhysicalRegister, std::uint32_t> RegisterToDwarf;
+ std::unordered_map<std::uint32_t, PhysicalRegister> DwarfToRegister;
+ std::unordered_set<std::uint32_t> 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<std::string_view>
+ physicalRegisterMIRName(PhysicalRegister Reg) const noexcept;
+ [[nodiscard]] std::optional<std::string_view>
+ registerClassMIRName(RegisterClassID ID) const noexcept;
+ [[nodiscard]] std::optional<std::string_view>
+ registerBankMIRName(RegisterBankID ID) const noexcept;
[[nodiscard]] bool isKnownPhysicalRegister(PhysicalRegister Reg) const noexcept {
return physicalRegister(Reg) != nullptr;
@@ -177,14 +187,20 @@ private:
std::unordered_map<PhysicalRegister, std::size_t> RegisterToIndex;
std::unordered_map<std::string, std::size_t> RegisterNameToIndex;
std::unordered_map<SubRegIndex, std::size_t> SubRegIndexToIndex;
+ std::unordered_map<std::string, std::size_t> SubRegNameToIndex;
std::unordered_map<RegisterClassID, std::size_t> ClassToIndex;
+ std::unordered_map<std::string, std::size_t> ClassNameToIndex;
std::unordered_map<RegisterBankID, std::size_t> BankToIndex;
+ std::unordered_map<std::string, std::size_t> BankNameToIndex;
std::unordered_map<std::uint64_t, PhysicalRegister> SubRegisterMap;
std::unordered_map<std::uint64_t, SubRegIndex> CompositionMap;
std::unordered_map<std::uint64_t, RegisterClassID> SubRegClassMap;
std::unordered_set<std::uint64_t> SubclassRelations;
std::vector<std::vector<PhysicalRegister>> Aliases;
std::vector<std::vector<PhysicalRegister>> SuperRegisters;
+ std::vector<std::string> RegisterMIRNames;
+ std::vector<std::string> ClassMIRNames;
+ std::vector<std::string> BankMIRNames;
};
} // namespace rcc