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

Vyacheslav Levytskyy via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 03:06:55 PDT 2024


================
@@ -0,0 +1,148 @@
+#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"
+#include "llvm/Support/Casting.h"
+
+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, "spirv-nonsemantic-debug-info",
+                "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) {
+  MachineModuleInfo &MMI = MF.getMMI();
+  const Module *M = MMI.getModule();
+  NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+  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))) {
+      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);
----------------
VyacheslavLevytskyy wrote:

Just as an idea, please feel free to ignore this, it would be easier to read the code if you group variables closer to each other when they are logically related. For example, if you can define and use all variables related to `DwarfVersion` closer to each other this would definitely facilitate tracing of `what` is `defined because of` and `used when` and so makes it easier to understand the underlying logics.

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


More information about the llvm-commits mailing list