[SPIRV] Emitting DebugSource, DebugCompileUnit (#97558)
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_info 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.
This commit is contained in:
parent
151945151c
commit
62da359ce7
@ -33,7 +33,11 @@ Static Compiler Commands
|
||||
Command: `llc -O1 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_arbitrary_precision_integers input.ll -o output.spvt`
|
||||
Description: Compiles an LLVM IL file to SPIR-V with (`-O1`) optimizations, targeting a 64-bit architecture. It enables the SPV_INTEL_arbitrary_precision_integers extension.
|
||||
|
||||
3. **SPIR-V Binary Generation**
|
||||
3. **Compilation with experimental NonSemantic.Shader.DebugInfo.100 support**
|
||||
Command: `llc --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info input.ll -o output.spvt`
|
||||
Description: Compiles an LLVM IL file to SPIR-V with additional NonSemantic.Shader.DebugInfo.100 instructions. It enables the required SPV_KHR_non_semantic_info extension.
|
||||
|
||||
4. **SPIR-V Binary Generation**
|
||||
Command: `llc -O0 -mtriple=spirv64-unknown-unknown -filetype=obj input.ll -o output.spvt`
|
||||
Description: Generates a SPIR-V object file (`output.spvt`) from an LLVM module, targeting a 64-bit SPIR-V architecture with no optimizations.
|
||||
|
||||
@ -181,6 +185,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
|
||||
- Adds a new instruction that enables rotating values across invocations within a subgroup.
|
||||
* - ``SPV_KHR_uniform_group_instructions``
|
||||
- Allows support for additional group operations within uniform control flow.
|
||||
* - ``SPV_KHR_non_semantic_info``
|
||||
- Adds the ability to declare extended instruction sets that have no semantic impact and can be safely removed from a module.
|
||||
|
||||
To enable multiple extensions, list them separated by spaces. For example, to enable support for atomic operations on floating-point numbers and arbitrary precision integers, use:
|
||||
|
||||
|
@ -40,6 +40,7 @@ add_llvm_target(SPIRVCodeGen
|
||||
SPIRVSubtarget.cpp
|
||||
SPIRVTargetMachine.cpp
|
||||
SPIRVUtils.cpp
|
||||
SPIRVEmitNonSemanticDI.cpp
|
||||
|
||||
LINK_COMPONENTS
|
||||
Analysis
|
||||
|
@ -26,6 +26,7 @@ FunctionPass *createSPIRVRegularizerPass();
|
||||
FunctionPass *createSPIRVPreLegalizerPass();
|
||||
FunctionPass *createSPIRVPostLegalizerPass();
|
||||
ModulePass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM);
|
||||
MachineFunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM);
|
||||
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
|
||||
|
@ -274,6 +274,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);
|
||||
@ -589,9 +591,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.
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
188
llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
Normal file
188
llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
#include "MCTargetDesc/SPIRVBaseInfo.h"
|
||||
#include "MCTargetDesc/SPIRVMCTargetDesc.h"
|
||||
#include "SPIRVGlobalRegistry.h"
|
||||
#include "SPIRVRegisterInfo.h"
|
||||
#include "SPIRVTargetMachine.h"
|
||||
#include "llvm/ADT/SmallString.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;
|
||||
SmallString<128> 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 =
|
||||
getAnalysis<MachineModuleInfoWrapperPass>().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();
|
||||
sys::path::append(FilePath, File->getDirectory(), File->getFilename());
|
||||
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();
|
||||
|
||||
// To correct placement of a OpLabel instruction during SPIRVAsmPrinter
|
||||
// emission all new instructions needs to be placed after OpFunction
|
||||
// and before first terminator
|
||||
MachineIRBuilder MIRBuilder(MBB, MBB.getFirstTerminator());
|
||||
|
||||
// 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 *VoidTy =
|
||||
GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder);
|
||||
|
||||
// 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(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);
|
||||
|
||||
// Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
|
||||
// instructions required by DebugCompilationUnit
|
||||
const Register DwarfVersionReg =
|
||||
GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);
|
||||
const Register DebugInfoVersionReg =
|
||||
GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);
|
||||
const Register SourceLanguageReg =
|
||||
GR->buildConstantInt(SourceLanguage, MIRBuilder, I32Ty, false);
|
||||
|
||||
// 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(VoidTy))
|
||||
.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);
|
||||
GR->assignSPIRVTypeToVReg(VoidTy, DebugCompUnitResIdReg, MF);
|
||||
}
|
||||
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);
|
||||
}
|
||||
return Res;
|
||||
}
|
@ -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,19 @@ 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);
|
||||
@ -899,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:
|
||||
|
@ -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.
|
||||
};
|
||||
|
@ -115,6 +115,7 @@ public:
|
||||
void addOptimizedRegAlloc() override {}
|
||||
|
||||
void addPostRegAlloc() override;
|
||||
void addPreEmitPass() override;
|
||||
|
||||
private:
|
||||
const SPIRVTargetMachine &TM;
|
||||
@ -208,6 +209,17 @@ bool SPIRVPassConfig::addRegBankSelect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static cl::opt<bool> SPVEnableNonSemanticDI(
|
||||
"spv-emit-nonsemantic-debug-info",
|
||||
cl::desc("Emit SPIR-V NonSemantic.Shader.DebugInfo.100 instructions"),
|
||||
cl::Optional, cl::init(false));
|
||||
|
||||
void SPIRVPassConfig::addPreEmitPass() {
|
||||
if (SPVEnableNonSemanticDI) {
|
||||
addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
// A custom subclass of InstructionSelect, which is mostly the same except from
|
||||
// not requiring RegBankSelect to occur previously.
|
||||
|
46
llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
Normal file
46
llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
Normal file
@ -0,0 +1,46 @@
|
||||
; RUN: llc --verify-machineinstrs --spv-emit-nonsemantic-debug-info --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 --verify-machineinstrs --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
|
||||
; RUN: llc --verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_non_semantic_info %s -o - | FileCheck %s --check-prefix=CHECK-OPTION
|
||||
; 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_i64:%[0-9]+\:type\(s64\)]] = OpTypeInt 32, 0
|
||||
; CHECK-MIR-DAG: [[dwarf_version:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i64]], 5
|
||||
; CHECK-MIR-DAG: [[source_language:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i64]], 3
|
||||
; CHECK-MIR-DAG: [[debug_info_version:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i64]], 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"
|
||||
; 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]]
|
||||
|
||||
; CHECK-OPTION-NOT: OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
|
||||
; CHECK-OPTION-NOT: OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c"
|
||||
|
||||
define spir_func void @foo() {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
define spir_func void @bar() {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2, !3, !4, !5}
|
||||
|
||||
!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}
|
Loading…
x
Reference in New Issue
Block a user