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

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 10 09:51:58 PDT 2024


================
@@ -0,0 +1,201 @@
+#include "MCTargetDesc/SPIRVBaseInfo.h"
+#include "MCTargetDesc/SPIRVMCTargetDesc.h"
+#include "SPIRVGlobalRegistry.h"
+#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"
+#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"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Path.h"
+
+#define DEBUG_TYPE "spirv-nonsemantic-debug-info"
+
+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(SPIRVTargetMachine *TM) {
+  return new SPIRVEmitNonSemanticDI(TM);
+}
+} // namespace llvm
+
+using namespace llvm;
+
+INITIALIZE_PASS(SPIRVEmitNonSemanticDI, DEBUG_TYPE,
+                "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
+
+char SPIRVEmitNonSemanticDI::ID = 0;
+
+SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI(SPIRVTargetMachine *TM)
+    : MachineFunctionPass(ID), TM(TM) {
+  initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
+}
+
+SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
+  initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
+}
+
+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;
+  }
+
+  // Required variables to get from metadata search
+  LLVMContext *Context;
+  std::string FilePath;
+  unsigned SourceLanguage = 0;
+  int64_t DwarfVersion = 0;
+  int64_t DebugInfoVersion = 0;
+
+  // 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 instruction 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);
----------------
bwlodarcz wrote:

Done. 

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


More information about the llvm-commits mailing list