[llvm-branch-commits] [llvm] [WIP][SPIRV][Debug Info] Add support for emitting DebugFunction debug info instructions (PR #183122)
Scott Linder via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Mar 2 13:50:38 PST 2026
================
@@ -373,8 +439,160 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
return true;
}
+// Emits the SPIRV DebugFunction instruction for a given MachineFunction.
+bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
+ const Function &F = MF.getFunction();
+
+ DISubprogram *SP = F.getSubprogram();
+ // DISubProgram is not available, don't translate
+ if (!SP) {
+ return false;
+ }
+
+ // TODO: Support declarations
+ // Only process function definitions, skip declarations.
+ // Function declarations require an optional operand in the DebugFunction
+ // instruction that is not yet supported.
+ if (!SP->isDefinition()) {
+ return false;
+ }
+
+ // We insert at the first basic block available
+ if (MF.begin() == MF.end()) {
+ return false;
+ }
+
+ // Get the scope from DISubProgram
+ DIScope *Scope = SP->getScope();
+ if (!Scope) {
+ return false;
+ }
+
+ // TODO: Support additional DIScope types beyond DIFile.
+ // Only translate when scope is DIFile
+ const DIFile *FileScope = dyn_cast<DIFile>(Scope);
+ if (!FileScope) {
+ return false;
+ }
+
+ // Use SP->getUnit() as the scope for DebugSource.
+ // In SPIRV, the DebugSource scope cannot be a File, so we use the
+ // CompilationUnit instead. This matches what the translator does when
+ // handling DIFile scopes.
+ const DICompileUnit *CU = SP->getUnit();
+ if (!CU) {
+ return false;
+ }
+
+ // Check for function type - required for DebugTypeFunction
+ DISubroutineType *FuncType = SP->getType();
+ if (!FuncType) {
+ return false;
+ }
+
+ // TODO: Support functions with return types and parameters.
+ // Check that the function type array has exactly one element and it is null.
+ // This corresponds to void functions with no parameters.
+ DITypeArray TypeArray = FuncType->getTypeArray();
+ if (TypeArray.size() != 1 || TypeArray[0] != nullptr) {
+ return false;
+ }
+
+ const Module *M = getModule(MF);
+ LLVMContext *Context = &M->getContext();
+
+ // Emit DebugCompilationUnit and DebugFunction
+ {
+ const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
----------------
slinder1 wrote:
The fact that all of these are needed in both `emitFunctionDI` and `emitGlobalDI`, and that they share so many parameters, makes me wonder if a new type would make sense? It would save some pointer chasing, and the duplication of it twice for each function.
It seems like this is sort of a pattern in the codebase if you search for `MF = &MF`, e.g. in `llvm/lib/CodeGen/MachineVerifier.cpp`:
```cpp
bool MachineVerifier::verify(const MachineFunction &MF) {
this->MF = &MF;
TM = &MF.getTarget();
TII = MF.getSubtarget().getInstrInfo();
TRI = MF.getSubtarget().getRegisterInfo();
RBI = MF.getSubtarget().getRegBankInfo();
MRI = &MF.getRegInfo();
...
}
bool [MachineVerifierPass::]runOnMachineFunction(MachineFunction &MF) override {
...
MachineVerifier(this, Banner.c_str(), &errs()).verify(MF);
return false;
}
```
https://github.com/llvm/llvm-project/pull/183122
More information about the llvm-branch-commits
mailing list