From a8a9d7d926202450645deae872d4d9dc11d63215 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sun, 2 Aug 2026 03:37:46 +0800 Subject: [CodeGen] Model machine debug metadata Replace marker-based metadata operands with scoped references and inline DIExpression values. Add structured DILocation chains, instruction debug attachments, stack variable records, and entry values with unified verification, builder support, and deterministic cloning. --- backend/include/rcc/CodeGen/MachineDebugInfo.h | 154 +++++++++++++++++++++ backend/include/rcc/CodeGen/MachineFrameInfo.h | 2 + .../include/rcc/CodeGen/MachineFunctionRecords.h | 16 +++ backend/include/rcc/CodeGen/MachineIRBuilder.h | 6 +- backend/include/rcc/CodeGen/MachineInstr.h | 11 ++ backend/include/rcc/CodeGen/MachineMetadata.h | 3 + backend/include/rcc/CodeGen/MachineOperand.h | 5 +- 7 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 backend/include/rcc/CodeGen/MachineDebugInfo.h (limited to 'backend/include/rcc/CodeGen') diff --git a/backend/include/rcc/CodeGen/MachineDebugInfo.h b/backend/include/rcc/CodeGen/MachineDebugInfo.h new file mode 100644 index 0000000..0d95e96 --- /dev/null +++ b/backend/include/rcc/CodeGen/MachineDebugInfo.h @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_MACHINEDEBUGINFO_H +#define RCC_CODEGEN_MACHINEDEBUGINFO_H + +#include "rcc/CodeGen/MachineMetadata.h" +#include "rcc/Support/Error.h" + +#include +#include +#include +#include +#include +#include + +namespace rcc { + +class MachineDIExpression final { +public: + MachineDIExpression() = default; + explicit MachineDIExpression(std::vector Elements) + : Elements(std::move(Elements)) {} + + [[nodiscard]] std::span elements() const noexcept { + return Elements; + } + + friend bool operator==(const MachineDIExpression &Left, + const MachineDIExpression &Right) = default; + +private: + std::vector Elements; +}; + +class MachineMetadataValue final { +public: + MachineMetadataValue() = default; + + [[nodiscard]] static Expected reference(MachineMetadataReference Reference); + [[nodiscard]] static MachineMetadataValue expression(MachineDIExpression Expression); + + [[nodiscard]] bool isValid() const noexcept { + return !std::holds_alternative(Storage); + } + + [[nodiscard]] const MachineMetadataReference *reference() const noexcept { + return std::get_if(&Storage); + } + + [[nodiscard]] const MachineDIExpression *expression() const noexcept { + return std::get_if(&Storage); + } + + [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; + + friend bool operator==(const MachineMetadataValue &Left, + const MachineMetadataValue &Right) = default; + +private: + explicit MachineMetadataValue(MachineMetadataReference Reference) : Storage(Reference) {} + explicit MachineMetadataValue(MachineDIExpression Expression) : Storage(std::move(Expression)) {} + + std::variant Storage; +}; + +struct MachineDILocationFrame final { + std::uint32_t Line = 0; + std::uint16_t Column = 0; + MachineMetadataReference Scope; + bool IsImplicitCode = false; + std::uint64_t AtomGroup = 0; + std::uint8_t AtomRank = 0; + + friend constexpr bool operator==(MachineDILocationFrame Left, + MachineDILocationFrame Right) noexcept = default; +}; + +class MachineDILocation final { +public: + static constexpr std::uint64_t MaxAtomGroup = (std::uint64_t{1} << 61) - 1; + + [[nodiscard]] static Expected + create(std::vector InlineChain, + std::optional TerminalInlinedAt = std::nullopt); + + [[nodiscard]] std::span inlineChain() const noexcept { + return InlineChain; + } + + [[nodiscard]] std::optional terminalInlinedAt() const noexcept { + return TerminalInlinedAt; + } + + [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; + + friend bool operator==(const MachineDILocation &Left, const MachineDILocation &Right) = default; + +private: + MachineDILocation(std::vector InlineChain, + std::optional TerminalInlinedAt) + : InlineChain(std::move(InlineChain)), TerminalInlinedAt(TerminalInlinedAt) {} + + [[nodiscard]] Expected verifyStructure() const; + + std::vector InlineChain; + std::optional TerminalInlinedAt; +}; + +class MachineDebugLocation final { +public: + MachineDebugLocation() = default; + + [[nodiscard]] static Expected reference(MachineMetadataReference Reference); + [[nodiscard]] static MachineDebugLocation inlineLocation(MachineDILocation Location); + + [[nodiscard]] bool isValid() const noexcept { + return !std::holds_alternative(Storage); + } + + [[nodiscard]] const MachineMetadataReference *reference() const noexcept { + return std::get_if(&Storage); + } + + [[nodiscard]] const MachineDILocation *inlineLocation() const noexcept { + return std::get_if(&Storage); + } + + [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; + + friend bool operator==(const MachineDebugLocation &Left, + const MachineDebugLocation &Right) = default; + +private: + explicit MachineDebugLocation(MachineMetadataReference Reference) : Storage(Reference) {} + explicit MachineDebugLocation(MachineDILocation Location) : Storage(std::move(Location)) {} + + std::variant Storage; +}; + +struct MachineVariableDebugInfo final { + std::optional Variable; + std::optional Expression; + std::optional Location; + + [[nodiscard]] Expected verifyStructure() const; + [[nodiscard]] Expected verify(const MachineMetadataInfo &Metadata) const; + + friend bool operator==(const MachineVariableDebugInfo &Left, + const MachineVariableDebugInfo &Right) = default; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_MACHINEDEBUGINFO_H diff --git a/backend/include/rcc/CodeGen/MachineFrameInfo.h b/backend/include/rcc/CodeGen/MachineFrameInfo.h index ad1de53..b837ff3 100644 --- a/backend/include/rcc/CodeGen/MachineFrameInfo.h +++ b/backend/include/rcc/CodeGen/MachineFrameInfo.h @@ -3,6 +3,7 @@ #ifndef RCC_CODEGEN_MACHINEFRAMEINFO_H #define RCC_CODEGEN_MACHINEFRAMEINFO_H +#include "rcc/CodeGen/MachineDebugInfo.h" #include "rcc/CodeGen/MachineIRTypes.h" #include "rcc/CodeGen/MachineMemOperand.h" #include "rcc/CodeGen/StableID.h" @@ -95,6 +96,7 @@ struct StackObjectDesc final { bool IsAliased = false; bool AddressTaken = false; std::vector Lifetime; + std::optional DebugInfo; std::uint64_t TargetFlags = 0; friend bool operator==(const StackObjectDesc &Left, const StackObjectDesc &Right) = default; diff --git a/backend/include/rcc/CodeGen/MachineFunctionRecords.h b/backend/include/rcc/CodeGen/MachineFunctionRecords.h index 7929ed3..b792494 100644 --- a/backend/include/rcc/CodeGen/MachineFunctionRecords.h +++ b/backend/include/rcc/CodeGen/MachineFunctionRecords.h @@ -4,6 +4,7 @@ #define RCC_CODEGEN_MACHINEFUNCTIONRECORDS_H #include "rcc/CodeGen/MachineBasicBlockAttributes.h" +#include "rcc/CodeGen/MachineDebugInfo.h" #include "rcc/CodeGen/Register.h" #include "rcc/CodeGen/StableID.h" #include "rcc/Support/Error.h" @@ -37,6 +38,14 @@ struct MachineDebugValueSubstitution final { MachineDebugValueSubstitution Right) noexcept = default; }; +struct MachineEntryValueInfo final { + PhysicalRegister Reg; + MachineVariableDebugInfo DebugInfo; + + friend bool operator==(const MachineEntryValueInfo &Left, + const MachineEntryValueInfo &Right) = default; +}; + struct MachineCallSiteArgument final { PhysicalRegister Reg; std::uint16_t ArgumentNumber = 0; @@ -122,6 +131,12 @@ public: [[nodiscard]] Expected addDebugValueSubstitution(MachineDebugValueSubstitution Substitution); + [[nodiscard]] std::span entryValues() const noexcept { + return EntryValues; + } + + [[nodiscard]] Expected addEntryValue(MachineEntryValueInfo EntryValue); + [[nodiscard]] Expected verify() const; [[nodiscard]] Expected clone(const MachineFunctionCloneContext &CloneContext) const; @@ -135,6 +150,7 @@ private: std::vector CalledGlobals; std::vector PrefetchTargets; std::vector DebugValueSubstitutions; + std::vector EntryValues; }; } // namespace rcc diff --git a/backend/include/rcc/CodeGen/MachineIRBuilder.h b/backend/include/rcc/CodeGen/MachineIRBuilder.h index 08ec9ba..918f389 100644 --- a/backend/include/rcc/CodeGen/MachineIRBuilder.h +++ b/backend/include/rcc/CodeGen/MachineIRBuilder.h @@ -70,7 +70,8 @@ public: std::uint32_t TargetFlags = 0); [[nodiscard]] Expected addRegisterMask(std::shared_ptr Mask, std::uint32_t TargetFlags = 0); - [[nodiscard]] Expected addMetadata(std::string Marker, std::uint32_t TargetFlags = 0); + [[nodiscard]] Expected addMetadata(MachineMetadataValue Value, + std::uint32_t TargetFlags = 0); [[nodiscard]] Expected addTargetIndex(TargetIndex Index, std::int64_t Offset = 0, std::uint32_t TargetFlags = 0); [[nodiscard]] Expected addMCSymbol(std::string Name, std::int64_t Offset = 0, @@ -83,6 +84,8 @@ public: [[nodiscard]] Expected setSourceLocation(SourceLocation NewLocation); [[nodiscard]] Expected clearSourceLocation(); + [[nodiscard]] Expected setDebugLocation(MachineDebugLocation NewLocation); + [[nodiscard]] Expected clearDebugLocation(); [[nodiscard]] Expected setOrigin(OriginID NewOrigin); [[nodiscard]] Expected clearOrigin(); @@ -116,6 +119,7 @@ private: std::vector MemOperands; MachineInstrFlags Flags; std::optional Location; + std::optional DebugLocation; std::optional Origin; bool IsBuilt = false; diff --git a/backend/include/rcc/CodeGen/MachineInstr.h b/backend/include/rcc/CodeGen/MachineInstr.h index 78d48cb..69d7dd7 100644 --- a/backend/include/rcc/CodeGen/MachineInstr.h +++ b/backend/include/rcc/CodeGen/MachineInstr.h @@ -121,6 +121,16 @@ public: Location.reset(); } + [[nodiscard]] const std::optional &debugLocation() const noexcept { + return DebugLocation; + } + + [[nodiscard]] Expected setDebugLocation(MachineDebugLocation NewLocation); + + void clearDebugLocation() noexcept { + DebugLocation.reset(); + } + [[nodiscard]] std::optional origin() const noexcept { return Origin; } @@ -164,6 +174,7 @@ private: std::vector MemOperands; MachineInstrFlags Flags; std::optional Location; + std::optional DebugLocation; std::optional Origin; std::uint32_t DebugInstrNumber = 0; diff --git a/backend/include/rcc/CodeGen/MachineMetadata.h b/backend/include/rcc/CodeGen/MachineMetadata.h index 577d5da..95033f6 100644 --- a/backend/include/rcc/CodeGen/MachineMetadata.h +++ b/backend/include/rcc/CodeGen/MachineMetadata.h @@ -126,6 +126,9 @@ private: std::unordered_map SlotToIndex; }; +[[nodiscard]] Expected verifyMachineMetadataReference(MachineMetadataReference Reference, + const MachineMetadataInfo &Metadata); + } // namespace rcc #endif // RCC_CODEGEN_MACHINEMETADATA_H diff --git a/backend/include/rcc/CodeGen/MachineOperand.h b/backend/include/rcc/CodeGen/MachineOperand.h index 35cf45b..ce5eb60 100644 --- a/backend/include/rcc/CodeGen/MachineOperand.h +++ b/backend/include/rcc/CodeGen/MachineOperand.h @@ -4,6 +4,7 @@ #define RCC_CODEGEN_MACHINEOPERAND_H #include "rcc/CodeGen/LowLevelType.h" +#include "rcc/CodeGen/MachineDebugInfo.h" #include "rcc/CodeGen/MachineIRTypes.h" #include "rcc/CodeGen/Register.h" #include "rcc/CodeGen/RegisterMask.h" @@ -176,7 +177,7 @@ struct RegisterMaskOperand final { }; struct MetadataOperand final { - std::string Marker; + MachineMetadataValue Value; friend bool operator==(const MetadataOperand &Left, const MetadataOperand &Right) = default; }; @@ -247,7 +248,7 @@ public: std::uint32_t TargetFlags = 0); [[nodiscard]] static Expected registerMask(std::shared_ptr Mask, std::uint32_t TargetFlags = 0); - [[nodiscard]] static Expected metadata(std::string Marker, + [[nodiscard]] static Expected metadata(MachineMetadataValue Value, std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand targetIndex(TargetIndex Index, std::int64_t Offset = 0, std::uint32_t TargetFlags = 0); -- cgit v1.2.3