Skip to content

Commit c6f720f

Browse files
vmaksimoFreddyLeaf
authored andcommitted
Support translation of DIStringType (intel#1877)
This type instruction describes a string, mostly for Fortran 90. Spec: KhronosGroup/SPIRV-Registry#186 Original commit: KhronosGroup/SPIRV-LLVM-Translator@beecd9d
1 parent 82efb93 commit c6f720f

File tree

7 files changed

+241
-1
lines changed

7 files changed

+241
-1
lines changed

llvm-spirv/lib/SPIRV/LLVMToSPIRVDbgTran.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,12 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgEntryImpl(const MDNode *MDN) {
283283
else
284284
return getDebugInfoNone();
285285

286+
case dwarf::DW_TAG_string_type: {
287+
if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100)
288+
return transDbgStringType(cast<DIStringType>(DIEntry));
289+
return getDebugInfoNone();
290+
}
291+
286292
case dwarf::DW_TAG_const_type:
287293
case dwarf::DW_TAG_restrict_type:
288294
case dwarf::DW_TAG_volatile_type:
@@ -731,6 +737,43 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgSubrangeType(const DISubrange *ST) {
731737
return BM->addDebugInfo(SPIRVDebug::TypeSubrange, getVoidTy(), Ops);
732738
}
733739

740+
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgStringType(const DIStringType *ST) {
741+
using namespace SPIRVDebug::Operand::TypeString;
742+
SPIRVWordVec Ops(MinOperandCount);
743+
Ops[NameIdx] = BM->getString(ST->getName().str())->getId();
744+
745+
Ops[BaseTypeIdx] = ST->getEncoding()
746+
? getDebugInfoNoneId() /*TODO: replace with basetype*/
747+
: getDebugInfoNoneId();
748+
749+
auto TransOperand = [&](llvm::Metadata *DIMD) -> SPIRVWord {
750+
if (auto *DIExpr = dyn_cast_or_null<DIExpression>(DIMD))
751+
return transDbgExpression(DIExpr)->getId();
752+
if (auto *DIVar = dyn_cast_or_null<DIVariable>(DIMD)) {
753+
if (const DILocalVariable *LV = dyn_cast<DILocalVariable>(DIVar))
754+
return transDbgLocalVariable(LV)->getId();
755+
if (const DIGlobalVariable *GV = dyn_cast<DIGlobalVariable>(DIVar))
756+
return transDbgGlobalVariable(GV)->getId();
757+
}
758+
return getDebugInfoNoneId();
759+
};
760+
761+
Ops[DataLocationIdx] = TransOperand(ST->getRawStringLocationExp());
762+
763+
ConstantInt *Size = getUInt(M, ST->getSizeInBits());
764+
Ops[SizeIdx] = SPIRVWriter->transValue(Size, nullptr)->getId();
765+
766+
if (auto *StrLengthExp = ST->getRawStringLengthExp()) {
767+
Ops[LengthAddrIdx] = TransOperand(StrLengthExp);
768+
} else if (auto *StrLengthVar = ST->getRawStringLength()) {
769+
Ops[LengthAddrIdx] = TransOperand(StrLengthVar);
770+
} else {
771+
Ops[LengthAddrIdx] = getDebugInfoNoneId();
772+
}
773+
774+
return BM->addDebugInfo(SPIRVDebug::TypeString, getVoidTy(), Ops);
775+
}
776+
734777
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgTypeDef(const DIDerivedType *DT) {
735778
using namespace SPIRVDebug::Operand::Typedef;
736779
SPIRVWordVec Ops(OperandCount);

llvm-spirv/lib/SPIRV/LLVMToSPIRVDbgTran.h

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class LLVMToSPIRVDbgTran {
109109
SPIRVEntry *transDbgArrayTypeNonSemantic(const DICompositeType *AT);
110110
SPIRVEntry *transDbgArrayTypeDynamic(const DICompositeType *AT);
111111
SPIRVEntry *transDbgSubrangeType(const DISubrange *ST);
112+
SPIRVEntry *transDbgStringType(const DIStringType *ST);
112113
SPIRVEntry *transDbgTypeDef(const DIDerivedType *D);
113114
SPIRVEntry *transDbgSubroutineType(const DISubroutineType *FT);
114115
SPIRVEntry *transDbgEnumType(const DICompositeType *ET);

llvm-spirv/lib/SPIRV/SPIRVToLLVMDbgTran.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,50 @@ SPIRVToLLVMDbgTran::transTypeSubrange(const SPIRVExtInst *DebugInst) {
450450
TranslatedOps[2], TranslatedOps[3]);
451451
}
452452

453+
DIStringType *
454+
SPIRVToLLVMDbgTran::transTypeString(const SPIRVExtInst *DebugInst) {
455+
using namespace SPIRVDebug::Operand::TypeString;
456+
const SPIRVWordVec &Ops = DebugInst->getArguments();
457+
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
458+
459+
StringRef Name = getString(Ops[NameIdx]);
460+
unsigned Encoding = 0;
461+
if (!getDbgInst<SPIRVDebug::DebugInfoNone>((Ops[BaseTypeIdx]))) {
462+
DIBasicType *BaseTy =
463+
transTypeBasic(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
464+
Encoding = BaseTy->getEncoding();
465+
}
466+
467+
DIExpression *StrLocationExp = nullptr;
468+
if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[DataLocationIdx])) {
469+
if (const auto *DIExpr =
470+
getDbgInst<SPIRVDebug::Expression>(Ops[DataLocationIdx]))
471+
StrLocationExp = transDebugInst<DIExpression>(DIExpr);
472+
}
473+
474+
uint64_t SizeInBits = BM->get<SPIRVConstant>(Ops[SizeIdx])->getZExtIntValue();
475+
476+
DIExpression *StringLengthExp = nullptr;
477+
DIVariable *StringLengthVar = nullptr;
478+
if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[LengthAddrIdx])) {
479+
if (const auto *GV =
480+
getDbgInst<SPIRVDebug::GlobalVariable>(Ops[LengthAddrIdx]))
481+
StringLengthVar = transDebugInst<DIGlobalVariable>(GV);
482+
if (const auto *LV =
483+
getDbgInst<SPIRVDebug::LocalVariable>(Ops[LengthAddrIdx]))
484+
StringLengthVar = transDebugInst<DILocalVariable>(LV);
485+
if (const auto *DIExpr =
486+
getDbgInst<SPIRVDebug::Expression>(Ops[LengthAddrIdx]))
487+
StringLengthExp = transDebugInst<DIExpression>(DIExpr);
488+
}
489+
490+
return DIStringType::get(M->getContext(), dwarf::DW_TAG_string_type, Name,
491+
cast_or_null<Metadata>(StringLengthVar),
492+
cast_or_null<Metadata>(StringLengthExp),
493+
cast_or_null<Metadata>(StrLocationExp), SizeInBits,
494+
0 /*AlignInBits*/, Encoding);
495+
}
496+
453497
DINode *SPIRVToLLVMDbgTran::transTypeMember(const SPIRVExtInst *DebugInst) {
454498
using namespace SPIRVDebug::Operand::TypeMember;
455499
const SPIRVWordVec &Ops = DebugInst->getArguments();
@@ -1008,6 +1052,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) {
10081052
case SPIRVDebug::TypeSubrange:
10091053
return transTypeSubrange(DebugInst);
10101054

1055+
case SPIRVDebug::TypeString:
1056+
return transTypeString(DebugInst);
1057+
10111058
case SPIRVDebug::TypeVector:
10121059
return transTypeVector(DebugInst);
10131060

llvm-spirv/lib/SPIRV/SPIRVToLLVMDbgTran.h

+2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ class SPIRVToLLVMDbgTran {
122122

123123
DISubrange *transTypeSubrange(const SPIRVExtInst *DebugInst);
124124

125+
DIStringType *transTypeString(const SPIRVExtInst *DebugInst);
126+
125127
DINode *transTypeMember(const SPIRVExtInst *DebugInst);
126128

127129
DINode *transTypeEnum(const SPIRVExtInst *DebugInst);

llvm-spirv/lib/SPIRV/libSPIRV/SPIRV.debug.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ enum Instruction {
5353
ModuleINTEL = 36,
5454
InstCount = 37,
5555
TypeSubrange = 110,
56-
TypeArrayDynamic = 202
56+
TypeArrayDynamic = 202,
57+
TypeString = 203
5758
};
5859

5960
enum Flag {
@@ -355,6 +356,18 @@ enum {
355356
};
356357
}
357358

359+
namespace TypeString {
360+
enum {
361+
NameIdx = 0,
362+
BaseTypeIdx = 1,
363+
DataLocationIdx = 2,
364+
SizeIdx = 3,
365+
LengthAddrIdx = 4,
366+
LengthSizeIdx = 5,
367+
MinOperandCount = 5
368+
};
369+
}
370+
358371
namespace Typedef {
359372
enum {
360373
NameIdx = 0,

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVExtInst.h

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ template <> inline void SPIRVMap<SPIRVDebugExtOpKind, std::string>::init() {
241241
add(SPIRVDebug::TypeTemplate, "DebugTemplate");
242242
add(SPIRVDebug::TypePtrToMember, "DebugTypePtrToMember,");
243243
add(SPIRVDebug::TypeSubrange, "DebugTypeSubrange");
244+
add(SPIRVDebug::TypeString, "DebugTypeString");
244245
add(SPIRVDebug::Inheritance, "DebugInheritance");
245246
add(SPIRVDebug::Function, "DebugFunction");
246247
add(SPIRVDebug::FunctionDecl, "DebugFunctionDecl");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv -spirv-text %t.bc -o %t.spt --spirv-debug-info-version=nonsemantic-kernel-100
3+
; RUN: FileCheck < %t.spt %s -check-prefix=CHECK-SPIRV
4+
; RUN: llvm-spirv -to-binary %t.spt -o %t.spv
5+
6+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
7+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
8+
; RUN: FileCheck < %t.rev.ll %s -check-prefix=CHECK-LLVM
9+
10+
; CHECK-SPIRV: ExtInstImport [[#EISId:]] "NonSemantic.Kernel.DebugInfo.100"
11+
; CHECK-SPIRV: String [[#StrGreet:]] ".str.GREETING"
12+
; CHECK-SPIRV: String [[#StrChar1:]] "CHARACTER_1"
13+
; CHECK-SPIRV: String [[#StrChar2:]] "CHARACTER_2"
14+
; CHECK-SPIRV: String [[#StrChar3:]] "CHARACTER_3"
15+
; CHECK-SPIRV: TypeInt [[#TypeInt:]] 32 0
16+
; CHECK-SPIRV: Constant [[#TypeInt]] [[#ConstZero:]] 0
17+
; CHECK-SPIRV: Constant [[#TypeInt]] [[#Const80:]] 80
18+
; CHECK-SPIRV: TypeVoid [[#TypeVoid:]]
19+
20+
; CHECK-SPIRV: [[#DINoneId:]] [[#EISId]] DebugInfoNone
21+
; CHECK-SPIRV: [[#DataLocExpr:]] [[#EISId]] DebugExpression [[#]] [[#]] {{$}}
22+
; CHECK-SPIRV: [[#LengthAddrExpr:]] [[#EISId]] DebugExpression [[#]] [[#]] {{$}}
23+
24+
; DebugTypeString NameId BaseTyId DataLocId SizeId LengthAddrId
25+
; CHECK-SPIRV: [[#EISId]] DebugTypeString [[#StrGreet]] [[#DINoneId]] [[#DataLocExpr]] [[#ConstZero]] [[#LengthAddrExpr]]
26+
; CHECK-SPIRV: [[#EISId]] DebugTypeString [[#StrChar1]] [[#DINoneId]] [[#DINoneId]] [[#Const80]] [[#DINoneId]]
27+
28+
; CHECK-SPIRV-COUNT-2: [[#LengthAddrVar:]] [[#EISId]] DebugLocalVariable
29+
; CHECK-SPIRV-NEXT: [[#EISId]] DebugTypeString [[#StrChar2]] [[#DINoneId]] [[#DINoneId]] [[#ConstZero]] [[#LengthAddrVar]]
30+
; CHECK-SPIRV-COUNT-3: [[#LengthAddrVar1:]] [[#EISId]] DebugLocalVariable
31+
; CHECK-SPIRV-NEXT: [[#EISId]] DebugTypeString [[#StrChar3]] [[#DINoneId]] [[#DINoneId]] [[#ConstZero]] [[#LengthAddrVar1]]
32+
; CHECK-SPIRV-COUNT-4: [[#LengthAddrVar2:]] [[#EISId]] DebugLocalVariable
33+
; CHECK-SPIRV-NEXT: [[#EISId]] DebugTypeString [[#StrChar2]] [[#DINoneId]] [[#DINoneId]] [[#ConstZero]] [[#LengthAddrVar2]]
34+
35+
; CHECK-LLVM: !DICompileUnit(language: DW_LANG_Fortran95
36+
; CHECK-LLVM-DAG: !DIStringType(name: "CHARACTER_1", size: 80)
37+
; CHECK-LLVM-DAG: !DIStringType(name: ".str.GREETING", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
38+
; CHECK-LLVM-DAG: ![[#Scope:]] = distinct !DISubprogram(name: "print_greeting", linkageName: "print_greeting_"
39+
; CHECK-LLVM-DAG: ![[#StrLenMD:]] = !DILocalVariable(name: "STRING1.len", scope: ![[#Scope]]
40+
; CHECK-LLVM-DAG: !DIStringType(name: "CHARACTER_2", stringLength: ![[#StrLenMD]])
41+
; CHECK-LLVM-DAG: ![[#StrLenMD1:]] = !DILocalVariable(name: "STRING2.len", scope: ![[#Scope]]
42+
; CHECK-LLVM-DAG: !DIStringType(name: "CHARACTER_3", stringLength: ![[#StrLenMD1]])
43+
44+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
45+
target triple = "spir64-unknown-unknown"
46+
47+
%"QNCA_a0$i8*$rank0$" = type { ptr, i64, i64, i64, i64, i64 }
48+
49+
@strlit = internal unnamed_addr constant [5 x i8] c"HELLO"
50+
@strlit.1 = internal unnamed_addr constant [3 x i8] c"TOM"
51+
@"hello_world_$GREETING" = internal global %"QNCA_a0$i8*$rank0$" zeroinitializer, !dbg !2
52+
@"hello_world_$NAME" = internal global [10 x i8] zeroinitializer, align 1, !dbg !10
53+
@0 = internal unnamed_addr constant i32 65536, align 4
54+
@1 = internal unnamed_addr constant i32 2, align 4
55+
@strlit.2 = internal unnamed_addr constant [2 x i8] c", "
56+
57+
; Function Attrs: nounwind uwtable
58+
define void @MAIN__() local_unnamed_addr #0 !dbg !4{
59+
%"hello_world_$GREETING_fetch.16" = load ptr, ptr @"hello_world_$GREETING", align 16, !dbg !20
60+
%fetch.15 = load i64, ptr getelementptr inbounds (%"QNCA_a0$i8*$rank0$", ptr @"hello_world_$GREETING", i64 0, i32 1), align 8, !dbg !20
61+
call void @llvm.dbg.value(metadata i64 %fetch.15, metadata !24, metadata !DIExpression()), !dbg !21
62+
call void @llvm.dbg.value(metadata i64 %fetch.15, metadata !31, metadata !DIExpression()), !dbg !21
63+
call void @llvm.dbg.value(metadata i64 10, metadata !28, metadata !DIExpression()), !dbg !21
64+
call void @llvm.dbg.value(metadata i64 10, metadata !32, metadata !DIExpression()), !dbg !21
65+
call void @llvm.dbg.declare(metadata ptr %"hello_world_$GREETING_fetch.16", metadata !26, metadata !DIExpression()), !dbg !36
66+
call void @llvm.dbg.declare(metadata ptr @"hello_world_$NAME", metadata !29, metadata !DIExpression()), !dbg !37
67+
ret void, !dbg !38
68+
}
69+
70+
; Function Attrs: nofree nounwind uwtable
71+
define void @print_greeting_(ptr noalias readonly %"print_greeting_$STRING1", ptr noalias readonly %"print_greeting_$STRING2", i64 %"STRING1.len$val", i64 %"STRING2.len$val") local_unnamed_addr #1 !dbg !22 {
72+
alloca_1:
73+
call void @llvm.dbg.value(metadata i64 %"STRING1.len$val", metadata !24, metadata !DIExpression()), !dbg !39
74+
call void @llvm.dbg.value(metadata i64 %"STRING1.len$val", metadata !31, metadata !DIExpression()), !dbg !39
75+
call void @llvm.dbg.value(metadata i64 %"STRING2.len$val", metadata !28, metadata !DIExpression()), !dbg !39
76+
call void @llvm.dbg.value(metadata i64 %"STRING2.len$val", metadata !32, metadata !DIExpression()), !dbg !39
77+
call void @llvm.dbg.declare(metadata ptr %"print_greeting_$STRING1", metadata !26, metadata !DIExpression()), !dbg !40
78+
call void @llvm.dbg.declare(metadata ptr %"print_greeting_$STRING2", metadata !29, metadata !DIExpression()), !dbg !41
79+
ret void, !dbg !42
80+
}
81+
82+
; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
83+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
84+
85+
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
86+
declare void @llvm.dbg.value(metadata, metadata, metadata) #3
87+
88+
attributes #0 = { nounwind uwtable }
89+
attributes #1 = { nofree nounwind uwtable}
90+
attributes #2 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) }
91+
attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
92+
93+
!llvm.module.flags = !{!18, !19}
94+
!llvm.dbg.cu = !{!8}
95+
96+
!2 = !DIGlobalVariableExpression(var: !3, expr: !DIExpression())
97+
!3 = distinct !DIGlobalVariable(name: "greeting", linkageName: "hello_world_$GREETING", scope: !4, file: !5, line: 3, type: !14, isLocal: true, isDefinition: true)
98+
!4 = distinct !DISubprogram(name: "hello_world", linkageName: "MAIN__", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !8, retainedNodes: !13)
99+
!5 = !DIFile(filename: "hello.f90", directory: "/dev/null")
100+
!6 = !DISubroutineType(types: !7)
101+
!7 = !{null}
102+
!8 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !5, producer: "fortran", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None)
103+
!9 = !{!2, !10}
104+
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
105+
!11 = distinct !DIGlobalVariable(name: "name", linkageName: "hello_world_$NAME", scope: !4, file: !5, line: 2, type: !12, isLocal: true, isDefinition: true)
106+
!12 = !DIStringType(name: "CHARACTER_1", size: 80)
107+
!13 = !{}
108+
!14 = !DIStringType(name: ".str.GREETING", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
109+
!18 = !{i32 2, !"Debug Info Version", i32 3}
110+
!19 = !{i32 2, !"Dwarf Version", i32 4}
111+
!20 = !DILocation(line: 6, column: 23, scope: !4)
112+
!21 = !DILocation(line: 0, scope: !22, inlinedAt: !33)
113+
!22 = distinct !DISubprogram(name: "print_greeting", linkageName: "print_greeting_", scope: !5, file: !5, line: 9, type: !6, scopeLine: 9, spFlags: DISPFlagDefinition, unit: !8, retainedNodes: !23)
114+
!23 = !{!24, !26, !28, !29, !31, !32}
115+
!24 = !DILocalVariable(name: "STRING1.len", scope: !22, type: !25, flags: DIFlagArtificial)
116+
!25 = !DIBasicType(name: "INTEGER*8", size: 64, encoding: DW_ATE_signed)
117+
!26 = !DILocalVariable(name: "string1", arg: 1, scope: !22, file: !5, line: 9, type: !27)
118+
!27 = !DIStringType(name: "CHARACTER_2", stringLength: !24)
119+
!28 = !DILocalVariable(name: "STRING2.len", scope: !22, type: !25, flags: DIFlagArtificial)
120+
!29 = !DILocalVariable(name: "string2", arg: 2, scope: !22, file: !5, line: 9, type: !30)
121+
!30 = !DIStringType(name: "CHARACTER_3", stringLength: !28)
122+
!31 = !DILocalVariable(name: "_string1", arg: 3, scope: !22, type: !25, flags: DIFlagArtificial)
123+
!32 = !DILocalVariable(name: "_string2", arg: 4, scope: !22, type: !25, flags: DIFlagArtificial)
124+
!33 = distinct !DILocation(line: 0, scope: !34, inlinedAt: !35)
125+
!34 = distinct !DISubprogram(name: "print_greeting_.t60p.t61p.t3v.t3v", linkageName: "print_greeting_.t60p.t61p.t3v.t3v", scope: !5, file: !5, type: !6, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !8, retainedNodes: !13, targetFuncName: "print_greeting_")
126+
!35 = distinct !DILocation(line: 6, column: 8, scope: !4)
127+
!36 = !DILocation(line: 9, column: 27, scope: !22, inlinedAt: !33)
128+
!37 = !DILocation(line: 9, column: 36, scope: !22, inlinedAt: !33)
129+
!38 = !DILocation(line: 7, column: 1, scope: !4)
130+
!39 = !DILocation(line: 0, scope: !22)
131+
!40 = !DILocation(line: 9, column: 27, scope: !22)
132+
!41 = !DILocation(line: 9, column: 36, scope: !22)
133+
!42 = !DILocation(line: 12, column: 1, scope: !22)

0 commit comments

Comments
 (0)