Skip to content

Commit c995c50

Browse files
jmorseOCHyams
andauthored
[KeyInstr] Add bitcode support (#147260)
Serialise key-instruction fields of DILocations and DISubprograms into and outof bitcode, add tests. debug-info bitcode sizes grow, but it balances out given an earlier size optimisation in 51f4e2c. Co-authored-by: Orlando Cazalet-Hyams <[email protected]>
1 parent 7a6435b commit c995c50

File tree

5 files changed

+149
-15
lines changed

5 files changed

+149
-15
lines changed

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5084,7 +5084,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
50845084

50855085
unsigned Line = Record[0], Col = Record[1];
50865086
unsigned ScopeID = Record[2], IAID = Record[3];
5087-
bool isImplicitCode = Record.size() == 5 && Record[4];
5087+
bool isImplicitCode = Record.size() >= 5 && Record[4];
5088+
uint64_t AtomGroup = Record.size() == 7 ? Record[5] : 0;
5089+
uint8_t AtomRank = Record.size() == 7 ? Record[6] : 0;
50885090

50895091
MDNode *Scope = nullptr, *IA = nullptr;
50905092
if (ScopeID) {
@@ -5099,8 +5101,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
50995101
if (!IA)
51005102
return error("Invalid record");
51015103
}
5104+
51025105
LastLoc = DILocation::get(Scope->getContext(), Line, Col, Scope, IA,
5103-
isImplicitCode);
5106+
isImplicitCode, AtomGroup, AtomRank);
51045107
I->setDebugLoc(LastLoc);
51055108
I = nullptr;
51065109
continue;

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,18 +1426,21 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
14261426
break;
14271427
}
14281428
case bitc::METADATA_LOCATION: {
1429-
if (Record.size() != 5 && Record.size() != 6)
1429+
// 5: inlinedAt, 6: isImplicit, 8: Key Instructions fields.
1430+
if (Record.size() != 5 && Record.size() != 6 && Record.size() != 8)
14301431
return error("Invalid record");
14311432

14321433
IsDistinct = Record[0];
14331434
unsigned Line = Record[1];
14341435
unsigned Column = Record[2];
14351436
Metadata *Scope = getMD(Record[3]);
14361437
Metadata *InlinedAt = getMDOrNull(Record[4]);
1437-
bool ImplicitCode = Record.size() == 6 && Record[5];
1438+
bool ImplicitCode = Record.size() >= 6 && Record[5];
1439+
uint64_t AtomGroup = Record.size() == 8 ? Record[6] : 0;
1440+
uint8_t AtomRank = Record.size() == 8 ? Record[7] : 0;
14381441
MetadataList.assignValue(
14391442
GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt,
1440-
ImplicitCode)),
1443+
ImplicitCode, AtomGroup, AtomRank)),
14411444
NextMetadataNo);
14421445
NextMetadataNo++;
14431446
break;
@@ -1890,7 +1893,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
18901893
break;
18911894
}
18921895
case bitc::METADATA_SUBPROGRAM: {
1893-
if (Record.size() < 18 || Record.size() > 21)
1896+
if (Record.size() < 18 || Record.size() > 22)
18941897
return error("Invalid record");
18951898

18961899
bool HasSPFlags = Record[0] & 4;
@@ -1942,6 +1945,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
19421945
bool HasTargetFuncName = false;
19431946
unsigned OffsetA = 0;
19441947
unsigned OffsetB = 0;
1948+
// Key instructions won't be enabled in old-format bitcode, so only
1949+
// check it if HasSPFlags is true.
1950+
bool UsesKeyInstructions = false;
19451951
if (!HasSPFlags) {
19461952
OffsetA = 2;
19471953
OffsetB = 2;
@@ -1954,7 +1960,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
19541960
} else {
19551961
HasAnnotations = Record.size() >= 19;
19561962
HasTargetFuncName = Record.size() >= 20;
1963+
UsesKeyInstructions = Record.size() >= 21 ? Record[20] : 0;
19571964
}
1965+
19581966
Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]);
19591967
DISubprogram *SP = GET_OR_DISTINCT(
19601968
DISubprogram,
@@ -1980,8 +1988,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
19801988
HasAnnotations ? getMDOrNull(Record[18 + OffsetB])
19811989
: nullptr, // annotations
19821990
HasTargetFuncName ? getMDString(Record[19 + OffsetB])
1983-
: nullptr // targetFuncName
1984-
));
1991+
: nullptr, // targetFuncName
1992+
UsesKeyInstructions));
19851993
MetadataList.assignValue(SP, NextMetadataNo);
19861994
NextMetadataNo++;
19871995

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,12 +1807,14 @@ unsigned ModuleBitcodeWriter::createDILocationAbbrev() {
18071807
// location (it's never more expensive than building an array size 1).
18081808
auto Abbv = std::make_shared<BitCodeAbbrev>();
18091809
Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
1810-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1811-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1812-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1813-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1814-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1815-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1810+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isDistinct
1811+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // line
1812+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // column
1813+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // scope
1814+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // inlinedAt
1815+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImplicitCode
1816+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // atomGroup
1817+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // atomRank
18161818
return Stream.EmitAbbrev(std::move(Abbv));
18171819
}
18181820

