[llvm] [SPIRV] Emit NonSemantic DebugValue (PR #224158)
Diego Novillo via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 06:46:55 PDT 2026
================
@@ -1533,12 +1904,104 @@ SPIRVNonSemanticDebugHandler::resolveDebugLocTarget(const MachineInstr *MI) {
// above skips it.
MI = findAdjacentEmittedInstruction(MI, MAI, true);
assert(MI && "Merge instruction must be followed by a terminator");
+ // The assert is compiled out in a release build, and returning MI there
+ // would give an engaged optional holding null.
+ if (!MI)
+ return std::nullopt;
}
return MI;
}
-void SPIRVNonSemanticDebugHandler::emitDebugScopeForInstruction(
+void SPIRVNonSemanticDebugHandler::resolveDebugRecord(
+ const MachineInstr &MI, const MachineInstr *LastEmitted) {
+ SPIRV::ModuleAnalysisInfo &MAI = *CurrentMAI;
+ const MachineFunction &MF = *MI.getMF();
+
+ // A record sits at its own position, except in a merge region: nothing may
+ // be emitted between a merge and its terminator, so it belongs ahead of the
+ // merge.
+ const MachineInstr *Anchor =
+ LastEmitted && isMergeInstruction(LastEmitted->getOpcode()) ? LastEmitted
+ : &MI;
+
+ // A #dbg_declare reaches Machine IR as an indirect DBG_VALUE. Its storage is
+ // an OpVariable in the entry block, so it is in the output by the time any
+ // record naming it is reached.
+ if (std::optional<Register> LocReg = getDebugDeclareStorageReg(MI)) {
+ MCRegister StorageReg = MAI.getRegisterAlias(&MF, *LocReg);
+ if (StorageReg.isValid())
+ placeRecord(SPIRV::NonSemanticExtInst::DebugDeclare, MI, StorageReg,
+ Anchor);
+ return;
+ }
+
+ // A constant assignment names the id emitted for it at module scope, which
+ // every function body follows.
+ if (std::optional<MCRegister> ConstReg = getConstantValueReg(MI)) {
+ placeRecord(SPIRV::NonSemanticExtInst::DebugValue, MI, *ConstReg, Anchor);
+ return;
+ }
+
+ std::optional<Register> ValReg = getDebugValueReg(MI);
+ if (!ValReg)
+ return;
+ MCRegister ValueReg = MAI.getRegisterAlias(&MF, *ValReg);
+ if (!ValueReg.isValid())
+ return;
+
+ // NonSemantic.Shader.DebugInfo states that "Forward references are not
+ // allowed, to be compliant with SPV_KHR_non_semantic_info", so the id has to
+ // be in the output already. A module section precedes every function body.
+ //
+ // For anything else, SPIR-V requires a definition in a function block to
+ // dominate a non-phi use, and requires a block to precede every block it
+ // dominates, so a dominating definition is also one already printed. A
+ // record naming a definition that does not dominate it is dropped.
+ const MachineInstr *Def = MF.getRegInfo().getUniqueVRegDef(*ValReg);
+ if (ModuleScopeIds.contains(ValueReg) ||
+ (isEmitted(Def, MAI) && DomTree->dominates(Def, &MI)))
+ placeRecord(SPIRV::NonSemanticExtInst::DebugValue, MI, ValueReg, Anchor);
+}
+
+void SPIRVNonSemanticDebugHandler::analyzeDebugRecords(
+ const MachineFunction &MF) {
+ assert(CurrentMAI && "CurrentMAI must be set");
+
+ for (const MachineBasicBlock &MBB : MF) {
+ const MachineInstr *LastEmitted = nullptr;
+ for (const MachineInstr &MI : MBB) {
+ if (MI.isDebugValueLike()) {
+ if (!DomTree) {
----------------
dnovillo wrote:
Yup. Done.
https://github.com/llvm/llvm-project/pull/224158
More information about the llvm-commits
mailing list