diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-02 03:37:46 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-02 03:37:46 +0800 |
| commit | a8a9d7d926202450645deae872d4d9dc11d63215 (patch) | |
| tree | 16a3640a93e3f567ff31045969c02a42e1f467e0 /backend/include/rcc/CodeGen | |
| parent | 49d70380a6a95e4039f6b5e5ccce09671d5b4796 (diff) | |
| download | rcc-project-a8a9d7d926202450645deae872d4d9dc11d63215.tar.gz rcc-project-a8a9d7d926202450645deae872d4d9dc11d63215.tar.xz | |
[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.
Diffstat (limited to 'backend/include/rcc/CodeGen')
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineDebugInfo.h | 154 | ||||
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineFrameInfo.h | 2 | ||||
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineFunctionRecords.h | 16 | ||||
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineIRBuilder.h | 6 | ||||
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineInstr.h | 11 | ||||
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineMetadata.h | 3 | ||||
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineOperand.h | 5 |
7 files changed, 194 insertions, 3 deletions
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 <cstdint> +#include <optional> +#include <span> +#include <utility> +#include <variant> +#include <vector> + +namespace rcc { + +class MachineDIExpression final { +public: + MachineDIExpression() = default; + explicit MachineDIExpression(std::vector<std::uint64_t> Elements) + : Elements(std::move(Elements)) {} + + [[nodiscard]] std::span<const std::uint64_t> elements() const noexcept { + return Elements; + } + + friend bool operator==(const MachineDIExpression &Left, + const MachineDIExpression &Right) = default; + +private: + std::vector<std::uint64_t> Elements; +}; + +class MachineMetadataValue final { +public: + MachineMetadataValue() = default; + + [[nodiscard]] static Expected<MachineMetadataValue> reference(MachineMetadataReference Reference); + [[nodiscard]] static MachineMetadataValue expression(MachineDIExpression Expression); + + [[nodiscard]] bool isValid() const noexcept { + return !std::holds_alternative<std::monostate>(Storage); + } + + [[nodiscard]] const MachineMetadataReference *reference() const noexcept { + return std::get_if<MachineMetadataReference>(&Storage); + } + + [[nodiscard]] const MachineDIExpression *expression() const noexcept { + return std::get_if<MachineDIExpression>(&Storage); + } + + [[nodiscard]] Expected<void> 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<std::monostate, MachineMetadataReference, MachineDIExpression> 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<MachineDILocation> + create(std::vector<MachineDILocationFrame> InlineChain, + std::optional<MachineMetadataReference> TerminalInlinedAt = std::nullopt); + + [[nodiscard]] std::span<const MachineDILocationFrame> inlineChain() const noexcept { + return InlineChain; + } + + [[nodiscard]] std::optional<MachineMetadataReference> terminalInlinedAt() const noexcept { + return TerminalInlinedAt; + } + + [[nodiscard]] Expected<void> verify(const MachineMetadataInfo &Metadata) const; + + friend bool operator==(const MachineDILocation &Left, const MachineDILocation &Right) = default; + +private: + MachineDILocation(std::vector<MachineDILocationFrame> InlineChain, + std::optional<MachineMetadataReference> TerminalInlinedAt) + : InlineChain(std::move(InlineChain)), TerminalInlinedAt(TerminalInlinedAt) {} + + [[nodiscard]] Expected<void> verifyStructure() const; + + std::vector<MachineDILocationFrame> InlineChain; + std::optional<MachineMetadataReference> TerminalInlinedAt; +}; + +class MachineDebugLocation final { +public: + MachineDebugLocation() = default; + + [[nodiscard]] static Expected<MachineDebugLocation> reference(MachineMetadataReference Reference); + [[nodiscard]] static MachineDebugLocation inlineLocation(MachineDILocation Location); + + [[nodiscard]] bool isValid() const noexcept { + return !std::holds_alternative<std::monostate>(Storage); + } + + [[nodiscard]] const MachineMetadataReference *reference() const noexcept { + return std::get_if<MachineMetadataReference>(&Storage); + } + + [[nodiscard]] const MachineDILocation *inlineLocation() const noexcept { + return std::get_if<MachineDILocation>(&Storage); + } + + [[nodiscard]] Expected<void> 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<std::monostate, MachineMetadataReference, MachineDILocation> Storage; +}; + +struct MachineVariableDebugInfo final { + std::optional<MachineMetadataReference> Variable; + std::optional<MachineMetadataValue> Expression; + std::optional<MachineDebugLocation> Location; + + [[nodiscard]] Expected<void> verifyStructure() const; + [[nodiscard]] Expected<void> 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<StackObjectLifetimeRange> Lifetime; + std::optional<MachineVariableDebugInfo> 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<void> addDebugValueSubstitution(MachineDebugValueSubstitution Substitution); + [[nodiscard]] std::span<const MachineEntryValueInfo> entryValues() const noexcept { + return EntryValues; + } + + [[nodiscard]] Expected<void> addEntryValue(MachineEntryValueInfo EntryValue); + [[nodiscard]] Expected<void> verify() const; [[nodiscard]] Expected<MachineFunctionRecords> clone(const MachineFunctionCloneContext &CloneContext) const; @@ -135,6 +150,7 @@ private: std::vector<MachineCalledGlobal> CalledGlobals; std::vector<MachinePrefetchTarget> PrefetchTargets; std::vector<MachineDebugValueSubstitution> DebugValueSubstitutions; + std::vector<MachineEntryValueInfo> 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<void> addRegisterMask(std::shared_ptr<const RegisterMask> Mask, std::uint32_t TargetFlags = 0); - [[nodiscard]] Expected<void> addMetadata(std::string Marker, std::uint32_t TargetFlags = 0); + [[nodiscard]] Expected<void> addMetadata(MachineMetadataValue Value, + std::uint32_t TargetFlags = 0); [[nodiscard]] Expected<void> addTargetIndex(TargetIndex Index, std::int64_t Offset = 0, std::uint32_t TargetFlags = 0); [[nodiscard]] Expected<void> addMCSymbol(std::string Name, std::int64_t Offset = 0, @@ -83,6 +84,8 @@ public: [[nodiscard]] Expected<void> setSourceLocation(SourceLocation NewLocation); [[nodiscard]] Expected<void> clearSourceLocation(); + [[nodiscard]] Expected<void> setDebugLocation(MachineDebugLocation NewLocation); + [[nodiscard]] Expected<void> clearDebugLocation(); [[nodiscard]] Expected<void> setOrigin(OriginID NewOrigin); [[nodiscard]] Expected<void> clearOrigin(); @@ -116,6 +119,7 @@ private: std::vector<const MachineMemOperand *> MemOperands; MachineInstrFlags Flags; std::optional<SourceLocation> Location; + std::optional<MachineDebugLocation> DebugLocation; std::optional<OriginID> 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<MachineDebugLocation> &debugLocation() const noexcept { + return DebugLocation; + } + + [[nodiscard]] Expected<void> setDebugLocation(MachineDebugLocation NewLocation); + + void clearDebugLocation() noexcept { + DebugLocation.reset(); + } + [[nodiscard]] std::optional<OriginID> origin() const noexcept { return Origin; } @@ -164,6 +174,7 @@ private: std::vector<const MachineMemOperand *> MemOperands; MachineInstrFlags Flags; std::optional<SourceLocation> Location; + std::optional<MachineDebugLocation> DebugLocation; std::optional<OriginID> 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<std::uint32_t, std::size_t> SlotToIndex; }; +[[nodiscard]] Expected<void> 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<MachineOperand> registerMask(std::shared_ptr<const RegisterMask> Mask, std::uint32_t TargetFlags = 0); - [[nodiscard]] static Expected<MachineOperand> metadata(std::string Marker, + [[nodiscard]] static Expected<MachineOperand> metadata(MachineMetadataValue Value, std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand targetIndex(TargetIndex Index, std::int64_t Offset = 0, std::uint32_t TargetFlags = 0); |