@@ -1828,7 +1830,8 @@ void ModuleBitcodeWriter::writeDILocation(const DILocation *N,
18281830
Record.push_back(VE.getMetadataID(N->getScope()));
18291831
Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
18301832
Record.push_back(N->isImplicitCode());
1831-
1833+
Record.push_back(N->getAtomGroup());
1834+
Record.push_back(N->getAtomRank());
18321835
Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
18331836
Record.clear();
18341837
}
@@ -2156,6 +2159,7 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N,
21562159
Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get()));
21572160
Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
21582161
Record.push_back(VE.getMetadataOrNullID(N->getRawTargetFuncName()));
2162+
Record.push_back(N->getKeyInstructionsEnabled());
21592163

21602164
Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev);
21612165
Record.clear();
@@ -3748,6 +3752,8 @@ void ModuleBitcodeWriter::writeFunction(
37483752
Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
37493753
Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
37503754
Vals.push_back(DL->isImplicitCode());
3755+
Vals.push_back(DL->getAtomGroup());
3756+
Vals.push_back(DL->getAtomRank());
37513757
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals,
37523758
FUNCTION_DEBUG_LOC_ABBREV);
37533759
Vals.clear();
@@ -4142,6 +4148,8 @@ void ModuleBitcodeWriter::writeBlockInfo() {
41424148
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
41434149
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
41444150
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
4151+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Atom group.
4152+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3)); // Atom rank.
41454153
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
41464154
FUNCTION_DEBUG_LOC_ABBREV)
41474155
llvm_unreachable("Unexpected abbrev ordering!");
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
; RUN: split-file %s %t
2+
; RUN: llvm-as %t/key-instr-enabled.ll -o %t/key-instr-enabled.bc
3+
; RUN: llvm-as %t/key-instr-disabled.ll -o %t/key-instr-disabled.bc
4+
; RUN: llvm-link %t/key-instr-enabled.bc %t/key-instr-disabled.bc -o - | llvm-dis | FileCheck %s
5+
6+
;; Check the Key Instructions metadata is preserved correctly when linking a
7+
;; modules with Key Instructions enabled/disabled.
8+
9+
;; Key Instructions enabled.
10+
; CHECK: void @f() !dbg [[f:!.*]] {
11+
; CHECK-NEXT: entry:
12+
; CHECK-NEXT: ret void, !dbg [[enabled:!.*]]
13+
; CHECK-NEXT: }
14+
15+
;; Key Instructions disabled.
16+
; CHECK: void @g() !dbg [[g:!.*]] {
17+
; CHECK-NEXT: entry:
18+
; CHECK-NEXT: ret void, !dbg [[disabled:!.*]]
19+
; CHECK-NEXT: }
20+
21+
; CHECK: !llvm.dbg.cu = !{!0, !2}
22+
; CHECK-NEXT: !llvm.module.flags = !{!4}
23+
24+
; CHECK: [[file1:!.*]] = !DIFile(filename: "key-instr-enabled.cpp", directory: "/")
25+
; CHECK: [[file2:!.*]] = !DIFile(filename: "key-instr-disabled.cpp", directory: "/")
26+
; CHECK: [[f]] = distinct !DISubprogram(name: "f", scope: [[file1]]{{.*}}, keyInstructions: true)
27+
; CHECK: [[enabled]] = !DILocation(line: 1, column: 11, scope: [[f]], atomGroup: 1, atomRank: 1)
28+
; CHECK: [[g]] = distinct !DISubprogram(name: "g", scope: [[file2]]
29+
; CHECK-NOT: keyInstructions
30+
; CHECK-SAME: )
31+
; CHECK: [[disabled]] = !DILocation(line: 1, column: 11, scope: [[g]])
32+
33+
;--- key-instr-enabled.ll
34+
define dso_local void @f() !dbg !10 {
35+
entry:
36+
ret void, !dbg !13
37+
}
38+
39+
!llvm.dbg.cu = !{!0}
40+
!llvm.module.flags = !{!3}
41+
42+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
43+
!1 = !DIFile(filename: "key-instr-enabled.cpp", directory: "/")
44+
!3 = !{i32 2, !"Debug Info Version", i32 3}
45+
!9 = !{!"clang version 21.0.0git"}
46+
!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: true)
47+
!11 = !DISubroutineType(types: !12)
48+
!12 = !{null}
49+
!13 = !DILocation(line: 1, column: 11, scope: !10, atomGroup: 1, atomRank: 1)
50+
51+
;--- key-instr-disabled.ll
52+
define dso_local void @g() !dbg !10 {
53+
entry:
54+
ret void, !dbg !13
55+
}
56+
57+
!llvm.dbg.cu = !{!0}
58+
!llvm.module.flags = !{!3}
59+
60+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
61+
!1 = !DIFile(filename: "key-instr-disabled.cpp", directory: "/")
62+
!3 = !{i32 2, !"Debug Info Version", i32 3}
63+
!9 = !{!"clang version 21.0.0git"}
64+
!10 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: false)
65+
!11 = !DISubroutineType(types: !12)
66+
!12 = !{null}
67+
!13 = !DILocation(line: 1, column: 11, scope: !10)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt %s -o - -S | llvm-as - | llvm-dis - | FileCheck %s
3+
4+
; Key Instructions enabled.
5+
define dso_local void @f() !dbg !10 {
6+
; CHECK-LABEL: define dso_local void @f(
7+
; CHECK-SAME: ) !dbg [[DBG3:![0-9]+]] {
8+
; CHECK-NEXT: [[ENTRY:.*:]]
9+
; CHECK-NEXT: ret void, !dbg [[DBG6:![0-9]+]]
10+
;
11+
entry:
12+
ret void, !dbg !13
13+
}
14+
15+
; Key Instructions disabled.
16+
define dso_local void @g() !dbg !14 {
17+
; CHECK-LABEL: define dso_local void @g(
18+
; CHECK-SAME: ) !dbg [[DBG7:![0-9]+]] {
19+
; CHECK-NEXT: [[ENTRY:.*:]]
20+
; CHECK-NEXT: ret void, !dbg [[DBG8:![0-9]+]]
21+
;
22+
entry:
23+
ret void, !dbg !15
24+
}
25+
26+
!llvm.dbg.cu = !{!0}
27+
!llvm.module.flags = !{!3}
28+
29+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
30+
!1 = !DIFile(filename: "key-instr.cpp", directory: "/")
31+
!3 = !{i32 2, !"Debug Info Version", i32 3}
32+
!9 = !{!"clang version 21.0.0git"}
33+
!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: true)
34+
!11 = !DISubroutineType(types: !12)
35+
!12 = !{null}
36+
!13 = !DILocation(line: 1, scope: !10, atomGroup: 1, atomRank: 1)
37+
!14 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 2, type: !11, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: false)
38+
!15 = !DILocation(line: 2, scope: !14)
39+
;.
40+
; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
41+
; CHECK: [[META1]] = !DIFile(filename: "{{.*}}key-instr.cpp", directory: {{.*}})
42+
; CHECK: [[DBG3]] = distinct !DISubprogram(name: "f", scope: [[META1]], file: [[META1]], line: 1, type: [[META4:![0-9]+]], scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], keyInstructions: true)
43+
; CHECK: [[META4]] = !DISubroutineType(types: [[META5:![0-9]+]])
44+
; CHECK: [[META5]] = !{null}
45+
; CHECK: [[DBG6]] = !DILocation(line: 1, scope: [[DBG3]], atomGroup: 1, atomRank: 1)
46+
; CHECK: [[DBG7]] = distinct !DISubprogram(name: "g", scope: [[META1]], file: [[META1]], line: 2, type: [[META4]], scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]])
47+
; CHECK: [[DBG8]] = !DILocation(line: 2, scope: [[DBG7]])
48+
;.

0 commit comments

Comments
 (0)