diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index fde934fbb3cf1..5f24aac2eb975 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5082,7 +5082,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned Line = Record[0], Col = Record[1]; unsigned ScopeID = Record[2], IAID = Record[3]; - bool isImplicitCode = Record.size() == 5 && Record[4]; + bool isImplicitCode = Record.size() >= 5 && Record[4]; + uint64_t AtomGroup = Record.size() == 7 ? Record[5] : 0; + uint8_t AtomRank = Record.size() == 7 ? Record[6] : 0; MDNode *Scope = nullptr, *IA = nullptr; if (ScopeID) { @@ -5097,8 +5099,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (!IA) return error("Invalid record"); } + LastLoc = DILocation::get(Scope->getContext(), Line, Col, Scope, IA, - isImplicitCode); + isImplicitCode, AtomGroup, AtomRank); I->setDebugLoc(LastLoc); I = nullptr; continue; diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 1cd1797c1092d..538a93b168410 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1416,7 +1416,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_LOCATION: { - if (Record.size() != 5 && Record.size() != 6) + // 5: inlinedAt, 6: isImplicit, 8: Key Instructions fields. + if (Record.size() != 5 && Record.size() != 6 && Record.size() != 8) return error("Invalid record"); IsDistinct = Record[0]; @@ -1424,10 +1425,12 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( unsigned Column = Record[2]; Metadata *Scope = getMD(Record[3]); Metadata *InlinedAt = getMDOrNull(Record[4]); - bool ImplicitCode = Record.size() == 6 && Record[5]; + bool ImplicitCode = Record.size() >= 6 && Record[5]; + uint64_t AtomGroup = Record.size() == 8 ? Record[6] : 0; + uint8_t AtomRank = Record.size() == 8 ? Record[7] : 0; MetadataList.assignValue( GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt, - ImplicitCode)), + ImplicitCode, AtomGroup, AtomRank)), NextMetadataNo); NextMetadataNo++; break; @@ -1857,7 +1860,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_SUBPROGRAM: { - if (Record.size() < 18 || Record.size() > 21) + if (Record.size() < 18 || Record.size() > 22) return error("Invalid record"); bool HasSPFlags = Record[0] & 4; @@ -1909,6 +1912,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( bool HasTargetFuncName = false; unsigned OffsetA = 0; unsigned OffsetB = 0; + // Key instructions won't be enabled in old-format bitcode, so only + // check it if HasSPFlags is true. + bool UsesKeyInstructions = false; if (!HasSPFlags) { OffsetA = 2; OffsetB = 2; @@ -1921,7 +1927,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( } else { HasAnnotations = Record.size() >= 19; HasTargetFuncName = Record.size() >= 20; + UsesKeyInstructions = Record.size() >= 21 ? Record[20] : 0; } + Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]); DISubprogram *SP = GET_OR_DISTINCT( DISubprogram, @@ -1947,8 +1955,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( HasAnnotations ? getMDOrNull(Record[18 + OffsetB]) : nullptr, // annotations HasTargetFuncName ? getMDString(Record[19 + OffsetB]) - : nullptr // targetFuncName - )); + : nullptr, // targetFuncName + UsesKeyInstructions)); MetadataList.assignValue(SP, NextMetadataNo); NextMetadataNo++; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 628b939af19ce..5afcc283c315a 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1799,12 +1799,14 @@ unsigned ModuleBitcodeWriter::createDILocationAbbrev() { // location (it's never more expensive than building an array size 1). auto Abbv = std::make_shared(); Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isDistinct + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // line + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // column + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // scope + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // inlinedAt + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImplicitCode + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // atomGroup + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // atomRank return Stream.EmitAbbrev(std::move(Abbv)); } @@ -1820,7 +1822,8 @@ void ModuleBitcodeWriter::writeDILocation(const DILocation *N, Record.push_back(VE.getMetadataID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt())); Record.push_back(N->isImplicitCode()); - + Record.push_back(N->getAtomGroup()); + Record.push_back(N->getAtomRank()); Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev); Record.clear(); } @@ -2141,6 +2144,7 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N, Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get())); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); Record.push_back(VE.getMetadataOrNullID(N->getRawTargetFuncName())); + Record.push_back(N->getKeyInstructionsEnabled()); Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); Record.clear(); @@ -3717,6 +3721,8 @@ void ModuleBitcodeWriter::writeFunction( Vals.push_back(VE.getMetadataOrNullID(DL->getScope())); Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt())); Vals.push_back(DL->isImplicitCode()); + Vals.push_back(DL->getAtomGroup()); + Vals.push_back(DL->getAtomRank()); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); Vals.clear(); LastDL = DL; diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/link-two-modes.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/link-two-modes.ll new file mode 100644 index 0000000000000..104d75d8648b6 --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/link-two-modes.ll @@ -0,0 +1,67 @@ +; RUN: split-file %s %t +; RUN: llvm-as %t/key-instr-enabled.ll -o %t/key-instr-enabled.bc +; RUN: llvm-as %t/key-instr-disabled.ll -o %t/key-instr-disabled.bc +; RUN: llvm-link %t/key-instr-enabled.bc %t/key-instr-disabled.bc -o - | llvm-dis | FileCheck %s + +;; Check the Key Instructions metadata is preserved correctly when linking a +;; modules with Key Instructions enabled/disabled. + +;; Key Instructions enabled. +; CHECK: void @f() !dbg [[f:!.*]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret void, !dbg [[enabled:!.*]] +; CHECK-NEXT: } + +;; Key Instructions disabled. +; CHECK: void @g() !dbg [[g:!.*]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret void, !dbg [[disabled:!.*]] +; CHECK-NEXT: } + +; CHECK: !llvm.dbg.cu = !{!0, !2} +; CHECK-NEXT: !llvm.module.flags = !{!4} + +; CHECK: [[file1:!.*]] = !DIFile(filename: "key-instr-enabled.cpp", directory: "/") +; CHECK: [[file2:!.*]] = !DIFile(filename: "key-instr-disabled.cpp", directory: "/") +; CHECK: [[f]] = distinct !DISubprogram(name: "f", scope: [[file1]]{{.*}}, keyInstructions: true) +; CHECK: [[enabled]] = !DILocation(line: 1, column: 11, scope: [[f]], atomGroup: 1, atomRank: 1) +; CHECK: [[g]] = distinct !DISubprogram(name: "g", scope: [[file2]] +; CHECK-NOT: keyInstructions +; CHECK-SAME: ) +; CHECK: [[disabled]] = !DILocation(line: 1, column: 11, scope: [[g]]) + +;--- key-instr-enabled.ll +define dso_local void @f() !dbg !10 { +entry: + ret void, !dbg !13 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3} + +!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) +!1 = !DIFile(filename: "key-instr-enabled.cpp", directory: "/") +!3 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 21.0.0git"} +!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: true) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = !DILocation(line: 1, column: 11, scope: !10, atomGroup: 1, atomRank: 1) + +;--- key-instr-disabled.ll +define dso_local void @g() !dbg !10 { +entry: + ret void, !dbg !13 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3} + +!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) +!1 = !DIFile(filename: "key-instr-disabled.cpp", directory: "/") +!3 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 21.0.0git"} +!10 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: false) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = !DILocation(line: 1, column: 11, scope: !10) diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/roundtrip.ll b/llvm/test/DebugInfo/KeyInstructions/Generic/roundtrip.ll new file mode 100644 index 0000000000000..79a06e51b264f --- /dev/null +++ b/llvm/test/DebugInfo/KeyInstructions/Generic/roundtrip.ll @@ -0,0 +1,48 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt %s -o - -S | llvm-as - | llvm-dis - | FileCheck %s + +; Key Instructions enabled. +define dso_local void @f() !dbg !10 { +; CHECK-LABEL: define dso_local void @f( +; CHECK-SAME: ) !dbg [[DBG3:![0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: ret void, !dbg [[DBG6:![0-9]+]] +; +entry: + ret void, !dbg !13 +} + +; Key Instructions disabled. +define dso_local void @g() !dbg !14 { +; CHECK-LABEL: define dso_local void @g( +; CHECK-SAME: ) !dbg [[DBG7:![0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: ret void, !dbg [[DBG8:![0-9]+]] +; +entry: + ret void, !dbg !15 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3} + +!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) +!1 = !DIFile(filename: "key-instr.cpp", directory: "/") +!3 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 21.0.0git"} +!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: true) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = !DILocation(line: 1, scope: !10, atomGroup: 1, atomRank: 1) +!14 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 2, type: !11, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, keyInstructions: false) +!15 = !DILocation(line: 2, scope: !14) +;. +; 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) +; CHECK: [[META1]] = !DIFile(filename: "{{.*}}key-instr.cpp", directory: {{.*}}) +; 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) +; CHECK: [[META4]] = !DISubroutineType(types: [[META5:![0-9]+]]) +; CHECK: [[META5]] = !{null} +; CHECK: [[DBG6]] = !DILocation(line: 1, scope: [[DBG3]], atomGroup: 1, atomRank: 1) +; CHECK: [[DBG7]] = distinct !DISubprogram(name: "g", scope: [[META1]], file: [[META1]], line: 2, type: [[META4]], scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]]) +; CHECK: [[DBG8]] = !DILocation(line: 2, scope: [[DBG7]]) +;.