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/lib/CodeGen/MachineDebugInfo.cpp | 164 +++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 backend/lib/CodeGen/MachineDebugInfo.cpp (limited to 'backend/lib/CodeGen/MachineDebugInfo.cpp') diff --git a/backend/lib/CodeGen/MachineDebugInfo.cpp b/backend/lib/CodeGen/MachineDebugInfo.cpp new file mode 100644 index 0000000..35f68ca --- /dev/null +++ b/backend/lib/CodeGen/MachineDebugInfo.cpp @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/CodeGen/MachineDebugInfo.h" + +#include + +namespace rcc { + +Expected MachineMetadataValue::reference(MachineMetadataReference Reference) { + if (!Reference.isValid()) { + return makeUnexpected(ErrorCode::InvalidArgument, + "machine metadata value reference must be valid"); + } + return MachineMetadataValue(Reference); +} + +MachineMetadataValue MachineMetadataValue::expression(MachineDIExpression Expression) { + return MachineMetadataValue(std::move(Expression)); +} + +Expected MachineMetadataValue::verify(const MachineMetadataInfo &Metadata) const { + if (!isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "machine metadata value has no representation"); + } + const MachineMetadataReference *Reference = reference(); + if (Reference == nullptr) + return {}; + return verifyMachineMetadataReference(*Reference, Metadata); +} + +Expected +MachineDILocation::create(std::vector InlineChain, + std::optional TerminalInlinedAt) { + MachineDILocation Result(std::move(InlineChain), TerminalInlinedAt); + auto Verification = Result.verifyStructure(); + if (!Verification) + return std::unexpected(Verification.error()); + return Result; +} + +Expected MachineDILocation::verifyStructure() const { + if (InlineChain.empty()) { + return makeUnexpected(ErrorCode::VerificationError, + "inline debug location requires at least one frame"); + } + for (const MachineDILocationFrame &Frame : InlineChain) { + if (!Frame.Scope.isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "inline debug location frame has an invalid scope"); + } + if (Frame.Scope.scope() != MachineMetadataScope::EmbeddedIR) { + return makeUnexpected(ErrorCode::VerificationError, + "inline debug location scope must reference embedded IR metadata"); + } + if (Frame.AtomGroup > MaxAtomGroup) { + return makeUnexpected(ErrorCode::VerificationError, + "inline debug location atom group exceeds 61 bits"); + } + if (Frame.AtomRank > 7) { + return makeUnexpected(ErrorCode::VerificationError, + "inline debug location atom rank exceeds three bits"); + } + } + if (TerminalInlinedAt && !TerminalInlinedAt->isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "inline debug location has an invalid terminal inlined-at reference"); + } + if (TerminalInlinedAt && TerminalInlinedAt->scope() != MachineMetadataScope::EmbeddedIR) { + return makeUnexpected(ErrorCode::VerificationError, + "inline debug location inlined-at must reference embedded IR metadata"); + } + return {}; +} + +Expected MachineDILocation::verify(const MachineMetadataInfo &Metadata) const { + auto Structure = verifyStructure(); + if (!Structure) + return Structure; + for (const MachineDILocationFrame &Frame : InlineChain) { + auto Scope = verifyMachineMetadataReference(Frame.Scope, Metadata); + if (!Scope) + return Scope; + } + if (TerminalInlinedAt) + return verifyMachineMetadataReference(*TerminalInlinedAt, Metadata); + return {}; +} + +Expected MachineDebugLocation::reference(MachineMetadataReference Reference) { + if (!Reference.isValid()) { + return makeUnexpected(ErrorCode::InvalidArgument, + "machine debug location reference must be valid"); + } + if (Reference.scope() != MachineMetadataScope::EmbeddedIR) { + return makeUnexpected(ErrorCode::InvalidArgument, + "machine debug location must reference embedded IR metadata"); + } + return MachineDebugLocation(Reference); +} + +MachineDebugLocation MachineDebugLocation::inlineLocation(MachineDILocation Location) { + return MachineDebugLocation(std::move(Location)); +} + +Expected MachineDebugLocation::verify(const MachineMetadataInfo &Metadata) const { + if (!isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "machine debug location has no representation"); + } + if (const MachineMetadataReference *Reference = reference()) + return verifyMachineMetadataReference(*Reference, Metadata); + return inlineLocation()->verify(Metadata); +} + +Expected MachineVariableDebugInfo::verifyStructure() const { + if (!Variable && !Expression && !Location) { + return makeUnexpected(ErrorCode::VerificationError, + "variable debug information has no metadata"); + } + if (Variable && !Variable->isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "variable debug information has an invalid variable reference"); + } + if (Variable && Variable->scope() != MachineMetadataScope::EmbeddedIR) { + return makeUnexpected(ErrorCode::VerificationError, + "variable debug information must reference embedded IR metadata"); + } + if (Expression && !Expression->isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "variable debug information has an invalid expression"); + } + if (Expression && Expression->reference() != nullptr && + Expression->reference()->scope() != MachineMetadataScope::EmbeddedIR) { + return makeUnexpected(ErrorCode::VerificationError, + "variable debug expression must reference embedded IR metadata"); + } + if (Location && !Location->isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "variable debug information has an invalid location"); + } + return {}; +} + +Expected MachineVariableDebugInfo::verify(const MachineMetadataInfo &Metadata) const { + auto Structure = verifyStructure(); + if (!Structure) + return Structure; + if (Variable) { + auto VariableResult = verifyMachineMetadataReference(*Variable, Metadata); + if (!VariableResult) + return VariableResult; + } + if (Expression) { + auto ExpressionResult = Expression->verify(Metadata); + if (!ExpressionResult) + return ExpressionResult; + } + if (Location) + return Location->verify(Metadata); + return {}; +} + +} // namespace rcc -- cgit v1.2.3