aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/MachineDebugInfo.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-02 03:37:46 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-02 03:37:46 +0800
commita8a9d7d926202450645deae872d4d9dc11d63215 (patch)
tree16a3640a93e3f567ff31045969c02a42e1f467e0 /backend/lib/CodeGen/MachineDebugInfo.cpp
parent49d70380a6a95e4039f6b5e5ccce09671d5b4796 (diff)
downloadrcc-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/lib/CodeGen/MachineDebugInfo.cpp')
-rw-r--r--backend/lib/CodeGen/MachineDebugInfo.cpp164
1 files changed, 164 insertions, 0 deletions
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 <utility>
+
+namespace rcc {
+
+Expected<MachineMetadataValue> 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<void> 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>
+MachineDILocation::create(std::vector<MachineDILocationFrame> InlineChain,
+ std::optional<MachineMetadataReference> TerminalInlinedAt) {
+ MachineDILocation Result(std::move(InlineChain), TerminalInlinedAt);
+ auto Verification = Result.verifyStructure();
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ return Result;
+}
+
+Expected<void> 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<void> 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> 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<void> 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<void> 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<void> 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