aboutsummaryrefslogtreecommitdiff
path: root/backend/unittests/CodeGen/MachineFunctionRecordsTest.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/unittests/CodeGen/MachineFunctionRecordsTest.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/unittests/CodeGen/MachineFunctionRecordsTest.cpp')
-rw-r--r--backend/unittests/CodeGen/MachineFunctionRecordsTest.cpp79
1 files changed, 61 insertions, 18 deletions
diff --git a/backend/unittests/CodeGen/MachineFunctionRecordsTest.cpp b/backend/unittests/CodeGen/MachineFunctionRecordsTest.cpp
index 4f41b39..8ca6bf3 100644
--- a/backend/unittests/CodeGen/MachineFunctionRecordsTest.cpp
+++ b/backend/unittests/CodeGen/MachineFunctionRecordsTest.cpp
@@ -5,6 +5,7 @@
#include "Target/TestTarget.h"
#include "rcc/CodeGen/InstructionDescriptor.h"
#include "rcc/CodeGen/MachineBasicBlock.h"
+#include "rcc/CodeGen/MachineDebugInfo.h"
#include "rcc/CodeGen/MachineFunction.h"
#include "rcc/CodeGen/MachineFunctionCloner.h"
#include "rcc/CodeGen/MachineInstr.h"
@@ -14,6 +15,7 @@
#include <cstdint>
#include <iostream>
#include <memory>
+#include <optional>
#include <string>
#include <string_view>
#include <utility>
@@ -120,6 +122,8 @@ void testValueValidation(TestContext &Context) {
.Flags = 0,
}),
"a called-global record must require a nonempty callee");
+ Context.expect(!Records.addEntryValue({}),
+ "an entry-value record must require a physical register and debug metadata");
const rcc::MachinePrefetchTarget Target{
.Block = {.BaseID = 7, .CloneID = 3},
@@ -135,6 +139,9 @@ void testVerifierAndClone(TestContext &Context) {
auto Function = createFunction(Context, 1, "records");
if (!Target || Function == nullptr)
return;
+ Context.expect(
+ Function->metadata().addNode({.Slot = 0, .IsDistinct = false, .Elements = {}}).has_value(),
+ "function record metadata setup must succeed");
rcc::MachineBasicBlock *Block = appendBlock(Context, *Function);
if (Block == nullptr)
@@ -175,6 +182,22 @@ void testVerifierAndClone(TestContext &Context) {
})
.has_value(),
"structured prefetch target information must be stored");
+ auto EntryLocation =
+ rcc::MachineDebugLocation::reference(rcc::MachineMetadataReference::embeddedIR(12));
+ Context.expect(EntryLocation.has_value(), "entry-value debug location must be representable");
+ if (!EntryLocation)
+ return;
+ const rcc::MachineEntryValueInfo EntryValue{
+ .Reg = G0,
+ .DebugInfo =
+ {
+ .Variable = rcc::MachineMetadataReference::embeddedIR(10),
+ .Expression = rcc::MachineMetadataValue::expression(rcc::MachineDIExpression{}),
+ .Location = *EntryLocation,
+ },
+ };
+ Context.expect(Function->records().addEntryValue(EntryValue).has_value(),
+ "structured entry-value debug information must be stored");
Context.expect(rcc::MachineVerifier::verify(*Function, *Target).has_value(),
"well-formed function records must pass unified verification");
@@ -190,24 +213,25 @@ void testVerifierAndClone(TestContext &Context) {
const auto InstructionID = Clone->InstructionStableIDs.find(Call->stableID());
const rcc::MachineFunctionRecords &ClonedRecords = Clone->ClonedFunction->records();
- Context.expect(InstructionID != Clone->InstructionStableIDs.end() &&
- ClonedRecords.hasCalleeSavedRegisters() &&
- ClonedRecords.calleeSavedRegisters().size() == 2 &&
- ClonedRecords.callSites().size() == 1 &&
- ClonedRecords.callSites()[0].CallInstruction == InstructionID->second &&
- ClonedRecords.callSites()[0].ForwardedArguments.size() == 2 &&
- ClonedRecords.callSites()[0].ForwardedArguments[1].ArgumentNumber == 0 &&
- ClonedRecords.callSites()[0].CalleeTypeIDs ==
- std::vector<std::uint64_t>({0x11, 0x22}) &&
- ClonedRecords.calledGlobals().size() == 1 &&
- ClonedRecords.calledGlobals()[0].CallInstruction == InstructionID->second &&
- ClonedRecords.calledGlobals()[0].Callee == "callee" &&
- ClonedRecords.calledGlobals()[0].Flags == 5 &&
- ClonedRecords.prefetchTargets().size() == 1 &&
- ClonedRecords.prefetchTargets()[0].Block ==
- rcc::MachineBasicBlockProfileID{.BaseID = 19, .CloneID = 2} &&
- ClonedRecords.prefetchTargets()[0].CallsiteIndex == 8,
- "deep clone must preserve records and remap instruction StableIDs");
+ Context.expect(
+ InstructionID != Clone->InstructionStableIDs.end() &&
+ ClonedRecords.hasCalleeSavedRegisters() &&
+ ClonedRecords.calleeSavedRegisters().size() == 2 &&
+ ClonedRecords.callSites().size() == 1 &&
+ ClonedRecords.callSites()[0].CallInstruction == InstructionID->second &&
+ ClonedRecords.callSites()[0].ForwardedArguments.size() == 2 &&
+ ClonedRecords.callSites()[0].ForwardedArguments[1].ArgumentNumber == 0 &&
+ ClonedRecords.callSites()[0].CalleeTypeIDs == std::vector<std::uint64_t>({0x11, 0x22}) &&
+ ClonedRecords.calledGlobals().size() == 1 &&
+ ClonedRecords.calledGlobals()[0].CallInstruction == InstructionID->second &&
+ ClonedRecords.calledGlobals()[0].Callee == "callee" &&
+ ClonedRecords.calledGlobals()[0].Flags == 5 &&
+ ClonedRecords.prefetchTargets().size() == 1 &&
+ ClonedRecords.prefetchTargets()[0].Block ==
+ rcc::MachineBasicBlockProfileID{.BaseID = 19, .CloneID = 2} &&
+ ClonedRecords.prefetchTargets()[0].CallsiteIndex == 8 &&
+ ClonedRecords.entryValues().size() == 1 && ClonedRecords.entryValues()[0] == EntryValue,
+ "deep clone must preserve records and remap instruction StableIDs");
}
void testCrossReferenceFailures(TestContext &Context) {
@@ -306,6 +330,25 @@ void testCrossReferenceFailures(TestContext &Context) {
Context.expect(!rcc::MachineVerifier::verify(*Function, *Target),
"linked block bb_id values must be unique");
}
+
+ {
+ auto Function = createFunction(Context, 13, "entry-value-register");
+ if (Function == nullptr)
+ return;
+ Context.expect(Function->records()
+ .addEntryValue({
+ .Reg = phys(999),
+ .DebugInfo =
+ {
+ .Variable = rcc::MachineMetadataReference::embeddedIR(1),
+ .Expression = std::nullopt,
+ .Location = std::nullopt,
+ },
+ })
+ .has_value() &&
+ !rcc::MachineVerifier::verify(*Function, *Target),
+ "entry-value records must reject target-unknown physical registers");
+ }
}
} // namespace