It no longer has a Scope (parent) parameter. It results in several changes including how to determine DIBuilder to use for debug info generation.
The patch also fixes a bug of incorrect debug info assignment in case of recursion DebugInfo inst generation.
Signed-off-by: Sidorov, Dmitry <dmitry.sidorov@intel.com>
Gbp-Pq: Name 0058-DebugInfo-Adjust-TypeMember-for-NonSemantic-spec-203.patch
}
SPIRVEntry *Res = transDbgEntryImpl(DIEntry);
assert(Res && "Translation failure");
+ // We might end up having a recursive debug info generation like the
+ // following:
+ // translation of DIDerivedType (member) calls DICompositeType translation
+ // as its parent scope;
+ // translation of DICompositeType calls translation of its members
+ // (DIDerivedType with member tag).
+ // Here we make only the latest of these instructions be cached and hence
+ // reused
+ // FIXME: find a way to not create dead instruction
+ if (MDMap[DIEntry])
+ return MDMap[DIEntry];
MDMap[DIEntry] = Res;
return Res;
}
}
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgMemberType(const DIDerivedType *MT) {
- using namespace SPIRVDebug::Operand::TypeMember;
+ if (isNonSemanticDebugInfo())
+ return transDbgMemberTypeNonSemantic(MT);
+ return transDbgMemberTypeOpenCL(MT);
+}
+
+SPIRVEntry *
+LLVMToSPIRVDbgTran::transDbgMemberTypeOpenCL(const DIDerivedType *MT) {
+ using namespace SPIRVDebug::Operand::TypeMember::OpenCL;
SPIRVWordVec Ops(MinOperandCount);
Ops[NameIdx] = BM->getString(MT->getName().str())->getId();
return BM->addDebugInfo(SPIRVDebug::TypeMember, getVoidTy(), Ops);
}
+SPIRVEntry *
+LLVMToSPIRVDbgTran::transDbgMemberTypeNonSemantic(const DIDerivedType *MT) {
+ using namespace SPIRVDebug::Operand::TypeMember::NonSemantic;
+ SPIRVWordVec Ops(MinOperandCount);
+
+ Ops[NameIdx] = BM->getString(MT->getName().str())->getId();
+ Ops[TypeIdx] = transDbgEntry(MT->getBaseType())->getId();
+ Ops[SourceIdx] = getSource(MT)->getId();
+ Ops[LineIdx] = MT->getLine();
+ Ops[ColumnIdx] = 0; // This version of DIDerivedType has no column number
+ ConstantInt *Offset = getUInt(M, MT->getOffsetInBits());
+ Ops[OffsetIdx] = SPIRVWriter->transValue(Offset, nullptr)->getId();
+ ConstantInt *Size = getUInt(M, MT->getSizeInBits());
+ Ops[SizeIdx] = SPIRVWriter->transValue(Size, nullptr)->getId();
+ Ops[FlagsIdx] = adjustAccessFlags(MT->getScope(), transDebugFlags(MT));
+ transDbgEntry(MT->getScope())->getId();
+ if (MT->isStaticMember()) {
+ if (llvm::Constant *C = MT->getConstant()) {
+ SPIRVValue *Val = SPIRVWriter->transValue(C, nullptr);
+ assert(isConstantOpCode(Val->getOpCode()) &&
+ "LLVM constant must be translated to SPIRV constant");
+ Ops.push_back(Val->getId());
+ }
+ }
+ transformToConstant(Ops, {LineIdx, ColumnIdx, FlagsIdx});
+ return BM->addDebugInfo(SPIRVDebug::TypeMember, getVoidTy(), Ops);
+}
+
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgInheritance(const DIDerivedType *DT) {
using namespace SPIRVDebug::Operand::TypeInheritance;
SPIRVWordVec Ops(OperandCount);
SPIRVEntry *transDbgEnumType(const DICompositeType *ET);
SPIRVEntry *transDbgCompositeType(const DICompositeType *CT);
SPIRVEntry *transDbgMemberType(const DIDerivedType *MT);
+ SPIRVEntry *transDbgMemberTypeOpenCL(const DIDerivedType *MT);
+ SPIRVEntry *transDbgMemberTypeNonSemantic(const DIDerivedType *MT);
SPIRVEntry *transDbgInheritance(const DIDerivedType *DT);
SPIRVEntry *transDbgPtrToMember(const DIDerivedType *DT);
DebugInstCache[DebugInst] = CT;
SmallVector<llvm::Metadata *, 8> EltTys;
for (size_t I = FirstMemberIdx; I < Ops.size(); ++I) {
- EltTys.push_back(transDebugInst(BM->get<SPIRVExtInst>(Ops[I])));
+ auto *MemberInst = BM->get<SPIRVExtInst>(Ops[I]);
+ if (MemberInst->getExtOp() == SPIRVDebug::TypeMember) {
+ auto *SPVMemberInst = BM->get<SPIRVExtInst>(Ops[I]);
+ DINode *MemberMD =
+ transTypeMember(SPVMemberInst, DebugInst, cast<DIScope>(CT));
+ EltTys.push_back(MemberMD);
+ DebugInstCache[SPVMemberInst] = MemberMD;
+ } else {
+ EltTys.emplace_back(transDebugInst(BM->get<SPIRVExtInst>(Ops[I])));
+ }
}
DINodeArray Elements = getDIBuilder(DebugInst).getOrCreateArray(EltTys);
getDIBuilder(DebugInst).replaceArrays(CT, Elements);
0 /*AlignInBits*/, Encoding);
}
-DINode *SPIRVToLLVMDbgTran::transTypeMember(const SPIRVExtInst *DebugInst) {
- using namespace SPIRVDebug::Operand::TypeMember;
+DINode *SPIRVToLLVMDbgTran::transTypeMember(const SPIRVExtInst *DebugInst,
+ const SPIRVExtInst *ParentInst,
+ DIScope *Scope) {
+ if (isNonSemanticDebugInfo(DebugInst->getExtSetKind()))
+ // In NonSemantic spec TypeMember doesn't have Scope parameter
+ return transTypeMemberNonSemantic(DebugInst, ParentInst, Scope);
+ return transTypeMemberOpenCL(DebugInst);
+}
+
+DINode *
+SPIRVToLLVMDbgTran::transTypeMemberOpenCL(const SPIRVExtInst *DebugInst) {
+ using namespace SPIRVDebug::Operand::TypeMember::OpenCL;
const SPIRVWordVec &Ops = DebugInst->getArguments();
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
Flags, BaseType);
}
+DINode *
+SPIRVToLLVMDbgTran::transTypeMemberNonSemantic(const SPIRVExtInst *DebugInst,
+ const SPIRVExtInst *ParentInst,
+ DIScope *Scope) {
+ if (!Scope)
+ // Will be translated later when processing TypeMember's parent
+ return nullptr;
+ using namespace SPIRVDebug::Operand::TypeMember::NonSemantic;
+ const SPIRVWordVec &Ops = DebugInst->getArguments();
+ assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
+
+ DIFile *File = getFile(Ops[SourceIdx]);
+ SPIRVWord LineNo =
+ getConstantValueOrLiteral(Ops, LineIdx, DebugInst->getExtSetKind());
+ StringRef Name = getString(Ops[NameIdx]);
+ DIType *BaseType =
+ transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
+ uint64_t OffsetInBits =
+ BM->get<SPIRVConstant>(Ops[OffsetIdx])->getZExtIntValue();
+ SPIRVWord SPIRVFlags =
+ getConstantValueOrLiteral(Ops, FlagsIdx, DebugInst->getExtSetKind());
+ DINode::DIFlags Flags = DINode::FlagZero;
+ if ((SPIRVDebug::FlagAccess & SPIRVFlags) == SPIRVDebug::FlagIsPublic) {
+ Flags |= DINode::FlagPublic;
+ } else if (SPIRVFlags & SPIRVDebug::FlagIsProtected) {
+ Flags |= DINode::FlagProtected;
+ } else if (SPIRVFlags & SPIRVDebug::FlagIsPrivate) {
+ Flags |= DINode::FlagPrivate;
+ }
+ if (SPIRVFlags & SPIRVDebug::FlagIsStaticMember)
+ Flags |= DINode::FlagStaticMember;
+
+ if (Flags & DINode::FlagStaticMember && Ops.size() > MinOperandCount) {
+ SPIRVValue *ConstVal = BM->get<SPIRVValue>(Ops[ValueIdx]);
+ assert(isConstantOpCode(ConstVal->getOpCode()) &&
+ "Static member must be a constant");
+ llvm::Value *Val = SPIRVReader->transValue(ConstVal, nullptr, nullptr);
+ return getDIBuilder(DebugInst).createStaticMemberType(
+ Scope, Name, File, LineNo, BaseType, Flags, cast<llvm::Constant>(Val));
+ }
+ uint64_t Size = BM->get<SPIRVConstant>(Ops[SizeIdx])->getZExtIntValue();
+ uint64_t Alignment = 0;
+
+ return getDIBuilder(ParentInst)
+ .createMemberType(Scope, Name, File, LineNo, Size, Alignment,
+ OffsetInBits, Flags, BaseType);
+}
+
DINode *SPIRVToLLVMDbgTran::transTypeEnum(const SPIRVExtInst *DebugInst) {
using namespace SPIRVDebug::Operand::TypeEnum;
const SPIRVWordVec &Ops = DebugInst->getArguments();
DIStringType *transTypeString(const SPIRVExtInst *DebugInst);
- DINode *transTypeMember(const SPIRVExtInst *DebugInst);
+ DINode *transTypeMember(const SPIRVExtInst *DebugInst,
+ const SPIRVExtInst *ParentInst = nullptr,
+ DIScope *Scope = nullptr);
+ DINode *transTypeMemberOpenCL(const SPIRVExtInst *DebugInst);
+ DINode *transTypeMemberNonSemantic(const SPIRVExtInst *DebugInst,
+ const SPIRVExtInst *ParentInst,
+ DIScope *Scope);
DINode *transTypeEnum(const SPIRVExtInst *DebugInst);
}
namespace TypeMember {
+namespace OpenCL {
enum {
NameIdx = 0,
TypeIdx = 1,
};
}
+namespace NonSemantic {
+enum {
+ NameIdx = 0,
+ TypeIdx = 1,
+ SourceIdx = 2,
+ LineIdx = 3,
+ ColumnIdx = 4,
+ OffsetIdx = 5,
+ SizeIdx = 6,
+ FlagsIdx = 7,
+ ValueIdx = 8,
+ MinOperandCount = 8
+};
+}
+} // namespace TypeMember
+
namespace TypeInheritance {
enum {
ChildIdx = 0,
ParentScopeIdx = TypeEnum::ParentIdx;
return true;
case SPIRVDebug::TypeComposite:
- ParentScopeIdx = TypeMember::ParentIdx;
+ ParentScopeIdx = TypeMember::OpenCL::ParentIdx;
return true;
case SPIRVDebug::TypeInheritance:
ParentScopeIdx = TypeInheritance::ParentIdx;
; CHECK-SPIRV: [[#DINoneId:]] [[#EISId]] DebugInfoNone
; CHECK-SPIRV: [[#DebugFuncId:]] [[#EISId]] DebugFunction
+; CHECK-SPIRV: [[#LocalVarId:]] [[#EISId]] DebugLocalVariable [[#LocalVarNameId]] [[#]] [[#]] [[#]] [[#]] [[#DebugFuncId]]
; CHECK-SPIRV: [[#DebugTypeTemplate:]] [[#EISId]] DebugTypeTemplate [[#DebugFuncId]]
-; CHECK-SPIRV: [[#LocalVarId:]] [[#EISId]] DebugLocalVariable [[#LocalVarNameId]] [[#]] [[#]] [[#]] [[#]] [[#DebugTypeTemplate]]
; CHECK-SPIRV: [[#EISId]] DebugTypeSubrange [[#DINoneId]] [[#Constant1Id]] [[#LocalVarId]] [[#DINoneId]]
; CHECK-SPIRV: [[#DIExprId:]] [[#EISId]] DebugExpression
--- /dev/null
+; RUN: llvm-as < %s -o %t.bc
+; RUN: llvm-spirv %t.bc -o %t.spv -spirv-debug-info-version=nonsemantic-shader-100
+; RUN: llvm-spirv %t.spv --to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
+; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
+
+; RUN: llvm-spirv %t.bc -o %t.spv -spirv-debug-info-version=nonsemantic-shader-200
+; RUN: llvm-spirv %t.spv --to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
+; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
+
+; Generated from:
+;
+; struct A {
+; static int fully_specified;
+; static int smem[];
+; };
+;
+; int A::fully_specified;
+; int A::smem[] = { 0, 1, 2, 3 };
+
+; CHECK-SPIRV: ExtInst [[#]] [[#Member1:]] [[#]] DebugTypeMember [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] {{$}}
+; CHECK-SPIRV: ExtInst [[#]] [[#Member2:]] [[#]] DebugTypeMember [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] {{$}}
+; CHECK-SPIRV: ExtInst [[#]] [[#]] [[#]] DebugTypeComposite [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#Member1]] [[#Member2]]
+; CHECK-SPIRV: ExtInst [[#]] [[#]] [[#]] DebugGlobalVariable [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#Member1]]
+; CHECK-SPIRV: ExtInst [[#]] [[#]] [[#]] DebugGlobalVariable [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#Member2]]
+
+; CHECK-LLVM: ![[#GVExpr1:]] = !DIGlobalVariableExpression(var: ![[#GV1:]], expr: !DIExpression())
+; CHECK-LLVM: ![[#GV1]] = distinct !DIGlobalVariable(name: "fully_specified", linkageName: "_ZN1A15fully_specifiedE", scope: ![[#CU:]], file: ![[#File:]], line: 7, type: ![[#GVTy1:]], isLocal: false, isDefinition: true, declaration: ![[#Decl1:]])
+; CHECK-LLVM: ![[#CU]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus{{.*}}, file: ![[#File:]], {{.*}}, globals: ![[#GVs:]]
+; CHECK-LLVM: ![[#File]] = !DIFile(filename: "static_member_array.cpp", directory: "/Volumes/Data/radar/28706946")
+; CHECK-LLVM: ![[#GVs]] = !{![[#GVExpr1]], ![[#GVExpr2:]]}
+; CHECK-LLVM: ![[#GVExpr2]] = !DIGlobalVariableExpression(var: ![[#GV2:]], expr: !DIExpression())
+; CHECK-LLVM: ![[#GV2]] = distinct !DIGlobalVariable(name: "smem", linkageName: "_ZN1A4smemE", scope: ![[#CU]], file: ![[#File]], line: 8, type: ![[#GVTy2:]], isLocal: false, isDefinition: true, declaration: ![[#Decl2:]])
+; CHECK-LLVM: ![[#GVTy2]] = !DICompositeType(tag: DW_TAG_array_type, baseType: !8, size: 128, elements: ![[#Elements1:]])
+; CHECK-LLVM: ![[#GVTy1]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+; CHECK-LLVM: ![[#Elements1]] = !{![[#Subrange:]]}
+; CHECK-LLVM: ![[#Subrange]] = !DISubrange(count: 4
+; CHECK-LLVM: ![[#MemTy1:]] = !DIDerivedType(tag: DW_TAG_member, name: "smem", scope: ![[#StructTy:]], file: ![[#File]], line: 4, baseType: ![[#ArrTy:]], flags: DIFlagPublic | DIFlagStaticMember)
+; CHECK-LLVM: ![[#StructTy]] = !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: ![[#File]], line: 1, size: 8, elements: ![[#Elements2:]], identifier: "_ZTS1A")
+; CHECK-LLVM: ![[#Elements2]] = !{![[#MemTy2:]], ![[#MemTy1]]}
+; CHECK-LLVM: ![[#MemTy2:]] = !DIDerivedType(tag: DW_TAG_member, name: "fully_specified", scope: ![[#StructTy]], file: ![[#File]], line: 3, baseType: ![[#GVTy1]], flags: DIFlagPublic | DIFlagStaticMember)
+; CHECK-LLVM: ![[#ArrTy]] = !DICompositeType(tag: DW_TAG_array_type, baseType: !8, elements: ![[#]])
+
+
+source_filename = "static_member_array.cpp"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "spir64-unknown-unknown"
+
+@_ZN1A15fully_specifiedE = global i32 0, align 4, !dbg !0
+@_ZN1A4smemE = global [4 x i32] [i32 0, i32 1, i32 2, i32 3], align 16, !dbg !6
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!19, !20, !21}
+!llvm.ident = !{!22}
+
+!0 = distinct !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = !DIGlobalVariable(name: "fully_specified", linkageName: "_ZN1A15fully_specifiedE", scope: !2, file: !3, line: 7, type: !9, isLocal: false, isDefinition: true, declaration: !15)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 4.0.0 (trunk 286129) (llvm/trunk 286128)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "static_member_array.cpp", directory: "/Volumes/Data/radar/28706946")
+!4 = !{}
+!5 = !{!0, !6}
+!6 = distinct !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
+!7 = !DIGlobalVariable(name: "smem", linkageName: "_ZN1A4smemE", scope: !2, file: !3, line: 8, type: !8, isLocal: false, isDefinition: true, declaration: !12)
+!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 128, elements: !10)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !{!11}
+!11 = !DISubrange(count: 4)
+!12 = !DIDerivedType(tag: DW_TAG_member, name: "smem", scope: !13, file: !3, line: 4, baseType: !16, flags: DIFlagStaticMember)
+!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !3, line: 1, size: 8, elements: !14, identifier: "_ZTS1A")
+!14 = !{!15, !12}
+!15 = !DIDerivedType(tag: DW_TAG_member, name: "fully_specified", scope: !13, file: !3, line: 3, baseType: !9, flags: DIFlagStaticMember)
+!16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, elements: !17)
+!17 = !{!18}
+!18 = !DISubrange(count: -1)
+!19 = !{i32 2, !"Dwarf Version", i32 4}
+!20 = !{i32 2, !"Debug Info Version", i32 3}
+!21 = !{i32 1, !"PIC Level", i32 2}
+!22 = !{!"clang version 4.0.0 (trunk 286129) (llvm/trunk 286128)"}
+
; CHECK-SPIRV: Constant [[#TypeInt64Id]] [[#NegativeCount:]] 4294967295 4294967295
; CHECK-SPIRV: [[#DbgFuncId:]] [[#]] DebugFunction [[#FuncNameId]]
+; CHECK-SPIRV: [[#]] [[#DbgLocVarId:]] [[#]] DebugLocalVariable [[#VarNameId]] [[#]] [[#]] [[#]] [[#]] [[#DbgFuncId]]
; CHECK-SPIRV: [[#DbgTemplateId:]] [[#]] DebugTypeTemplate [[#DbgFuncId]]
-; CHECK-SPIRV: [[#]] [[#DbgLocVarId:]] [[#]] DebugLocalVariable [[#VarNameId]] [[#]] [[#]] [[#]] [[#]] [[#DbgTemplateId]]
; CHECK-SPIRV: DebugTypeArray [[#]] [[#DbgLocVarId]] [[#LowerBoundId]]
; CHECK-SPIRV: [[#DbgExprId:]] [[#]] DebugExpression