aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/MachineVerifier.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 18:17:33 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 18:17:33 +0800
commite0c77d80585428818c32886eb8c26755ea8ed159 (patch)
treef1d79404cb767c91b9aed3ad1a7709a628b3860f /backend/lib/CodeGen/MachineVerifier.cpp
parent6e09614afd2a589690d107b41308f6fe6614c266 (diff)
downloadrcc-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/MachineVerifier.cpp')
-rw-r--r--backend/lib/CodeGen/MachineVerifier.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/backend/lib/CodeGen/MachineVerifier.cpp b/backend/lib/CodeGen/MachineVerifier.cpp
index d1c6989..2fbbd38 100644
--- a/backend/lib/CodeGen/MachineVerifier.cpp
+++ b/backend/lib/CodeGen/MachineVerifier.cpp
@@ -396,6 +396,17 @@ private:
if (!LinkedBlockProfileIDs.contains(Key))
return fail("prefetch target references an unknown bb_id");
}
+
+ if (!Records.debugValueSubstitutions().empty() &&
+ !Function.attributes().has(MachineFunctionAttribute::DebugInstrRef)) {
+ return fail("debug value substitutions require DebugInstrRef");
+ }
+ for (const MachineDebugValueSubstitution &Substitution : Records.debugValueSubstitutions()) {
+ if (Substitution.Subregister.value() != 0 &&
+ Target.registers().subRegIndex(Substitution.Subregister) == nullptr) {
+ return fail("debug value substitution references an unknown subregister index");
+ }
+ }
return {};
}
@@ -421,6 +432,14 @@ private:
const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction.opcode());
if (Descriptor == nullptr)
return fail("live instruction uses an unregistered opcode");
+ if (Instruction.debugInstrNumber() != 0) {
+ if (Descriptor->Flags.has(InstructionFlag::Meta)) {
+ return fail("metadata instruction has a debug value tracking number");
+ }
+ if (!DebugInstructionNumbers.insert(Instruction.debugInstrNumber()).second) {
+ return fail("multiple instructions have the same debug value tracking number");
+ }
+ }
auto DescriptorResult = Target.validateInstruction(Instruction, Function.registerInfo());
if (!DescriptorResult)
return failWith("instruction descriptor", DescriptorResult.error());
@@ -664,6 +683,7 @@ private:
std::unordered_set<MachineInstrStableID> LinkedInstructionIDs;
std::unordered_map<MachineInstrStableID, const MachineInstr *> LinkedInstructionsByID;
std::unordered_set<std::uint64_t> LinkedBlockProfileIDs;
+ std::unordered_set<std::uint32_t> DebugInstructionNumbers;
std::unordered_set<const MachineMemOperand *> RegisteredMemOperands;
std::unordered_map<Register, std::size_t> VirtualDefCounts;
bool HasPhi = false;