[llvm] [SPIRV] Emitting DebugSource, DebugCompileUnit (PR #97558)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 11 06:32:46 PDT 2024
https://github.com/bwlodarcz updated https://github.com/llvm/llvm-project/pull/97558
>From 1769e5559a8bc87508988a131c8212aaf2489c04 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Fri, 28 Jun 2024 13:17:42 +0200
Subject: [PATCH 01/10] [SPIRV] Added new stub pass for NonSemantic DI
The commit adds new empty pass for emission of
NonSemantic.Shader.DebugInfo.100 instructions.
The pass is a basis for future development and
can be (and likely will be) a subject of change.
In addition to that there is additional unused function
which main purpose is to be basis of accessing global
metadata which is inaccessible in MIR. Accessing such
metadata is necessary for emitting such instructions
like DebugCompilationUnit or DebugSource.
---
llvm/lib/Target/SPIRV/CMakeLists.txt | 1 +
llvm/lib/Target/SPIRV/SPIRV.h | 2 +
.../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 55 +++++++++++++++++++
llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp | 1 +
4 files changed, 59 insertions(+)
create mode 100644 llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
diff --git a/llvm/lib/Target/SPIRV/CMakeLists.txt b/llvm/lib/Target/SPIRV/CMakeLists.txt
index 14647e92f5d08..5f8aea5fc8d84 100644
--- a/llvm/lib/Target/SPIRV/CMakeLists.txt
+++ b/llvm/lib/Target/SPIRV/CMakeLists.txt
@@ -40,6 +40,7 @@ add_llvm_target(SPIRVCodeGen
SPIRVSubtarget.cpp
SPIRVTargetMachine.cpp
SPIRVUtils.cpp
+ SPIRVEmitNonSemanticDI.cpp
LINK_COMPONENTS
Analysis
diff --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h
index e597a1dc8dc06..c32bf6f5a863d 100644
--- a/llvm/lib/Target/SPIRV/SPIRV.h
+++ b/llvm/lib/Target/SPIRV/SPIRV.h
@@ -26,6 +26,7 @@ FunctionPass *createSPIRVRegularizerPass();
FunctionPass *createSPIRVPreLegalizerPass();
FunctionPass *createSPIRVPostLegalizerPass();
ModulePass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM);
+MachineFunctionPass *createSPIRVEmitNonSemanticDIPass();
InstructionSelector *
createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
const SPIRVSubtarget &Subtarget,
@@ -36,6 +37,7 @@ void initializeSPIRVConvergenceRegionAnalysisWrapperPassPass(PassRegistry &);
void initializeSPIRVPreLegalizerPass(PassRegistry &);
void initializeSPIRVPostLegalizerPass(PassRegistry &);
void initializeSPIRVEmitIntrinsicsPass(PassRegistry &);
+void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &);
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRV_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
new file mode 100644
index 0000000000000..5b938047025d1
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -0,0 +1,55 @@
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
+ static char ID;
+ SPIRVEmitNonSemanticDI();
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+};
+
+void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &);
+
+FunctionPass *createSPIRVEmitNonSemanticDIPass() {
+ return new SPIRVEmitNonSemanticDI();
+}
+} // namespace llvm
+
+using namespace llvm;
+
+INITIALIZE_PASS(SPIRVEmitNonSemanticDI, "spirv-nonsemantic-debug-info",
+ "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
+
+char SPIRVEmitNonSemanticDI::ID = 0;
+
+SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
+ initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
+}
+
+[[maybe_unused]]
+static void findCompileUnitDI(const MachineFunction &MF) {
+ MachineModuleInfo &MMI = MF.getMMI();
+ const Module *M = MMI.getModule();
+ NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+ std::string FilePath;
+ if (DbgCu) {
+ unsigned NumOp = DbgCu->getNumOperands();
+ if (NumOp) {
+ if (const auto *CompileUnit =
+ dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
+ DIFile *File = CompileUnit->getFile();
+ FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
+ }
+ }
+ }
+}
+
+bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
+ return false;
+}
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 52fc6f33b4ef1..ee71190bc02ff 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -199,6 +199,7 @@ void SPIRVPassConfig::addPreLegalizeMachineIR() {
bool SPIRVPassConfig::addLegalizeMachineIR() {
addPass(new Legalizer());
addPass(createSPIRVPostLegalizerPass());
+ addPass(createSPIRVEmitNonSemanticDIPass());
return false;
}
>From 3dcb731a2563b22cac9e55fbd296beb3fdc3834b Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Wed, 3 Jul 2024 12:59:41 +0200
Subject: [PATCH 02/10] [SPIRV] Emitting DebugSource, DebugCompileUnit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit introduces emission of DebugSource, DebugCompileUnit from NonSemantic.Shader.DebugInfo.100 and required OpString with filename.
NonSemantic.Shader.DebugInfo.100 is divided, following DWARF into two main concepts – emitting DIE and Line . In DWARF .debug_abbriev and .debug_line sections
are responsible for emitting tree with information (DEIs) about e.g. types, compilation unit.
Corresponding to that in NonSemantic.Shader.DebugInfo.100 have instructions like DebugSource, DebugCompileUnit etc. which preforms same role in SPIR-V file. The difference is in fact that in SPIR-V there are no sections but logical layout
which forces order of the instruction emission.
The NonSemantic.Shader.DebugInfo.100 requires for this type of global information to be emitted after OpTypeXXX
and OpConstantXXX instructions.
One of the goals was to minimize changes and interaction with SPIRVModuleAnalysis as possible which current commit achieves by emitting it’s instructions
directly into MachineFunction. The possibility of duplicates are mitigated by guard inside pass which emits the global information only once in one function.
By that method duplicates don’t have chance to be emitted.
>From that point, adding new debug global instructions should be straightforward.
---
llvm/lib/Target/SPIRV/SPIRV.h | 2 +-
llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 8 +-
.../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 119 ++++++++++++++++--
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 18 ++-
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h | 3 +-
llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp | 2 +-
6 files changed, 132 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h
index c32bf6f5a863d..6c35a467f53be 100644
--- a/llvm/lib/Target/SPIRV/SPIRV.h
+++ b/llvm/lib/Target/SPIRV/SPIRV.h
@@ -26,7 +26,7 @@ FunctionPass *createSPIRVRegularizerPass();
FunctionPass *createSPIRVPreLegalizerPass();
FunctionPass *createSPIRVPostLegalizerPass();
ModulePass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM);
-MachineFunctionPass *createSPIRVEmitNonSemanticDIPass();
+MachineFunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM);
InstructionSelector *
createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
const SPIRVSubtarget &Subtarget,
diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index 3206c264f99d3..f9f36cc25eec5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -273,6 +273,8 @@ void SPIRVAsmPrinter::outputDebugSourceAndStrings(const Module &M) {
addStringImm(Str.first(), Inst);
outputMCInst(Inst);
}
+ // Output OpString.
+ outputModuleSection(SPIRV::MB_DebugStrings);
// Output OpSource.
MCInst Inst;
Inst.setOpcode(SPIRV::OpSource);
@@ -588,9 +590,11 @@ void SPIRVAsmPrinter::outputModuleSections() {
// the first section to allow use of: OpLine and OpNoLine debug information;
// non-semantic instructions with OpExtInst.
outputModuleSection(SPIRV::MB_TypeConstVars);
- // 10. All function declarations (functions without a body).
+ // 10. All global NonSemantic.Shader.DebugInfo.100 instructions.
+ outputModuleSection(SPIRV::MB_NonSemanticGlobalDI);
+ // 11. All function declarations (functions without a body).
outputExtFuncDecls();
- // 11. All function definitions (functions with a body).
+ // 12. All function definitions (functions with a body).
// This is done in regular function output.
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 5b938047025d1..f630685d98ac8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -1,6 +1,14 @@
+#include "MCTargetDesc/SPIRVBaseInfo.h"
+#include "SPIRVGlobalRegistry.h"
+#include "SPIRVRegisterInfo.h"
+#include "SPIRVTargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Metadata.h"
#include "llvm/PassRegistry.h"
@@ -9,15 +17,21 @@
namespace llvm {
struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
static char ID;
+ SPIRVTargetMachine *TM;
+ SPIRVEmitNonSemanticDI(SPIRVTargetMachine *TM);
SPIRVEmitNonSemanticDI();
bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+ bool IsGlobalDIEmitted = false;
+ bool emitGlobalDI(MachineFunction &MF);
};
void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &);
-FunctionPass *createSPIRVEmitNonSemanticDIPass() {
- return new SPIRVEmitNonSemanticDI();
+FunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM) {
+ return new SPIRVEmitNonSemanticDI(TM);
}
} // namespace llvm
@@ -28,28 +42,107 @@ INITIALIZE_PASS(SPIRVEmitNonSemanticDI, "spirv-nonsemantic-debug-info",
char SPIRVEmitNonSemanticDI::ID = 0;
+SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI(SPIRVTargetMachine *TM)
+ : MachineFunctionPass(ID), TM(TM) {
+ initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
+}
+
SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
}
-[[maybe_unused]]
-static void findCompileUnitDI(const MachineFunction &MF) {
+bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
MachineModuleInfo &MMI = MF.getMMI();
const Module *M = MMI.getModule();
NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+ if (!DbgCu) {
+ return false;
+ }
std::string FilePath;
- if (DbgCu) {
- unsigned NumOp = DbgCu->getNumOperands();
- if (NumOp) {
- if (const auto *CompileUnit =
- dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
- DIFile *File = CompileUnit->getFile();
- FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
- }
+ unsigned SourceLanguage;
+ unsigned NumOp = DbgCu->getNumOperands();
+ if (NumOp) {
+ if (const auto *CompileUnit =
+ dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
+ DIFile *File = CompileUnit->getFile();
+ FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
+ SourceLanguage = CompileUnit->getSourceLanguage();
+ }
+ }
+ NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
+ int64_t DwarfVersion = 0;
+ int64_t DebugInfoVersion = 0;
+ for (auto *Op : ModuleFlags->operands()) {
+ const MDOperand &StrOp = Op->getOperand(1);
+ if (StrOp.equalsStr("Dwarf Version")) {
+ DwarfVersion =
+ cast<ConstantInt>(
+ cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+ ->getSExtValue();
+ } else if (StrOp.equalsStr("Debug Info Version")) {
+ DebugInfoVersion =
+ cast<ConstantInt>(
+ cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+ ->getSExtValue();
}
}
+ const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
+ const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
+ const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
+ SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ for (MachineBasicBlock &MBB : MF) {
+ MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+ MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+ Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
+ MIB.add(StrRegOp);
+ addStringImm(FilePath, MIB);
+
+ const MachineInstr *VoidTyMI =
+ GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
+
+ MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
+ Register DebugSourceResIdReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MIB.addDef(DebugSourceResIdReg); // Result ID
+ MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
+ MIB.addImm(static_cast<int64_t>(
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
+ MIB.addImm(SPIRV::NonSemanticExtInst::DebugSource); //
+ MIB.addUse(StrReg);
+ MIB.constrainAllUses(*TII, *TRI, *RBI);
+
+ Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
+ Register DebugInfoVersionReg =
+ GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
+ Register SourceLanguageReg =
+ GR->buildConstantInt(SourceLanguage, MIRBuilder);
+
+ MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
+ Register DebugCompUnitResIdReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MIB.addDef(DebugCompUnitResIdReg); // Result ID
+ MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
+ MIB.addImm(static_cast<int64_t>(
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
+ MIB.addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit);
+ MIB.addUse(DebugInfoVersionReg);
+ MIB.addUse(DwarfVersionReg);
+ MIB.addUse(DebugSourceResIdReg);
+ MIB.addUse(SourceLanguageReg);
+ MIB.constrainAllUses(*TII, *TRI, *RBI);
+ }
+
+ return true;
}
bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
- return false;
+ bool Res = false;
+ if (!IsGlobalDIEmitted) {
+ Res = emitGlobalDI(MF);
+ IsGlobalDIEmitted = true;
+ }
+ return Res;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index ac0aa682ea4be..32ca6c4155dfe 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -21,7 +21,6 @@
#include "SPIRVSubtarget.h"
#include "SPIRVTargetMachine.h"
#include "SPIRVUtils.h"
-#include "TargetInfo/SPIRVTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
@@ -427,7 +426,22 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
if (MAI.getSkipEmission(&MI))
continue;
const unsigned OpCode = MI.getOpcode();
- if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
+ if (OpCode == SPIRV::OpString) {
+ collectOtherInstr(MI, MAI, SPIRV::MB_DebugStrings, IS);
+ } else if (OpCode == SPIRV::OpExtInst) {
+ MachineOperand Ins = MI.getOperand(3);
+ namespace NS = SPIRV::NonSemanticExtInst;
+ static constexpr int64_t GlobalNonSemanticDITy[] = {
+ NS::DebugSource, NS::DebugCompilationUnit};
+ bool IsGlobalDI = false;
+ for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy);
+ ++Idx) {
+ IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];
+ }
+ if (IsGlobalDI) {
+ collectOtherInstr(MI, MAI, SPIRV::MB_NonSemanticGlobalDI, IS);
+ }
+ } else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
} else if (OpCode == SPIRV::OpEntryPoint) {
collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
index 79226d6d93efb..024728c347e8a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
@@ -20,7 +20,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
namespace llvm {
class SPIRVSubtarget;
@@ -34,9 +33,11 @@ enum ModuleSectionType {
MB_EntryPoints, // All OpEntryPoint instructions (if any).
// MB_ExecutionModes, MB_DebugSourceAndStrings,
MB_DebugNames, // All OpName and OpMemberName intrs.
+ MB_DebugStrings, // All OpString intrs.
MB_DebugModuleProcessed, // All OpModuleProcessed instructions.
MB_Annotations, // OpDecorate, OpMemberDecorate etc.
MB_TypeConstVars, // OpTypeXXX, OpConstantXXX, and global OpVariables.
+ MB_NonSemanticGlobalDI, // OpExtInst with e.g. DebugSource, DebugTypeBasic.
MB_ExtFuncDecls, // OpFunction etc. to declare for external funcs.
NUM_MODULE_SECTIONS // Total number of sections requiring basic blocks.
};
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index ee71190bc02ff..bffc079981bc1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -199,7 +199,7 @@ void SPIRVPassConfig::addPreLegalizeMachineIR() {
bool SPIRVPassConfig::addLegalizeMachineIR() {
addPass(new Legalizer());
addPass(createSPIRVPostLegalizerPass());
- addPass(createSPIRVEmitNonSemanticDIPass());
+ addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
return false;
}
>From 190811d9f6a3acd5cbc92849142cd1df40e0a84a Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Thu, 4 Jul 2024 17:49:29 +0200
Subject: [PATCH 03/10] Fixes after CR
---
.../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 122 ++++++++++--------
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 7 +-
2 files changed, 67 insertions(+), 62 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index f630685d98ac8..bc39ce11222be 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -3,6 +3,7 @@
#include "SPIRVRegisterInfo.h"
#include "SPIRVTargetMachine.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -13,6 +14,9 @@
#include "llvm/IR/Metadata.h"
#include "llvm/PassRegistry.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Path.h"
+
+#define DEBUG_TYPE "spirv-nonsemantic-debug-info"
namespace llvm {
struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
@@ -37,7 +41,7 @@ FunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM) {
using namespace llvm;
-INITIALIZE_PASS(SPIRVEmitNonSemanticDI, "spirv-nonsemantic-debug-info",
+INITIALIZE_PASS(SPIRVEmitNonSemanticDI, DEBUG_TYPE,
"SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
char SPIRVEmitNonSemanticDI::ID = 0;
@@ -52,88 +56,92 @@ SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
}
bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
+ if (MF.begin() == MF.end()) {
+ IsGlobalDIEmitted = false;
+ return false;
+ }
MachineModuleInfo &MMI = MF.getMMI();
const Module *M = MMI.getModule();
NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
- if (!DbgCu) {
+ if (!DbgCu)
return false;
- }
std::string FilePath;
- unsigned SourceLanguage;
- unsigned NumOp = DbgCu->getNumOperands();
- if (NumOp) {
- if (const auto *CompileUnit =
- dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
+ unsigned SourceLanguage = 0;
+ for (auto *Op : DbgCu->operands()) {
+ if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
DIFile *File = CompileUnit->getFile();
- FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
+ FilePath = ((File->getDirectory() + sys::path::get_separator() +
+ File->getFilename()))
+ .str();
SourceLanguage = CompileUnit->getSourceLanguage();
+ break;
}
}
NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
int64_t DwarfVersion = 0;
int64_t DebugInfoVersion = 0;
for (auto *Op : ModuleFlags->operands()) {
- const MDOperand &StrOp = Op->getOperand(1);
- if (StrOp.equalsStr("Dwarf Version")) {
+ const MDOperand &MaybeStrOp = Op->getOperand(1);
+ if (MaybeStrOp.equalsStr("Dwarf Version"))
DwarfVersion =
cast<ConstantInt>(
cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
->getSExtValue();
- } else if (StrOp.equalsStr("Debug Info Version")) {
+ else if (MaybeStrOp.equalsStr("Debug Info Version"))
DebugInfoVersion =
cast<ConstantInt>(
cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
->getSExtValue();
- }
}
const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
MachineRegisterInfo &MRI = MF.getRegInfo();
- for (MachineBasicBlock &MBB : MF) {
- MachineIRBuilder MIRBuilder(MBB, MBB.begin());
-
- MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
- Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
- MIB.add(StrRegOp);
- addStringImm(FilePath, MIB);
-
- const MachineInstr *VoidTyMI =
- GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
-
- MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
- Register DebugSourceResIdReg =
- MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MIB.addDef(DebugSourceResIdReg); // Result ID
- MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
- MIB.addImm(static_cast<int64_t>(
- SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
- MIB.addImm(SPIRV::NonSemanticExtInst::DebugSource); //
- MIB.addUse(StrReg);
- MIB.constrainAllUses(*TII, *TRI, *RBI);
-
- Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
- Register DebugInfoVersionReg =
- GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
- Register SourceLanguageReg =
- GR->buildConstantInt(SourceLanguage, MIRBuilder);
-
- MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
- Register DebugCompUnitResIdReg =
- MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MIB.addDef(DebugCompUnitResIdReg); // Result ID
- MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
- MIB.addImm(static_cast<int64_t>(
- SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
- MIB.addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit);
- MIB.addUse(DebugInfoVersionReg);
- MIB.addUse(DwarfVersionReg);
- MIB.addUse(DebugSourceResIdReg);
- MIB.addUse(SourceLanguageReg);
- MIB.constrainAllUses(*TII, *TRI, *RBI);
- }
+ MachineBasicBlock &MBB = *MF.begin();
+ MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+ MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+ Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(StrReg, LLT::scalar(32));
+
+ MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
+ MIB.add(StrRegOp);
+ addStringImm(FilePath, MIB);
+
+ SPIRVType *VoidTyMI =
+ GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
+
+ Register DebugSourceResIdReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
+ MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+ .addDef(DebugSourceResIdReg)
+ .addUse(GR->getSPIRVTypeID(VoidTyMI))
+ .addImm(static_cast<int64_t>(
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+ .addImm(SPIRV::NonSemanticExtInst::DebugSource)
+ .addUse(StrReg);
+ MIB.constrainAllUses(*TII, *TRI, *RBI);
+
+ Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
+ Register DebugInfoVersionReg =
+ GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
+ Register SourceLanguageReg = GR->buildConstantInt(SourceLanguage, MIRBuilder);
+
+ Register DebugCompUnitResIdReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
+ MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+ .addDef(DebugCompUnitResIdReg)
+ .addUse(GR->getSPIRVTypeID(VoidTyMI))
+ .addImm(static_cast<int64_t>(
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+ .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
+ .addUse(DebugInfoVersionReg)
+ .addUse(DwarfVersionReg)
+ .addUse(DebugSourceResIdReg)
+ .addUse(SourceLanguageReg);
+ MIB.constrainAllUses(*TII, *TRI, *RBI);
return true;
}
@@ -141,8 +149,8 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
bool Res = false;
if (!IsGlobalDIEmitted) {
- Res = emitGlobalDI(MF);
IsGlobalDIEmitted = true;
+ Res = emitGlobalDI(MF);
}
return Res;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 32ca6c4155dfe..45518d79edf9e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -434,13 +434,10 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
static constexpr int64_t GlobalNonSemanticDITy[] = {
NS::DebugSource, NS::DebugCompilationUnit};
bool IsGlobalDI = false;
- for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy);
- ++Idx) {
+ for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];
- }
- if (IsGlobalDI) {
+ if (IsGlobalDI)
collectOtherInstr(MI, MAI, SPIRV::MB_NonSemanticGlobalDI, IS);
- }
} else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
} else if (OpCode == SPIRV::OpEntryPoint) {
>From d32bfbabb97e4baefc70cc175f70b5844e6bcfd8 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Thu, 4 Jul 2024 18:15:21 +0200
Subject: [PATCH 04/10] Add assignSPIRVTypeToVReg
---
llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index bc39ce11222be..8f3aeede9169c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -111,6 +111,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
SPIRVType *VoidTyMI =
GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
+ GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
Register DebugSourceResIdReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
>From 4c45e542ea576ca082b92c97374e11c92f888a37 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Fri, 5 Jul 2024 12:47:15 +0200
Subject: [PATCH 05/10] Pass moved to the end
---
.../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 57 +++++++++++++------
llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp | 7 ++-
2 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 8f3aeede9169c..fe3b0baf4df68 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -1,4 +1,5 @@
#include "MCTargetDesc/SPIRVBaseInfo.h"
+#include "MCTargetDesc/SPIRVMCTargetDesc.h"
#include "SPIRVGlobalRegistry.h"
#include "SPIRVRegisterInfo.h"
#include "SPIRVTargetMachine.h"
@@ -60,14 +61,14 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
IsGlobalDIEmitted = false;
return false;
}
- MachineModuleInfo &MMI = MF.getMMI();
+ const MachineModuleInfo &MMI = MF.getMMI();
const Module *M = MMI.getModule();
- NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+ const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
if (!DbgCu)
return false;
std::string FilePath;
unsigned SourceLanguage = 0;
- for (auto *Op : DbgCu->operands()) {
+ for (const auto *Op : DbgCu->operands()) {
if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
DIFile *File = CompileUnit->getFile();
FilePath = ((File->getDirectory() + sys::path::get_separator() +
@@ -77,10 +78,10 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
break;
}
}
- NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
+ const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
int64_t DwarfVersion = 0;
int64_t DebugInfoVersion = 0;
- for (auto *Op : ModuleFlags->operands()) {
+ for (const auto *Op : ModuleFlags->operands()) {
const MDOperand &MaybeStrOp = Op->getOperand(1);
if (MaybeStrOp.equalsStr("Dwarf Version"))
DwarfVersion =
@@ -101,19 +102,18 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
MachineBasicBlock &MBB = *MF.begin();
MachineIRBuilder MIRBuilder(MBB, MBB.begin());
- MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
- Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(StrReg, LLT::scalar(32));
-
- MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
- MIB.add(StrRegOp);
+ MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+ MIB.addDef(StrReg);
addStringImm(FilePath, MIB);
- SPIRVType *VoidTyMI =
+ const SPIRVType *VoidTyMI =
GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
- Register DebugSourceResIdReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ const Register DebugSourceResIdReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
.addDef(DebugSourceResIdReg)
@@ -124,12 +124,35 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
.addUse(StrReg);
MIB.constrainAllUses(*TII, *TRI, *RBI);
- Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
- Register DebugInfoVersionReg =
- GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
- Register SourceLanguageReg = GR->buildConstantInt(SourceLanguage, MIRBuilder);
+ const SPIRVType *I32Ty =
+ GR->getOrCreateSPIRVType(Type::getInt32Ty(M->getContext()), MIRBuilder);
+ GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
+
+ const Register DwarfVersionReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DwarfVersionReg, LLT::scalar(32));
+ MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(DwarfVersionReg)
+ .addUse(GR->getSPIRVTypeID(I32Ty))
+ .addImm(DwarfVersion);
+
+ const Register DebugInfoVersionReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DebugInfoVersionReg, LLT::scalar(32));
+ MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(DebugInfoVersionReg)
+ .addUse(GR->getSPIRVTypeID(I32Ty))
+ .addImm(DebugInfoVersion);
+
+ const Register SourceLanguageReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(SourceLanguageReg, LLT::scalar(32));
+ MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(SourceLanguageReg)
+ .addUse(GR->getSPIRVTypeID(I32Ty))
+ .addImm(SourceLanguage);
- Register DebugCompUnitResIdReg =
+ const Register DebugCompUnitResIdReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index bffc079981bc1..2470bce56faf7 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -115,6 +115,7 @@ class SPIRVPassConfig : public TargetPassConfig {
void addOptimizedRegAlloc() override {}
void addPostRegAlloc() override;
+ void addMachinePasses() override;
private:
const SPIRVTargetMachine &TM;
@@ -199,7 +200,6 @@ void SPIRVPassConfig::addPreLegalizeMachineIR() {
bool SPIRVPassConfig::addLegalizeMachineIR() {
addPass(new Legalizer());
addPass(createSPIRVPostLegalizerPass());
- addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
return false;
}
@@ -209,6 +209,11 @@ bool SPIRVPassConfig::addRegBankSelect() {
return false;
}
+void SPIRVPassConfig::addMachinePasses() {
+ TargetPassConfig::addMachinePasses();
+ addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
+}
+
namespace {
// A custom subclass of InstructionSelect, which is mostly the same except from
// not requiring RegBankSelect to occur previously.
>From c543cd30197cf41bd2db4cea3bc2e164317a632c Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Fri, 5 Jul 2024 14:30:55 +0200
Subject: [PATCH 06/10] Adding braces and comments
---
.../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 223 ++++++++++--------
1 file changed, 122 insertions(+), 101 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index fe3b0baf4df68..857d07f79d254 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -57,121 +57,142 @@ SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
}
bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
+ // If this MachineFunction doesn't have any BB repeat procedure
+ // for the next
if (MF.begin() == MF.end()) {
IsGlobalDIEmitted = false;
return false;
}
- const MachineModuleInfo &MMI = MF.getMMI();
- const Module *M = MMI.getModule();
- const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
- if (!DbgCu)
- return false;
+
+ // Required variables to get from metadata search
+ LLVMContext *Context;
std::string FilePath;
unsigned SourceLanguage = 0;
- for (const auto *Op : DbgCu->operands()) {
- if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
- DIFile *File = CompileUnit->getFile();
- FilePath = ((File->getDirectory() + sys::path::get_separator() +
- File->getFilename()))
- .str();
- SourceLanguage = CompileUnit->getSourceLanguage();
- break;
- }
- }
- const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
int64_t DwarfVersion = 0;
int64_t DebugInfoVersion = 0;
- for (const auto *Op : ModuleFlags->operands()) {
- const MDOperand &MaybeStrOp = Op->getOperand(1);
- if (MaybeStrOp.equalsStr("Dwarf Version"))
- DwarfVersion =
- cast<ConstantInt>(
- cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
- ->getSExtValue();
- else if (MaybeStrOp.equalsStr("Debug Info Version"))
- DebugInfoVersion =
- cast<ConstantInt>(
- cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
- ->getSExtValue();
- }
- const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
- const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
- const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
- SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
- MachineRegisterInfo &MRI = MF.getRegInfo();
- MachineBasicBlock &MBB = *MF.begin();
- MachineIRBuilder MIRBuilder(MBB, MBB.begin());
-
- const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MRI.setType(StrReg, LLT::scalar(32));
- MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
- MIB.addDef(StrReg);
- addStringImm(FilePath, MIB);
-
- const SPIRVType *VoidTyMI =
- GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
- GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
-
- const Register DebugSourceResIdReg =
- MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
- MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
- .addDef(DebugSourceResIdReg)
- .addUse(GR->getSPIRVTypeID(VoidTyMI))
- .addImm(static_cast<int64_t>(
- SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
- .addImm(SPIRV::NonSemanticExtInst::DebugSource)
- .addUse(StrReg);
- MIB.constrainAllUses(*TII, *TRI, *RBI);
-
- const SPIRVType *I32Ty =
- GR->getOrCreateSPIRVType(Type::getInt32Ty(M->getContext()), MIRBuilder);
- GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
-
- const Register DwarfVersionReg =
- MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MRI.setType(DwarfVersionReg, LLT::scalar(32));
- MIRBuilder.buildInstr(SPIRV::OpConstantI)
- .addDef(DwarfVersionReg)
- .addUse(GR->getSPIRVTypeID(I32Ty))
- .addImm(DwarfVersion);
-
- const Register DebugInfoVersionReg =
- MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MRI.setType(DebugInfoVersionReg, LLT::scalar(32));
- MIRBuilder.buildInstr(SPIRV::OpConstantI)
- .addDef(DebugInfoVersionReg)
- .addUse(GR->getSPIRVTypeID(I32Ty))
- .addImm(DebugInfoVersion);
-
- const Register SourceLanguageReg =
- MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MRI.setType(SourceLanguageReg, LLT::scalar(32));
- MIRBuilder.buildInstr(SPIRV::OpConstantI)
- .addDef(SourceLanguageReg)
- .addUse(GR->getSPIRVTypeID(I32Ty))
- .addImm(SourceLanguage);
-
- const Register DebugCompUnitResIdReg =
- MRI.createVirtualRegister(&SPIRV::IDRegClass);
- MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
- MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
- .addDef(DebugCompUnitResIdReg)
- .addUse(GR->getSPIRVTypeID(VoidTyMI))
- .addImm(static_cast<int64_t>(
- SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
- .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
- .addUse(DebugInfoVersionReg)
- .addUse(DwarfVersionReg)
- .addUse(DebugSourceResIdReg)
- .addUse(SourceLanguageReg);
- MIB.constrainAllUses(*TII, *TRI, *RBI);
+ // Searching through the Module metadata to find nescessary
+ // information like DwarfVersion or SourceLanguage
+ {
+ const MachineModuleInfo &MMI = MF.getMMI();
+ const Module *M = MMI.getModule();
+ Context = &M->getContext();
+ const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+ if (!DbgCu)
+ return false;
+ for (const auto *Op : DbgCu->operands()) {
+ if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
+ DIFile *File = CompileUnit->getFile();
+ FilePath = ((File->getDirectory() + sys::path::get_separator() +
+ File->getFilename()))
+ .str();
+ SourceLanguage = CompileUnit->getSourceLanguage();
+ break;
+ }
+ }
+ const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
+ for (const auto *Op : ModuleFlags->operands()) {
+ const MDOperand &MaybeStrOp = Op->getOperand(1);
+ if (MaybeStrOp.equalsStr("Dwarf Version"))
+ DwarfVersion =
+ cast<ConstantInt>(
+ cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+ ->getSExtValue();
+ else if (MaybeStrOp.equalsStr("Debug Info Version"))
+ DebugInfoVersion =
+ cast<ConstantInt>(
+ cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+ ->getSExtValue();
+ }
+ }
+ // NonSemantic.Shader.DebugInfo.100 global DI intruction emitting
+ {
+ // Required LLVM variables for emitting logic
+ const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
+ const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
+ const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
+ SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ MachineBasicBlock &MBB = *MF.begin();
+ MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+ // Emit OpString with FilePath which is required by DebugSource
+ const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(StrReg, LLT::scalar(32));
+ MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+ MIB.addDef(StrReg);
+ addStringImm(FilePath, MIB);
+
+ const SPIRVType *VoidTyMI =
+ GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder);
+ GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
+
+ // Emit DebugSource which is required by DebugCompilationUnit
+ const Register DebugSourceResIdReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
+ MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+ .addDef(DebugSourceResIdReg)
+ .addUse(GR->getSPIRVTypeID(VoidTyMI))
+ .addImm(static_cast<int64_t>(
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+ .addImm(SPIRV::NonSemanticExtInst::DebugSource)
+ .addUse(StrReg);
+ MIB.constrainAllUses(*TII, *TRI, *RBI);
+
+ const SPIRVType *I32Ty =
+ GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder);
+ GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
+
+ // Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
+ // instructions required by DebugCompilationUnit
+ const Register DwarfVersionReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DwarfVersionReg, LLT::scalar(32));
+ MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(DwarfVersionReg)
+ .addUse(GR->getSPIRVTypeID(I32Ty))
+ .addImm(DwarfVersion);
+
+ const Register DebugInfoVersionReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DebugInfoVersionReg, LLT::scalar(32));
+ MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(DebugInfoVersionReg)
+ .addUse(GR->getSPIRVTypeID(I32Ty))
+ .addImm(DebugInfoVersion);
+
+ const Register SourceLanguageReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(SourceLanguageReg, LLT::scalar(32));
+ MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(SourceLanguageReg)
+ .addUse(GR->getSPIRVTypeID(I32Ty))
+ .addImm(SourceLanguage);
+
+ // Emit DebugCompilationUnit
+ const Register DebugCompUnitResIdReg =
+ MRI.createVirtualRegister(&SPIRV::IDRegClass);
+ MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
+ MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+ .addDef(DebugCompUnitResIdReg)
+ .addUse(GR->getSPIRVTypeID(VoidTyMI))
+ .addImm(static_cast<int64_t>(
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+ .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
+ .addUse(DebugInfoVersionReg)
+ .addUse(DwarfVersionReg)
+ .addUse(DebugSourceResIdReg)
+ .addUse(SourceLanguageReg);
+ MIB.constrainAllUses(*TII, *TRI, *RBI);
+ }
return true;
}
bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
bool Res = false;
+ // emitGlobalDI needs to be executed only once to avoid
+ // emitting duplicates
if (!IsGlobalDIEmitted) {
IsGlobalDIEmitted = true;
Res = emitGlobalDI(MF);
>From c8bccd58c5971fc3e2648ecaa17b519c6601202e Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 8 Jul 2024 13:59:28 +0200
Subject: [PATCH 07/10] Added test
---
.../SPIRV/debug-info/basic-global-di.ll | 129 ++++++++++++++++++
1 file changed, 129 insertions(+)
create mode 100644 llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
new file mode 100644
index 0000000000000..eef31da57831c
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -0,0 +1,129 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+
+source_filename = "example.c"
+target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
+target triple = "spir"
+
+%struct.A = type { i32, float }
+
+; CHECK-SPIRV: [[ext_inst_non_semantic:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+; CHECK-SPIRV: [[filename_str:%[0-9]+]] = OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c"
+; CHECK-SPIRV-DAG: [[type_void:%[0-9]+]] = OpTypeVoid
+; CHECK-SPIRV-DAG: [[type_i32:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: [[dwarf_version:%[0-9]+]] = OpConstant [[type_i32]] 5
+; CHECK-SPIRV-DAG: [[debug_info_version:%[0-9]+]] = OpConstant [[type_i32]] 21
+; CHECK-SPIRV-DAG: [[source_language:%[0-9]+]] = OpConstant [[type_i32]] 3
+; CHECK-SPIRV: [[debug_source:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugSource [[filename_str]]
+; CHECK-SPIRV: [[debug_compiation_unit:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugCompilationUnit [[source_language]] [[dwarf_version]] [[debug_source]] [[debug_info_version]]
+
+; Function Attrs: convergent noinline norecurse nounwind optnone
+define dso_local spir_func i32 @bar(i32 noundef %n) #0 !dbg !8 {
+entry:
+ %n.addr = alloca i32, align 4
+ store i32 %n, ptr %n.addr, align 4
+ #dbg_declare(ptr %n.addr, !13, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !14)
+ %0 = load i32, ptr %n.addr, align 4, !dbg !15
+ %1 = load i32, ptr %n.addr, align 4, !dbg !16
+ %mul = mul nsw i32 %0, %1, !dbg !17
+ %2 = load i32, ptr %n.addr, align 4, !dbg !18
+ %add = add nsw i32 %mul, %2, !dbg !19
+ ret i32 %add, !dbg !20
+}
+
+; Function Attrs: convergent noinline norecurse nounwind optnone
+define dso_local spir_func i32 @foo(i32 noundef %num, ptr addrspace(4) noundef %a) #0 !dbg !21 {
+entry:
+ %num.addr = alloca i32, align 4
+ %a.addr = alloca ptr addrspace(4), align 4
+ store i32 %num, ptr %num.addr, align 4
+ #dbg_declare(ptr %num.addr, !30, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !31)
+ store ptr addrspace(4) %a, ptr %a.addr, align 4
+ #dbg_declare(ptr %a.addr, !32, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !33)
+ %0 = load i32, ptr %num.addr, align 4, !dbg !34
+ %1 = load i32, ptr %num.addr, align 4, !dbg !35
+ %mul = mul nsw i32 %0, %1, !dbg !36
+ %2 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !37
+ %a1 = getelementptr inbounds %struct.A, ptr addrspace(4) %2, i32 0, i32 0, !dbg !38
+ %3 = load i32, ptr addrspace(4) %a1, align 4, !dbg !38
+ %mul2 = mul nsw i32 %mul, %3, !dbg !39
+ %conv = sitofp i32 %mul2 to float, !dbg !34
+ %4 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !40
+ %b = getelementptr inbounds %struct.A, ptr addrspace(4) %4, i32 0, i32 1, !dbg !41
+ %5 = load float, ptr addrspace(4) %b, align 4, !dbg !41
+ %6 = load i32, ptr %num.addr, align 4, !dbg !42
+ %call = call spir_func i32 @bar(i32 noundef %6) #2, !dbg !43
+ %conv4 = sitofp i32 %call to float, !dbg !43
+ %7 = call float @llvm.fmuladd.f32(float %conv, float %5, float %conv4), !dbg !44
+ %conv5 = fptosi float %7 to i32, !dbg !34
+ ret i32 %conv5, !dbg !45
+}
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare float @llvm.fmuladd.f32(float, float, float) #1
+
+; Function Attrs: convergent noinline norecurse nounwind optnone
+define dso_local spir_func void @zar() #0 !dbg !46 {
+entry:
+ ret void, !dbg !49
+}
+
+attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #2 = { convergent nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+!opencl.ocl.version = !{!6}
+!opencl.spir.version = !{!6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "example.c", directory: "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC", checksumkind: CSK_MD5, checksum: "ffffffffffffffffffffffffffffffff")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 7, !"frame-pointer", i32 2}
+!6 = !{i32 3, i32 0}
+!7 = !{!"clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)"}
+!8 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 6, type: !9, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
+!9 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !10)
+!10 = !{!11, !11}
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !{}
+!13 = !DILocalVariable(name: "n", arg: 1, scope: !8, file: !1, line: 6, type: !11)
+!14 = !DILocation(line: 6, column: 13, scope: !8)
+!15 = !DILocation(line: 6, column: 25, scope: !8)
+!16 = !DILocation(line: 6, column: 29, scope: !8)
+!17 = !DILocation(line: 6, column: 27, scope: !8)
+!18 = !DILocation(line: 6, column: 33, scope: !8)
+!19 = !DILocation(line: 6, column: 31, scope: !8)
+!20 = !DILocation(line: 6, column: 18, scope: !8)
+!21 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 8, type: !22, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
+!22 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !23)
+!23 = !{!11, !11, !24}
+!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 32, dwarfAddressSpace: 4)
+!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !1, line: 1, size: 64, elements: !26)
+!26 = !{!27, !28}
+!27 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !25, file: !1, line: 2, baseType: !11, size: 32)
+!28 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !25, file: !1, line: 3, baseType: !29, size: 32, offset: 32)
+!29 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!30 = !DILocalVariable(name: "num", arg: 1, scope: !21, file: !1, line: 8, type: !11)
+!31 = !DILocation(line: 8, column: 13, scope: !21)
+!32 = !DILocalVariable(name: "a", arg: 2, scope: !21, file: !1, line: 8, type: !24)
+!33 = !DILocation(line: 8, column: 28, scope: !21)
+!34 = !DILocation(line: 8, column: 40, scope: !21)
+!35 = !DILocation(line: 8, column: 46, scope: !21)
+!36 = !DILocation(line: 8, column: 44, scope: !21)
+!37 = !DILocation(line: 8, column: 52, scope: !21)
+!38 = !DILocation(line: 8, column: 55, scope: !21)
+!39 = !DILocation(line: 8, column: 50, scope: !21)
+!40 = !DILocation(line: 8, column: 59, scope: !21)
+!41 = !DILocation(line: 8, column: 62, scope: !21)
+!42 = !DILocation(line: 8, column: 70, scope: !21)
+!43 = !DILocation(line: 8, column: 66, scope: !21)
+!44 = !DILocation(line: 8, column: 64, scope: !21)
+!45 = !DILocation(line: 8, column: 33, scope: !21)
+!46 = distinct !DISubprogram(name: "zar", scope: !1, file: !1, line: 10, type: !47, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
+!47 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !48)
+!48 = !{null}
+!49 = !DILocation(line: 10, column: 13, scope: !46)
>From 50c2c9a597ca977f931795fa2486a0fc8daf1f8e Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 8 Jul 2024 14:21:57 +0200
Subject: [PATCH 08/10] Fix comment typo
---
llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 857d07f79d254..2868c7a307365 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -105,7 +105,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
->getSExtValue();
}
}
- // NonSemantic.Shader.DebugInfo.100 global DI intruction emitting
+ // NonSemantic.Shader.DebugInfo.100 global DI instruction emitting
{
// Required LLVM variables for emitting logic
const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
>From e4c20829154a868cb3a45592ffa0e7a586d67845 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Wed, 10 Jul 2024 18:43:44 +0200
Subject: [PATCH 09/10] Fix after review plus mir test
---
.../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 13 +-
llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp | 5 +-
.../SPIRV/debug-info/basic-global-di.ll | 119 +++---------------
3 files changed, 26 insertions(+), 111 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 2868c7a307365..d866af2c87392 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -123,9 +123,8 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
MIB.addDef(StrReg);
addStringImm(FilePath, MIB);
- const SPIRVType *VoidTyMI =
+ const SPIRVType *VoidTy =
GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder);
- GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
// Emit DebugSource which is required by DebugCompilationUnit
const Register DebugSourceResIdReg =
@@ -133,16 +132,16 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
.addDef(DebugSourceResIdReg)
- .addUse(GR->getSPIRVTypeID(VoidTyMI))
+ .addUse(GR->getSPIRVTypeID(VoidTy))
.addImm(static_cast<int64_t>(
SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
.addImm(SPIRV::NonSemanticExtInst::DebugSource)
.addUse(StrReg);
MIB.constrainAllUses(*TII, *TRI, *RBI);
+ GR->assignSPIRVTypeToVReg(VoidTy, DebugSourceResIdReg, MF);
const SPIRVType *I32Ty =
GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder);
- GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
// Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
// instructions required by DebugCompilationUnit
@@ -153,6 +152,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
.addDef(DwarfVersionReg)
.addUse(GR->getSPIRVTypeID(I32Ty))
.addImm(DwarfVersion);
+ GR->assignSPIRVTypeToVReg(I32Ty, DwarfVersionReg, MF);
const Register DebugInfoVersionReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
@@ -161,6 +161,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
.addDef(DebugInfoVersionReg)
.addUse(GR->getSPIRVTypeID(I32Ty))
.addImm(DebugInfoVersion);
+ GR->assignSPIRVTypeToVReg(I32Ty, DebugInfoVersionReg, MF);
const Register SourceLanguageReg =
MRI.createVirtualRegister(&SPIRV::IDRegClass);
@@ -169,6 +170,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
.addDef(SourceLanguageReg)
.addUse(GR->getSPIRVTypeID(I32Ty))
.addImm(SourceLanguage);
+ GR->assignSPIRVTypeToVReg(I32Ty, SourceLanguageReg, MF);
// Emit DebugCompilationUnit
const Register DebugCompUnitResIdReg =
@@ -176,7 +178,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
.addDef(DebugCompUnitResIdReg)
- .addUse(GR->getSPIRVTypeID(VoidTyMI))
+ .addUse(GR->getSPIRVTypeID(VoidTy))
.addImm(static_cast<int64_t>(
SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
.addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
@@ -185,6 +187,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
.addUse(DebugSourceResIdReg)
.addUse(SourceLanguageReg);
MIB.constrainAllUses(*TII, *TRI, *RBI);
+ GR->assignSPIRVTypeToVReg(VoidTy, DebugCompUnitResIdReg, MF);
}
return true;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 2470bce56faf7..32a9b3f71cf08 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -115,7 +115,7 @@ class SPIRVPassConfig : public TargetPassConfig {
void addOptimizedRegAlloc() override {}
void addPostRegAlloc() override;
- void addMachinePasses() override;
+ void addPreEmitPass() override;
private:
const SPIRVTargetMachine &TM;
@@ -209,8 +209,7 @@ bool SPIRVPassConfig::addRegBankSelect() {
return false;
}
-void SPIRVPassConfig::addMachinePasses() {
- TargetPassConfig::addMachinePasses();
+void SPIRVPassConfig::addPreEmitPass() {
addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
}
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
index eef31da57831c..6b7a13a24d7e8 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -1,10 +1,15 @@
+; RUN: llc --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-source_filename = "example.c"
-target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
-target triple = "spir"
-
-%struct.A = type { i32, float }
+; CHECK-MIR-DAG: [[type_void:%[0-9]+\:type]] = OpTypeVoid
+; CHECK-MIR-DAG: [[type_i32:%[0-9]+\:type\(s32\)]] = OpTypeInt 32, 0
+; CHECK-MIR-DAG: [[dwarf_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 5
+; CHECK-MIR-DAG: [[source_language:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 3
+; CHECK-MIR-DAG: [[debug_info_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 21
+; CHECK-MIR-DAG: [[filename_str:%[0-9]+\:id\(s32\)]] = OpString 1094795567, 1094795585, 792805697, 1111638594, 1111638594, 1128481583, 1128481603, 1697596227, 1886216568, 1663985004, 0
+; CHECK-MIR-DAG: [[debug_source:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 35, [[filename_str]]
+; CHECK-MIR-DAG: [[debug_compilation_unit:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 1, [[source_language]], [[dwarf_version]], [[debug_source]], [[debug_info_version]]
; CHECK-SPIRV: [[ext_inst_non_semantic:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
; CHECK-SPIRV: [[filename_str:%[0-9]+]] = OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c"
@@ -16,114 +21,22 @@ target triple = "spir"
; CHECK-SPIRV: [[debug_source:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugSource [[filename_str]]
; CHECK-SPIRV: [[debug_compiation_unit:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugCompilationUnit [[source_language]] [[dwarf_version]] [[debug_source]] [[debug_info_version]]
-; Function Attrs: convergent noinline norecurse nounwind optnone
-define dso_local spir_func i32 @bar(i32 noundef %n) #0 !dbg !8 {
-entry:
- %n.addr = alloca i32, align 4
- store i32 %n, ptr %n.addr, align 4
- #dbg_declare(ptr %n.addr, !13, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !14)
- %0 = load i32, ptr %n.addr, align 4, !dbg !15
- %1 = load i32, ptr %n.addr, align 4, !dbg !16
- %mul = mul nsw i32 %0, %1, !dbg !17
- %2 = load i32, ptr %n.addr, align 4, !dbg !18
- %add = add nsw i32 %mul, %2, !dbg !19
- ret i32 %add, !dbg !20
-}
-
-; Function Attrs: convergent noinline norecurse nounwind optnone
-define dso_local spir_func i32 @foo(i32 noundef %num, ptr addrspace(4) noundef %a) #0 !dbg !21 {
+define spir_func void @foo() {
entry:
- %num.addr = alloca i32, align 4
- %a.addr = alloca ptr addrspace(4), align 4
- store i32 %num, ptr %num.addr, align 4
- #dbg_declare(ptr %num.addr, !30, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !31)
- store ptr addrspace(4) %a, ptr %a.addr, align 4
- #dbg_declare(ptr %a.addr, !32, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !33)
- %0 = load i32, ptr %num.addr, align 4, !dbg !34
- %1 = load i32, ptr %num.addr, align 4, !dbg !35
- %mul = mul nsw i32 %0, %1, !dbg !36
- %2 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !37
- %a1 = getelementptr inbounds %struct.A, ptr addrspace(4) %2, i32 0, i32 0, !dbg !38
- %3 = load i32, ptr addrspace(4) %a1, align 4, !dbg !38
- %mul2 = mul nsw i32 %mul, %3, !dbg !39
- %conv = sitofp i32 %mul2 to float, !dbg !34
- %4 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !40
- %b = getelementptr inbounds %struct.A, ptr addrspace(4) %4, i32 0, i32 1, !dbg !41
- %5 = load float, ptr addrspace(4) %b, align 4, !dbg !41
- %6 = load i32, ptr %num.addr, align 4, !dbg !42
- %call = call spir_func i32 @bar(i32 noundef %6) #2, !dbg !43
- %conv4 = sitofp i32 %call to float, !dbg !43
- %7 = call float @llvm.fmuladd.f32(float %conv, float %5, float %conv4), !dbg !44
- %conv5 = fptosi float %7 to i32, !dbg !34
- ret i32 %conv5, !dbg !45
+ ret void
}
-; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
-declare float @llvm.fmuladd.f32(float, float, float) #1
-
-; Function Attrs: convergent noinline norecurse nounwind optnone
-define dso_local spir_func void @zar() #0 !dbg !46 {
+define spir_func void @bar() {
entry:
- ret void, !dbg !49
+ ret void
}
-attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
-attributes #2 = { convergent nounwind }
-
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3, !4, !5}
-!opencl.ocl.version = !{!6}
-!opencl.spir.version = !{!6}
-!llvm.ident = !{!7}
-!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-!1 = !DIFile(filename: "example.c", directory: "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC", checksumkind: CSK_MD5, checksum: "ffffffffffffffffffffffffffffffff")
+!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang version XX.X.XXXX (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "example.c", directory: "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC", checksumkind: CSK_MD5, checksum: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
!2 = !{i32 7, !"Dwarf Version", i32 5}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 7, !"frame-pointer", i32 2}
-!6 = !{i32 3, i32 0}
-!7 = !{!"clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)"}
-!8 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 6, type: !9, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
-!9 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !10)
-!10 = !{!11, !11}
-!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!12 = !{}
-!13 = !DILocalVariable(name: "n", arg: 1, scope: !8, file: !1, line: 6, type: !11)
-!14 = !DILocation(line: 6, column: 13, scope: !8)
-!15 = !DILocation(line: 6, column: 25, scope: !8)
-!16 = !DILocation(line: 6, column: 29, scope: !8)
-!17 = !DILocation(line: 6, column: 27, scope: !8)
-!18 = !DILocation(line: 6, column: 33, scope: !8)
-!19 = !DILocation(line: 6, column: 31, scope: !8)
-!20 = !DILocation(line: 6, column: 18, scope: !8)
-!21 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 8, type: !22, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
-!22 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !23)
-!23 = !{!11, !11, !24}
-!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 32, dwarfAddressSpace: 4)
-!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !1, line: 1, size: 64, elements: !26)
-!26 = !{!27, !28}
-!27 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !25, file: !1, line: 2, baseType: !11, size: 32)
-!28 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !25, file: !1, line: 3, baseType: !29, size: 32, offset: 32)
-!29 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-!30 = !DILocalVariable(name: "num", arg: 1, scope: !21, file: !1, line: 8, type: !11)
-!31 = !DILocation(line: 8, column: 13, scope: !21)
-!32 = !DILocalVariable(name: "a", arg: 2, scope: !21, file: !1, line: 8, type: !24)
-!33 = !DILocation(line: 8, column: 28, scope: !21)
-!34 = !DILocation(line: 8, column: 40, scope: !21)
-!35 = !DILocation(line: 8, column: 46, scope: !21)
-!36 = !DILocation(line: 8, column: 44, scope: !21)
-!37 = !DILocation(line: 8, column: 52, scope: !21)
-!38 = !DILocation(line: 8, column: 55, scope: !21)
-!39 = !DILocation(line: 8, column: 50, scope: !21)
-!40 = !DILocation(line: 8, column: 59, scope: !21)
-!41 = !DILocation(line: 8, column: 62, scope: !21)
-!42 = !DILocation(line: 8, column: 70, scope: !21)
-!43 = !DILocation(line: 8, column: 66, scope: !21)
-!44 = !DILocation(line: 8, column: 64, scope: !21)
-!45 = !DILocation(line: 8, column: 33, scope: !21)
-!46 = distinct !DISubprogram(name: "zar", scope: !1, file: !1, line: 10, type: !47, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
-!47 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !48)
-!48 = !{null}
-!49 = !DILocation(line: 10, column: 13, scope: !46)
>From ad701a28544bf83550dde24e2e667443d0865db5 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Thu, 11 Jul 2024 15:32:11 +0200
Subject: [PATCH 10/10] Fixed spirv-val OpLabel issue
---
llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp | 3 ++-
llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 5 ++++-
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 8 ++++++++
llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll | 6 +++---
4 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index c7c244cfa8977..90a9ab1d33ced 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -68,7 +68,8 @@ static const std::map<std::string, SPIRV::Extension::Extension>
SPIRV::Extension::Extension::SPV_KHR_shader_clock},
{"SPV_KHR_cooperative_matrix",
SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
-};
+ {"SPV_KHR_non_semantic_info",
+ SPIRV::Extension::Extension::SPV_KHR_non_semantic_info}};
bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
llvm::StringRef ArgValue,
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index d866af2c87392..cc17fa14eec85 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -114,7 +114,10 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
MachineRegisterInfo &MRI = MF.getRegInfo();
MachineBasicBlock &MBB = *MF.begin();
- MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+ // To correct placement of a OpLabel instruction during SPIRVAsmPrinter
+ // emission all new instructions needs to be placed after OpFunction
+ MachineIRBuilder MIRBuilder(MBB, MBB.end());
// Emit OpString with FilePath which is required by DebugSource
const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 45518d79edf9e..a2fcfc636e368 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -910,6 +910,14 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(SPIRV::Capability::Float16Buffer);
break;
}
+ case SPIRV::OpExtInst: {
+ if (MI.getOperand(2).getImm() ==
+ static_cast<int64_t>(
+ SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
+ Reqs.addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
+ }
+ break;
+ }
case SPIRV::OpBitReverse:
case SPIRV::OpBitFieldInsert:
case SPIRV::OpBitFieldSExtract:
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
index 6b7a13a24d7e8..1b5979187a7cd 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -1,6 +1,6 @@
-; RUN: llc --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc --spirv-ext=+SPV_KHR_non_semantic_info --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
+; RUN: llc --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; CHECK-MIR-DAG: [[type_void:%[0-9]+\:type]] = OpTypeVoid
; CHECK-MIR-DAG: [[type_i32:%[0-9]+\:type\(s32\)]] = OpTypeInt 32, 0
More information about the llvm-commits
mailing list