diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-01 18:17:33 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-01 18:17:33 +0800 |
| commit | e0c77d80585428818c32886eb8c26755ea8ed159 (patch) | |
| tree | f1d79404cb767c91b9aed3ad1a7709a628b3860f /backend/lib/CodeGen/MachineFunctionRecords.cpp | |
| parent | 6e09614afd2a589690d107b41308f6fe6614c266 (diff) | |
| download | rcc-project-e0c77d80585428818c32886eb8c26755ea8ed159.tar.gz rcc-project-e0c77d80585428818c32886eb8c26755ea8ed159.tar.xz | |
[CodeGen] Track debug instruction identities
Add monotonic MIR debug instruction numbers and structured value substitutions. Verify live number uniqueness, meta-instruction exclusion, substitution graph integrity, and target subregister references while preserving debug identities during cloning.
Diffstat (limited to 'backend/lib/CodeGen/MachineFunctionRecords.cpp')
| -rw-r--r-- | backend/lib/CodeGen/MachineFunctionRecords.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/backend/lib/CodeGen/MachineFunctionRecords.cpp b/backend/lib/CodeGen/MachineFunctionRecords.cpp index be0d936..9fda0d7 100644 --- a/backend/lib/CodeGen/MachineFunctionRecords.cpp +++ b/backend/lib/CodeGen/MachineFunctionRecords.cpp @@ -7,6 +7,7 @@ #include <algorithm> #include <cstddef> #include <string> +#include <unordered_map> #include <unordered_set> #include <utility> @@ -55,6 +56,30 @@ verifyCalleeSavedRegisters(std::span<const PhysicalRegister> Registers) { return {}; } +[[nodiscard]] constexpr std::uint64_t +debugReferenceKey(MachineDebugValueReference Reference) noexcept { + return (static_cast<std::uint64_t>(Reference.InstructionNumber) << 32U) | + static_cast<std::uint64_t>(Reference.OperandNumber); +} + +[[nodiscard]] Expected<void> +verifyDebugValueSubstitution(const MachineDebugValueSubstitution &Substitution) { + if (Substitution.Source.InstructionNumber == 0 || + Substitution.Destination.InstructionNumber == 0) { + return makeUnexpected(ErrorCode::VerificationError, + "debug value substitution has a zero instruction number"); + } + if (Substitution.Source.InstructionNumber == Substitution.Destination.InstructionNumber) { + return makeUnexpected(ErrorCode::VerificationError, + "debug value substitution cannot replace a value within one instruction"); + } + if (Substitution.Source.OperandNumber == MachineDebugMemoryOperandNumber) { + return makeUnexpected(ErrorCode::VerificationError, + "debug value substitution cannot originate from the memory operand"); + } + return {}; +} + } // namespace Expected<void> @@ -102,6 +127,22 @@ Expected<void> MachineFunctionRecords::addPrefetchTarget(MachinePrefetchTarget T return {}; } +Expected<void> +MachineFunctionRecords::addDebugValueSubstitution(MachineDebugValueSubstitution Substitution) { + auto Verification = verifyDebugValueSubstitution(Substitution); + if (!Verification) + return std::unexpected(Verification.error()); + if (std::ranges::any_of(DebugValueSubstitutions, + [&Substitution](const MachineDebugValueSubstitution &Existing) { + return Existing.Source == Substitution.Source; + })) { + return makeUnexpected(ErrorCode::InvalidArgument, + "debug value source already has a substitution"); + } + DebugValueSubstitutions.push_back(Substitution); + return {}; +} + Expected<void> MachineFunctionRecords::verify() const { if (CalleeSavedRegisters) { auto CalleeSavedVerification = verifyCalleeSavedRegisters(*CalleeSavedRegisters); @@ -138,6 +179,37 @@ Expected<void> MachineFunctionRecords::verify() const { "prefetch target list contains a duplicate entry"); } } + + std::unordered_map<std::uint64_t, std::uint64_t> DebugSubstitutionEdges; + for (const MachineDebugValueSubstitution &Substitution : DebugValueSubstitutions) { + auto SubstitutionVerification = verifyDebugValueSubstitution(Substitution); + if (!SubstitutionVerification) + return SubstitutionVerification; + const std::uint64_t Source = debugReferenceKey(Substitution.Source); + const std::uint64_t Destination = debugReferenceKey(Substitution.Destination); + if (!DebugSubstitutionEdges.emplace(Source, Destination).second) { + return makeUnexpected(ErrorCode::VerificationError, + "multiple debug substitutions have the same source"); + } + } + + std::unordered_set<std::uint64_t> CompletedDebugReferences; + for (const auto &Edge : DebugSubstitutionEdges) { + const std::uint64_t Start = Edge.first; + std::unordered_set<std::uint64_t> Path; + std::uint64_t Current = Start; + while (!CompletedDebugReferences.contains(Current)) { + const auto Position = DebugSubstitutionEdges.find(Current); + if (Position == DebugSubstitutionEdges.end()) + break; + if (!Path.insert(Current).second) { + return makeUnexpected(ErrorCode::VerificationError, + "debug value substitutions contain a cycle"); + } + Current = Position->second; + } + CompletedDebugReferences.insert(Path.begin(), Path.end()); + } return {}; } @@ -181,6 +253,11 @@ MachineFunctionRecords::clone(const MachineFunctionCloneContext &CloneContext) c if (!AddResult) return std::unexpected(AddResult.error()); } + for (const MachineDebugValueSubstitution Source : DebugValueSubstitutions) { + auto AddResult = Result.addDebugValueSubstitution(Source); + if (!AddResult) + return std::unexpected(AddResult.error()); + } return Result; } |
