[llvm] [SPIRV] Emitting DebugSource, DebugCompileUnit (PR #97558)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 5 05:31:22 PDT 2024


https://github.com/bwlodarcz updated https://github.com/llvm/llvm-project/pull/97558

>From cd6da102610a9ece6277706c3fdd95332fbda079 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 1/6] [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 14647e92f5d088..5f8aea5fc8d84d 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 e597a1dc8dc06c..c32bf6f5a863d5 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 00000000000000..5b938047025d13
--- /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 52fc6f33b4ef14..ee71190bc02ffd 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 12854b30d991adc333e32e0c3c087789cf32d340 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 2/6] [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 c32bf6f5a863d5..6c35a467f53bef 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 3206c264f99d3f..f9f36cc25eec50 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 5b938047025d13..f630685d98ac8b 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 ac0aa682ea4beb..32ca6c4155dfed 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 79226d6d93efb2..024728c347e8a8 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 ee71190bc02ffd..bffc079981bc11 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 d7ed170c0a3b57c4fb73f1b20e0ab73f6ad47276 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 3/6] 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 f630685d98ac8b..bc39ce11222be0 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 32ca6c4155dfed..45518d79edf9ed 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 4f80ab0aacfeb62e1cc5506b18db4470a43907c1 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 4/6] 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 bc39ce11222be0..8f3aeede9169ca 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 1b5adbdb517948c4c58445bd6afa2c2d50a3bed2 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 5/6] 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 8f3aeede9169ca..fe3b0baf4df685 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 bffc079981bc11..2470bce56faf73 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 ea8b9cb0f2382f461743e0094fce467d0fad0afe 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 6/6] 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 fe3b0baf4df685..4e5f9c87731436 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);



More information about the llvm-commits mailing list