[flang-commits] [flang] d58b056 - [DebugMetadata][DwarfDebug][CodeView] Support function-local static variables in lexical block scopes (6/7) (#187927)
via flang-commits
flang-commits at lists.llvm.org
Fri Jul 10 08:32:22 PDT 2026
Author: Vladislav Dzhidzhoev
Date: 2026-07-10T15:32:16Z
New Revision: d58b0562a340b043ed83b0fb4375e89ed74fc621
URL: https://github.com/llvm/llvm-project/commit/d58b0562a340b043ed83b0fb4375e89ed74fc621
DIFF: https://github.com/llvm/llvm-project/commit/d58b0562a340b043ed83b0fb4375e89ed74fc621.diff
LOG: [DebugMetadata][DwarfDebug][CodeView] Support function-local static variables in lexical block scopes (6/7) (#187927)
RFC
https://discourse.llvm.org/t/rfc-dwarfdebug-fix-and-improve-handling-imported-entities-types-and-static-local-in-subprogram-and-lexical-block-scopes/68544
Similar to imported declarations and types, the patch tracks
function-local static variables (globals in terms of LLVM IR) in
DISubprogram's 'retainedNodes'. DwarfDebug is adjusted in accordance
with the aforementioned metadata change and provided a support of static
locals scoped by a lexical block. CodeViewDebug is modified to collect
global variables from DISubprogram's 'retainedNodes' too.
The patch assumes that DICompileUnit's 'globals' no longer tracks static
locals and DwarfDebug would assert if any locally-scoped variables get
placed there.
This change has already been reviewed in
https://reviews.llvm.org/D144008, but I’m opening a new PR because it
has been a while since it was approved. Additional logic was added to
CloneFunction to deal with DISubprograms that have static locals: if
such a subprogram is cloned, DIGlobalVariableExpressions are removed
from retainedNodes of the clone. This is consistent with the current
behavior, in which DIGlobalVariableExpressions are not cloned.
Authored-by: Kristina Bessonova <kbessonova at accesssoftek.com>
Co-authored-by: Tobias Gysi <tobias.gysi at nextsilicon.com>
Added:
llvm/test/Bitcode/upgrade-cu-static-locals.ll
llvm/test/Bitcode/upgrade-cu-static-locals.ll.bc
llvm/test/DebugInfo/Generic/verifier-invalid-dicompileunit.ll
llvm/test/DebugInfo/X86/lexical-block-static-var.ll
Modified:
clang/test/OpenMP/error_codegen.cpp
compiler-rt/test/profile/Linux/instrprof-debug-info-correlate-warnings.ll
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
llvm/include/llvm/IR/DIBuilder.h
llvm/include/llvm/IR/DebugInfo.h
llvm/include/llvm/IR/DebugInfoMetadata.h
llvm/include/llvm/IR/Metadata.h
llvm/lib/Bitcode/Reader/MetadataLoader.cpp
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp
llvm/lib/IR/DIBuilder.cpp
llvm/lib/IR/DebugInfo.cpp
llvm/lib/IR/DebugInfoMetadata.cpp
llvm/lib/IR/Verifier.cpp
llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
llvm/lib/Target/BPF/BTFDebug.cpp
llvm/lib/Transforms/Coroutines/CoroFrame.cpp
llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
llvm/lib/Transforms/Utils/CloneFunction.cpp
llvm/lib/Transforms/Utils/Debugify.cpp
llvm/test/Bitcode/DIModule-fortran-external-module.ll
llvm/test/CodeGen/AArch64/arm64-2011-03-17-AsmPrinterCrash.ll
llvm/test/CodeGen/BPF/BTF/static-var-inited-sec.ll
llvm/test/CodeGen/BPF/BTF/static-var-inited.ll
llvm/test/CodeGen/BPF/BTF/static-var-readonly-sec.ll
llvm/test/CodeGen/BPF/BTF/static-var-readonly.ll
llvm/test/CodeGen/BPF/BTF/static-var-sec.ll
llvm/test/CodeGen/BPF/BTF/static-var.ll
llvm/test/CodeGen/BPF/dwarfdump.ll
llvm/test/CodeGen/PowerPC/pr24546.ll
llvm/test/CodeGen/X86/dbg-distringtype-uint.ll
llvm/test/DebugInfo/COFF/fortran-basic.ll
llvm/test/DebugInfo/COFF/fortran-contained-proc.ll
llvm/test/DebugInfo/COFF/global_visibility.ll
llvm/test/DebugInfo/COFF/type-quals.ll
llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll
llvm/test/DebugInfo/Generic/global-var-in-abstract-lexical-block.ll
llvm/test/DebugInfo/Generic/inlined-static-var.ll
llvm/test/DebugInfo/Generic/verifier-invalid-disubprogram.ll
llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll
llvm/test/DebugInfo/X86/DW_AT_specification.ll
llvm/test/DebugInfo/X86/dbg-value-transfer-order.ll
llvm/test/DebugInfo/X86/dimodule-external-fortran.ll
llvm/test/DebugInfo/X86/distringtype.ll
llvm/test/DebugInfo/X86/global-sra-struct-fit-segment.ll
llvm/test/DebugInfo/X86/global-sra-struct-part-overlap-segment.ll
llvm/test/DebugInfo/X86/gnu-public-names.ll
llvm/test/DebugInfo/X86/namelist1.ll
llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
llvm/test/DebugInfo/duplicate_dbgvalue.ll
llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-bitmap.ll
llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
llvm/test/Transforms/Util/clone-dicompileunit.ll
llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll
llvm/unittests/Transforms/Utils/CloningTest.cpp
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
mlir/lib/CAPI/Dialect/LLVM.cpp
mlir/lib/Target/LLVMIR/DebugImporter.cpp
mlir/lib/Target/LLVMIR/DebugTranslation.cpp
mlir/lib/Target/LLVMIR/DebugTranslation.h
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Target/LLVMIR/Import/debug-info.ll
mlir/test/Target/LLVMIR/llvmir-debug.mlir
Removed:
################################################################################
diff --git a/clang/test/OpenMP/error_codegen.cpp b/clang/test/OpenMP/error_codegen.cpp
index 0efb0ab098cf3..def68ea020c63 100644
--- a/clang/test/OpenMP/error_codegen.cpp
+++ b/clang/test/OpenMP/error_codegen.cpp
@@ -565,7 +565,7 @@ int main (int argc, char **argv) {
//
//
// SIMD-LABEL: define linkonce_odr noundef i32 @_Z5tmainIiLi10EEiT_PPc(
-// SIMD-SAME: i32 noundef [[ARGC:%.*]], ptr noundef [[ARGV:%.*]]) #[[ATTR0]] comdat !dbg [[DBG21:![0-9]+]] {
+// SIMD-SAME: i32 noundef [[ARGC:%.*]], ptr noundef [[ARGV:%.*]]) #[[ATTR0]] comdat !dbg [[DBG22:![0-9]+]] {
// SIMD-NEXT: [[ENTRY:.*:]]
// SIMD-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4
// SIMD-NEXT: [[ARGV_ADDR:%.*]] = alloca ptr, align 8
@@ -630,7 +630,7 @@ int main (int argc, char **argv) {
//.
// SIMD: [[META0:![0-9]+]] = !DIGlobalVariableExpression(var: [[META1:![0-9]+]], expr: !DIExpression())
// SIMD: [[META1]] = distinct !DIGlobalVariable(name: "a", scope: [[DBG2]], file: [[META3:![0-9]+]], line: 61, type: [[META6:![0-9]+]], isLocal: true, isDefinition: true)
-// SIMD: [[DBG2]] = distinct !DISubprogram(name: "main", scope: [[META3]], file: [[META3]], line: 59, type: [[META4:![0-9]+]], scopeLine: 59, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META10:![0-9]+]], retainedNodes: [[META22:![0-9]+]])
+// SIMD: [[DBG2]] = distinct !DISubprogram(name: "main", scope: [[META3]], file: [[META3]], line: 59, type: [[META4:![0-9]+]], scopeLine: 59, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META10:![0-9]+]], retainedNodes: [[META19:![0-9]+]])
// SIMD: [[META3]] = !DIFile(filename: "{{.*}}error_codegen.cpp", directory: {{.*}})
// SIMD: [[META4]] = !DISubroutineType(types: [[META5:![0-9]+]])
// SIMD: [[META5]] = !{[[META6]], [[META6]], [[META7:![0-9]+]]}
@@ -640,20 +640,21 @@ int main (int argc, char **argv) {
// SIMD: [[META9]] = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
// SIMD: [[META10]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_11, file: [[META11:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: [[META12:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
// SIMD: [[META11]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
-// SIMD: [[META12]] = !{[[META0]], [[META13:![0-9]+]], [[META19:![0-9]+]]}
+// SIMD: [[META12]] = !{[[META13:![0-9]+]]}
// SIMD: [[META13]] = !DIGlobalVariableExpression(var: [[META14:![0-9]+]], expr: !DIExpression())
// SIMD: [[META14]] = distinct !DIGlobalVariable(scope: null, file: [[META3]], line: 63, type: [[META15:![0-9]+]], isLocal: true, isDefinition: true)
// SIMD: [[META15]] = !DICompositeType(tag: DW_TAG_array_type, baseType: [[META16:![0-9]+]], size: 32, elements: [[META17:![0-9]+]])
// SIMD: [[META16]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: [[META9]])
// SIMD: [[META17]] = !{[[META18:![0-9]+]]}
// SIMD: [[META18]] = !DISubrange(count: 4)
-// SIMD: [[META19]] = !DIGlobalVariableExpression(var: [[META20:![0-9]+]], expr: !DIExpression())
-// SIMD: [[META20]] = distinct !DIGlobalVariable(name: "a", scope: [[DBG21]], file: [[META3]], line: 22, type: [[META6]], isLocal: false, isDefinition: true)
-// SIMD: [[DBG21]] = distinct !DISubprogram(name: "tmain<int, 10>", linkageName: "_Z5tmainIiLi10EEiT_PPc", scope: [[META3]], file: [[META3]], line: 20, type: [[META4]], scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META10]], templateParams: [[META23:![0-9]+]], retainedNodes: [[META22]])
-// SIMD: [[META22]] = !{}
-// SIMD: [[META23]] = !{[[META24:![0-9]+]], [[META25:![0-9]+]]}
-// SIMD: [[META24]] = !DITemplateTypeParameter(name: "T", type: [[META6]])
-// SIMD: [[META25]] = !DITemplateValueParameter(name: "N", type: [[META6]], value: i32 10)
+// SIMD: [[META19]] = !{[[META0]]}
+// SIMD: [[META20:![0-9]+]] = !DIGlobalVariableExpression(var: [[META21:![0-9]+]], expr: !DIExpression())
+// SIMD: [[META21]] = distinct !DIGlobalVariable(name: "a", scope: [[DBG22]], file: [[META3]], line: 22, type: [[META6]], isLocal: false, isDefinition: true)
+// SIMD: [[DBG22]] = distinct !DISubprogram(name: "tmain<int, 10>", linkageName: "_Z5tmainIiLi10EEiT_PPc", scope: [[META3]], file: [[META3]], line: 20, type: [[META4]], scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META10]], templateParams: [[META24:![0-9]+]], retainedNodes: [[META23:![0-9]+]])
+// SIMD: [[META23]] = !{[[META20]]}
+// SIMD: [[META24]] = !{[[META25:![0-9]+]], [[META26:![0-9]+]]}
+// SIMD: [[META25]] = !DITemplateTypeParameter(name: "T", type: [[META6]])
+// SIMD: [[META26]] = !DITemplateValueParameter(name: "N", type: [[META6]], value: i32 10)
// SIMD: [[DBG29]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: [[META3]], file: [[META3]], line: 17, type: [[META30:![0-9]+]], scopeLine: 17, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META10]])
// SIMD: [[META30]] = !DISubroutineType(types: [[META31:![0-9]+]])
// SIMD: [[META31]] = !{null}
@@ -696,40 +697,40 @@ int main (int argc, char **argv) {
// SIMD: [[DBG68]] = !DILocation(line: 81, column: 24, scope: [[DBG2]])
// SIMD: [[DBG69]] = !DILocation(line: 81, column: 3, scope: [[DBG2]])
// SIMD: [[DBG70]] = !DILocation(line: 82, column: 1, scope: [[DBG2]])
-// SIMD: [[META71]] = !DILocalVariable(name: "argc", arg: 1, scope: [[DBG21]], file: [[META3]], line: 20, type: [[META6]])
-// SIMD: [[META72]] = !DILocation(line: 20, column: 13, scope: [[DBG21]])
-// SIMD: [[META73]] = !DILocalVariable(name: "argv", arg: 2, scope: [[DBG21]], file: [[META3]], line: 20, type: [[META7]])
-// SIMD: [[META74]] = !DILocation(line: 20, column: 26, scope: [[DBG21]])
-// SIMD: [[META75]] = !DILocalVariable(name: "b", scope: [[DBG21]], file: [[META3]], line: 21, type: [[META6]])
-// SIMD: [[META76]] = !DILocation(line: 21, column: 5, scope: [[DBG21]])
-// SIMD: [[DBG77]] = !DILocation(line: 21, column: 9, scope: [[DBG21]])
-// SIMD: [[META78]] = !DILocalVariable(name: "c", scope: [[DBG21]], file: [[META3]], line: 21, type: [[META6]])
-// SIMD: [[META79]] = !DILocation(line: 21, column: 15, scope: [[DBG21]])
-// SIMD: [[META80]] = !DILocalVariable(name: "d", scope: [[DBG21]], file: [[META3]], line: 21, type: [[META6]])
-// SIMD: [[META81]] = !DILocation(line: 21, column: 18, scope: [[DBG21]])
-// SIMD: [[META82]] = !DILocalVariable(name: "e", scope: [[DBG21]], file: [[META3]], line: 21, type: [[META6]])
-// SIMD: [[META83]] = !DILocation(line: 21, column: 21, scope: [[DBG21]])
-// SIMD: [[META84]] = !DILocalVariable(name: "f", scope: [[DBG21]], file: [[META3]], line: 21, type: [[META6]])
-// SIMD: [[META85]] = !DILocation(line: 21, column: 24, scope: [[DBG21]])
-// SIMD: [[META86]] = !DILocalVariable(name: "g", scope: [[DBG21]], file: [[META3]], line: 21, type: [[META6]])
-// SIMD: [[META87]] = !DILocation(line: 21, column: 27, scope: [[DBG21]])
-// SIMD: [[META88]] = !DILocalVariable(name: "str1", scope: [[DBG21]], file: [[META3]], line: 23, type: [[META15]])
-// SIMD: [[META89]] = !DILocation(line: 23, column: 14, scope: [[DBG21]])
-// SIMD: [[META90]] = !DILocalVariable(name: "str2", scope: [[DBG21]], file: [[META3]], line: 24, type: [[META53]])
-// SIMD: [[META91]] = !DILocation(line: 24, column: 15, scope: [[DBG21]])
-// SIMD: [[META92]] = !DILocalVariable(name: "str3", scope: [[DBG21]], file: [[META3]], line: 25, type: [[META56]])
-// SIMD: [[META93]] = !DILocation(line: 25, column: 8, scope: [[DBG21]])
-// SIMD: [[META94]] = !DILocalVariable(name: "str4", scope: [[DBG21]], file: [[META3]], line: 26, type: [[META8]])
-// SIMD: [[META95]] = !DILocation(line: 26, column: 9, scope: [[DBG21]])
-// SIMD: [[DBG96]] = !DILocation(line: 26, column: 16, scope: [[DBG21]])
-// SIMD: [[META97]] = !DILocalVariable(name: "str5", scope: [[DBG21]], file: [[META3]], line: 27, type: [[META62]])
-// SIMD: [[META98]] = !DILocation(line: 27, column: 16, scope: [[DBG21]])
-// SIMD: [[DBG99]] = !DILocation(line: 27, column: 23, scope: [[DBG21]])
-// SIMD: [[DBG100]] = !DILocation(line: 34, column: 7, scope: [[DBG21]])
-// SIMD: [[DBG101]] = !DILocation(line: 34, column: 5, scope: [[DBG21]])
-// SIMD: [[DBG102]] = !DILocation(line: 35, column: 3, scope: [[DBG21]])
+// SIMD: [[META71]] = !DILocalVariable(name: "argc", arg: 1, scope: [[DBG22]], file: [[META3]], line: 20, type: [[META6]])
+// SIMD: [[META72]] = !DILocation(line: 20, column: 13, scope: [[DBG22]])
+// SIMD: [[META73]] = !DILocalVariable(name: "argv", arg: 2, scope: [[DBG22]], file: [[META3]], line: 20, type: [[META7]])
+// SIMD: [[META74]] = !DILocation(line: 20, column: 26, scope: [[DBG22]])
+// SIMD: [[META75]] = !DILocalVariable(name: "b", scope: [[DBG22]], file: [[META3]], line: 21, type: [[META6]])
+// SIMD: [[META76]] = !DILocation(line: 21, column: 5, scope: [[DBG22]])
+// SIMD: [[DBG77]] = !DILocation(line: 21, column: 9, scope: [[DBG22]])
+// SIMD: [[META78]] = !DILocalVariable(name: "c", scope: [[DBG22]], file: [[META3]], line: 21, type: [[META6]])
+// SIMD: [[META79]] = !DILocation(line: 21, column: 15, scope: [[DBG22]])
+// SIMD: [[META80]] = !DILocalVariable(name: "d", scope: [[DBG22]], file: [[META3]], line: 21, type: [[META6]])
+// SIMD: [[META81]] = !DILocation(line: 21, column: 18, scope: [[DBG22]])
+// SIMD: [[META82]] = !DILocalVariable(name: "e", scope: [[DBG22]], file: [[META3]], line: 21, type: [[META6]])
+// SIMD: [[META83]] = !DILocation(line: 21, column: 21, scope: [[DBG22]])
+// SIMD: [[META84]] = !DILocalVariable(name: "f", scope: [[DBG22]], file: [[META3]], line: 21, type: [[META6]])
+// SIMD: [[META85]] = !DILocation(line: 21, column: 24, scope: [[DBG22]])
+// SIMD: [[META86]] = !DILocalVariable(name: "g", scope: [[DBG22]], file: [[META3]], line: 21, type: [[META6]])
+// SIMD: [[META87]] = !DILocation(line: 21, column: 27, scope: [[DBG22]])
+// SIMD: [[META88]] = !DILocalVariable(name: "str1", scope: [[DBG22]], file: [[META3]], line: 23, type: [[META15]])
+// SIMD: [[META89]] = !DILocation(line: 23, column: 14, scope: [[DBG22]])
+// SIMD: [[META90]] = !DILocalVariable(name: "str2", scope: [[DBG22]], file: [[META3]], line: 24, type: [[META53]])
+// SIMD: [[META91]] = !DILocation(line: 24, column: 15, scope: [[DBG22]])
+// SIMD: [[META92]] = !DILocalVariable(name: "str3", scope: [[DBG22]], file: [[META3]], line: 25, type: [[META56]])
+// SIMD: [[META93]] = !DILocation(line: 25, column: 8, scope: [[DBG22]])
+// SIMD: [[META94]] = !DILocalVariable(name: "str4", scope: [[DBG22]], file: [[META3]], line: 26, type: [[META8]])
+// SIMD: [[META95]] = !DILocation(line: 26, column: 9, scope: [[DBG22]])
+// SIMD: [[DBG96]] = !DILocation(line: 26, column: 16, scope: [[DBG22]])
+// SIMD: [[META97]] = !DILocalVariable(name: "str5", scope: [[DBG22]], file: [[META3]], line: 27, type: [[META62]])
+// SIMD: [[META98]] = !DILocation(line: 27, column: 16, scope: [[DBG22]])
+// SIMD: [[DBG99]] = !DILocation(line: 27, column: 23, scope: [[DBG22]])
+// SIMD: [[DBG100]] = !DILocation(line: 34, column: 7, scope: [[DBG22]])
+// SIMD: [[DBG101]] = !DILocation(line: 34, column: 5, scope: [[DBG22]])
+// SIMD: [[DBG102]] = !DILocation(line: 35, column: 3, scope: [[DBG22]])
// SIMD: [[META103]] = !DILocalVariable(name: "b", scope: [[META104:![0-9]+]], file: [[META3]], line: 43, type: [[META6]])
-// SIMD: [[META104]] = distinct !DILexicalBlock(scope: [[DBG21]], file: [[META3]], line: 42, column: 3)
+// SIMD: [[META104]] = distinct !DILexicalBlock(scope: [[DBG22]], file: [[META3]], line: 42, column: 3)
// SIMD: [[META105]] = !DILocation(line: 43, column: 9, scope: [[META104]])
// SIMD: [[META106]] = !DILocalVariable(name: "c", scope: [[META104]], file: [[META3]], line: 44, type: [[META6]])
// SIMD: [[META107]] = !DILocation(line: 44, column: 7, scope: [[META104]])
@@ -737,6 +738,6 @@ int main (int argc, char **argv) {
// SIMD: [[DBG109]] = !DILocation(line: 45, column: 13, scope: [[META104]])
// SIMD: [[DBG110]] = !DILocation(line: 45, column: 11, scope: [[META104]])
// SIMD: [[DBG111]] = !DILocation(line: 45, column: 7, scope: [[META104]])
-// SIMD: [[DBG112]] = !DILocation(line: 53, column: 3, scope: [[DBG21]])
-// SIMD: [[DBG113]] = !DILocation(line: 54, column: 1, scope: [[DBG21]])
+// SIMD: [[DBG112]] = !DILocation(line: 53, column: 3, scope: [[DBG22]])
+// SIMD: [[DBG113]] = !DILocation(line: 54, column: 1, scope: [[DBG22]])
//.
diff --git a/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate-warnings.ll b/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate-warnings.ll
index 7a8569975c82b..ecd076c811dcc 100644
--- a/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate-warnings.ll
+++ b/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate-warnings.ll
@@ -21,7 +21,8 @@ void no_name() {}
void no_cfg() {}
void no_counter() {}
void no_profc() {}
-void no_func() {}
+__attribute__((always_inline)) void no_func() {}
+void use_func() { no_func(); }
// NOTE: After generating the IR below, manually remove the follwing pieces
// 1. Remove "@removed" function and "@__profc_removed" global
@@ -55,6 +56,8 @@ $__profc_no_profc = comdat nodeduplicate
$__profc_no_func = comdat nodeduplicate
+$__profc_use_func = comdat nodeduplicate
+
$__llvm_profile_filename = comdat any
@__llvm_profile_raw_version = hidden constant i64 648518346341351434, comdat
@@ -65,119 +68,153 @@ $__llvm_profile_filename = comdat any
@__profn_no_counter = private constant [10 x i8] c"no_counter"
@__profn_no_profc = private constant [8 x i8] c"no_profc"
@__profn_no_func = private constant [7 x i8] c"no_func"
+ at __profn_use_func = private constant [8 x i8] c"use_func"
@__profc_main = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !0
- at __profc_no_name = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !19
- at __profc_no_cfg = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !24
- at __profc_no_counter = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !29
- at __profc_no_func = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !39
+ at __profc_no_name = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !22
+ at __profc_no_cfg = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !28
+ at __profc_no_counter = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !34
+ at __profc_no_func = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !46
+ at __profc_use_func = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8, !dbg !52
@llvm.compiler.used = appending global [5 x ptr] [ptr @__profc_main, ptr @__profc_no_name, ptr @__profc_no_cfg, ptr @__profc_no_counter, ptr @__profc_no_func], section "llvm.metadata"
@__llvm_profile_filename = hidden constant [20 x i8] c"default_%m.proflite\00", comdat
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 !dbg !2 {
- %1 = alloca i32, align 4
- %2 = load i64, ptr @__profc_main, align 8
- %3 = add i64 %2, 1
- store i64 %3, ptr @__profc_main, align 8
- store i32 0, ptr %1, align 4
- ret i32 0, !dbg !53
+entry:
+ %retval = alloca i32, align 4
+ %pgocount = load i64, ptr @__profc_main, align 8
+ %0 = add i64 %pgocount, 1
+ store i64 %0, ptr @__profc_main, align 8
+ store i32 0, ptr %retval, align 4
+ ret i32 0, !dbg !64
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local void @no_name() #0 !dbg !24 {
+entry:
+ %pgocount = load i64, ptr @__profc_no_name, align 8, !dbg !66
+ %0 = add i64 %pgocount, 1, !dbg !66
+ store i64 %0, ptr @__profc_no_name, align 8, !dbg !66
+ ret void, !dbg !66
}
; Function Attrs: noinline nounwind optnone uwtable
-define dso_local void @no_name() #0 !dbg !21 {
- %1 = load i64, ptr @__profc_no_name, align 8, !dbg !55
- %2 = add i64 %1, 1, !dbg !55
- store i64 %2, ptr @__profc_no_name, align 8, !dbg !55
- ret void, !dbg !55
+define dso_local void @no_cfg() #0 !dbg !30 {
+entry:
+ %pgocount = load i64, ptr @__profc_no_cfg, align 8, !dbg !67
+ %0 = add i64 %pgocount, 1, !dbg !67
+ store i64 %0, ptr @__profc_no_cfg, align 8, !dbg !67
+ ret void, !dbg !67
}
; Function Attrs: noinline nounwind optnone uwtable
-define dso_local void @no_cfg() #0 !dbg !26 {
- %1 = load i64, ptr @__profc_no_cfg, align 8, !dbg !56
- %2 = add i64 %1, 1, !dbg !56
- store i64 %2, ptr @__profc_no_cfg, align 8, !dbg !56
- ret void, !dbg !56
+define dso_local void @no_counter() #0 !dbg !36 {
+entry:
+ %pgocount = load i64, ptr @__profc_no_counter, align 8, !dbg !68
+ %0 = add i64 %pgocount, 1, !dbg !68
+ store i64 %0, ptr @__profc_no_counter, align 8, !dbg !68
+ ret void, !dbg !68
}
; Function Attrs: noinline nounwind optnone uwtable
-define dso_local void @no_counter() #0 !dbg !31 {
- %1 = load i64, ptr @__profc_no_counter, align 8, !dbg !57
- %2 = add i64 %1, 1, !dbg !57
- store i64 %2, ptr @__profc_no_counter, align 8, !dbg !57
- ret void, !dbg !57
+define dso_local void @no_profc() #0 !dbg !42 {
+entry:
+ ret void, !dbg !69
}
; Function Attrs: noinline nounwind optnone uwtable
-define dso_local void @no_profc() #0 !dbg !36 {
- ret void, !dbg !58
+define dso_local void @use_func() #0 !dbg !54 {
+entry:
+ %pgocount = load i64, ptr @__profc_use_func, align 8, !dbg !71
+ %0 = add i64 %pgocount, 1, !dbg !71
+ store i64 %0, ptr @__profc_use_func, align 8, !dbg !71
+ %pgocount.i = load i64, ptr @__profc_no_func, align 8, !dbg !72
+ %1 = add i64 %pgocount.i, 1, !dbg !72
+ store i64 %1, ptr @__profc_no_func, align 8, !dbg !72
+ ret void, !dbg !74
}
; Function Attrs: nounwind
-declare void @llvm.instrprof.increment(ptr, i64, i32, i32) #1
+declare void @llvm.instrprof.increment(ptr, i64, i32, i32) #2
attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
-attributes #1 = { nounwind }
+attributes #1 = { alwaysinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #2 = { nounwind }
!llvm.dbg.cu = !{!7}
-!llvm.module.flags = !{!46, !47, !48, !49, !50, !51, !52}
+!llvm.module.flags = !{!58, !59, !60, !61, !62, !63}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
-!1 = distinct !DIGlobalVariable(name: "__profc_main", scope: !2, file: !3, type: !14, isLocal: true, isDefinition: true, annotations: !44)
-!2 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !7)
-!3 = !DIFile(filename: "a.c", directory: "/proc/self/cwd", checksumkind: CSK_MD5, checksum: "22eee0eada6e6964fca794aa5a0966d0")
+!1 = distinct !DIGlobalVariable(name: "__profc_main", scope: !2, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !10)
+!2 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !8)
+!3 = !DIFile(filename: "a.c", directory: "/proc/self/cwd", checksumkind: CSK_MD5, checksum: "7bab6089d746f793d8c0c8d39f3a691c")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!7 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false, nameTableKind: None)
-!8 = !{!0, !9, !19, !24, !29, !34, !39}
-!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression())
-!10 = distinct !DIGlobalVariable(name: "__profc_removed", scope: !11, file: !3, type: !14, isLocal: true, isDefinition: true, annotations: !15)
-!11 = distinct !DISubprogram(name: "removed", scope: !3, file: !3, line: 3, type: !12, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !7)
-!12 = !DISubroutineType(types: !13)
-!13 = !{null}
-!14 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "Profile Data Type")
-!15 = !{!16, !17, !18}
-!16 = !{!"Function Name", !"removed"}
-!17 = !{!"CFG Hash", i64 742261418966908927}
-!18 = !{!"Num Counters", i32 1}
-!19 = !DIGlobalVariableExpression(var: !20, expr: !DIExpression())
-!20 = distinct !DIGlobalVariable(name: "__profc_no_name", scope: !21, file: !3, type: !14, isLocal: true, isDefinition: true, annotations: !22)
-!21 = distinct !DISubprogram(name: "no_name", scope: !3, file: !3, line: 4, type: !12, scopeLine: 4, spFlags: DISPFlagDefinition, unit: !7)
-!22 = !{!17, !18}
-!23 = !{!"Function Name", !"no_name"}
-!24 = !DIGlobalVariableExpression(var: !25, expr: !DIExpression())
-!25 = distinct !DIGlobalVariable(name: "__profc_no_cfg", scope: !26, file: !3, type: !14, isLocal: true, isDefinition: true, annotations: !27)
-!26 = distinct !DISubprogram(name: "no_cfg", scope: !3, file: !3, line: 5, type: !12, scopeLine: 5, spFlags: DISPFlagDefinition, unit: !7)
-!27 = !{!28, !18}
-!28 = !{!"Function Name", !"no_cfg"}
-!29 = !DIGlobalVariableExpression(var: !30, expr: !DIExpression())
-!30 = distinct !DIGlobalVariable(name: "__profc_no_counter", scope: !31, file: !3, type: !14, isLocal: true, isDefinition: true, annotations: !32)
-!31 = distinct !DISubprogram(name: "no_counter", scope: !3, file: !3, line: 6, type: !12, scopeLine: 6, spFlags: DISPFlagDefinition, unit: !7)
-!32 = !{!33, !17}
-!33 = !{!"Function Name", !"no_counter"}
+!7 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!8 = !{!0}
+!9 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "Profile Data Type")
+!10 = !{!11, !12, !13}
+!11 = !{!"Function Name", !"main"}
+!12 = !{!"CFG Hash", i64 742261418966908927}
+!13 = !{!"Num Counters", i32 1}
+!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression())
+!15 = distinct !DIGlobalVariable(name: "__profc_removed", scope: !16, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !20)
+!16 = distinct !DISubprogram(name: "removed", scope: !3, file: !3, line: 3, type: !17, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !19)
+!17 = !DISubroutineType(types: !18)
+!18 = !{null}
+!19 = !{!14}
+!20 = !{!21, !12, !13}
+!21 = !{!"Function Name", !"removed"}
+!22 = !DIGlobalVariableExpression(var: !23, expr: !DIExpression())
+!23 = distinct !DIGlobalVariable(name: "__profc_no_name", scope: !24, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !26)
+!24 = distinct !DISubprogram(name: "no_name", scope: !3, file: !3, line: 4, type: !17, scopeLine: 4, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !25)
+!25 = !{!22}
+!26 = !{!12, !13}
+!28 = !DIGlobalVariableExpression(var: !29, expr: !DIExpression())
+!29 = distinct !DIGlobalVariable(name: "__profc_no_cfg", scope: !30, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !32)
+!30 = distinct !DISubprogram(name: "no_cfg", scope: !3, file: !3, line: 5, type: !17, scopeLine: 5, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !31)
+!31 = !{!28}
+!32 = !{!33, !13}
+!33 = !{!"Function Name", !"no_cfg"}
!34 = !DIGlobalVariableExpression(var: !35, expr: !DIExpression())
-!35 = distinct !DIGlobalVariable(name: "__profc_no_profc", scope: !36, file: !3, type: !14, isLocal: true, isDefinition: true, annotations: !37)
-!36 = distinct !DISubprogram(name: "no_profc", scope: !3, file: !3, line: 7, type: !12, scopeLine: 7, spFlags: DISPFlagDefinition, unit: !7)
-!37 = !{!38, !17, !18}
-!38 = !{!"Function Name", !"no_profc"}
-!39 = !DIGlobalVariableExpression(var: !40, expr: !DIExpression())
-!40 = distinct !DIGlobalVariable(name: "__profc_no_func", scope: !41, file: !3, type: !14, isLocal: true, isDefinition: true, annotations: !42)
-!41 = distinct !DISubprogram(name: "no_func", scope: !3, file: !3, line: 8, type: !12, scopeLine: 8, spFlags: DISPFlagDefinition, unit: !7)
-!42 = !{!43, !17, !18}
-!43 = !{!"Function Name", !"no_func"}
-!44 = !{!45, !17, !18}
-!45 = !{!"Function Name", !"main"}
-!46 = !{i32 7, !"Dwarf Version", i32 5}
-!47 = !{i32 2, !"Debug Info Version", i32 3}
-!48 = !{i32 1, !"wchar_size", i32 4}
-!49 = !{i32 8, !"PIC Level", i32 2}
-!50 = !{i32 7, !"PIE Level", i32 2}
-!51 = !{i32 7, !"uwtable", i32 2}
-!52 = !{i32 7, !"frame-pointer", i32 2}
-!53 = !DILocation(line: 1, column: 14, scope: !2)
-!54 = !DILocation(line: 3, column: 17, scope: !11)
-!55 = !DILocation(line: 4, column: 17, scope: !21)
-!56 = !DILocation(line: 5, column: 16, scope: !26)
-!57 = !DILocation(line: 6, column: 20, scope: !31)
-!58 = !DILocation(line: 7, column: 18, scope: !36)
-!59 = !DILocation(line: 8, column: 17, scope: !41)
+!35 = distinct !DIGlobalVariable(name: "__profc_no_counter", scope: !36, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !38)
+!36 = distinct !DISubprogram(name: "no_counter", scope: !3, file: !3, line: 6, type: !17, scopeLine: 6, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !37)
+!37 = !{!34}
+!38 = !{!39, !12}
+!39 = !{!"Function Name", !"no_counter"}
+!40 = !DIGlobalVariableExpression(var: !41, expr: !DIExpression())
+!41 = distinct !DIGlobalVariable(name: "__profc_no_profc", scope: !42, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !44)
+!42 = distinct !DISubprogram(name: "no_profc", scope: !3, file: !3, line: 7, type: !17, scopeLine: 7, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !43)
+!43 = !{!40}
+!44 = !{!45, !12, !13}
+!45 = !{!"Function Name", !"no_profc"}
+!46 = !DIGlobalVariableExpression(var: !47, expr: !DIExpression())
+!47 = distinct !DIGlobalVariable(name: "__profc_no_func", scope: !48, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !50)
+!48 = distinct !DISubprogram(name: "no_func", scope: !3, file: !3, line: 8, type: !17, scopeLine: 8, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !49)
+!49 = !{!46}
+!50 = !{!51, !12, !13}
+!51 = !{!"Function Name", !"no_func"}
+!52 = !DIGlobalVariableExpression(var: !53, expr: !DIExpression())
+!53 = distinct !DIGlobalVariable(name: "__profc_use_func", scope: !54, file: !3, type: !9, isLocal: true, isDefinition: true, annotations: !56)
+!54 = distinct !DISubprogram(name: "use_func", scope: !3, file: !3, line: 9, type: !17, scopeLine: 9, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !55)
+!55 = !{!52}
+!56 = !{!57, !12, !13}
+!57 = !{!"Function Name", !"use_func"}
+!58 = !{i32 7, !"Dwarf Version", i32 5}
+!59 = !{i32 2, !"Debug Info Version", i32 3}
+!60 = !{i32 8, !"PIC Level", i32 2}
+!61 = !{i32 7, !"PIE Level", i32 2}
+!62 = !{i32 7, !"uwtable", i32 2}
+!63 = !{i32 7, !"frame-pointer", i32 2}
+!64 = !DILocation(line: 1, column: 14, scope: !2)
+!65 = !DILocation(line: 3, column: 17, scope: !16)
+!66 = !DILocation(line: 4, column: 17, scope: !24)
+!67 = !DILocation(line: 5, column: 16, scope: !30)
+!68 = !DILocation(line: 6, column: 20, scope: !36)
+!69 = !DILocation(line: 7, column: 18, scope: !42)
+!70 = !DILocation(line: 8, column: 48, scope: !48)
+!71 = !DILocation(line: 9, column: 19, scope: !54)
+!72 = !DILocation(line: 8, column: 48, scope: !48, inlinedAt: !73)
+!73 = distinct !DILocation(line: 9, column: 19, scope: !54)
+!74 = !DILocation(line: 9, column: 30, scope: !54)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 484d5df4c162e..7c0b32e48832e 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -665,7 +665,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
}
auto addTargetOpDISP = [&](bool lineTableOnly,
- llvm::ArrayRef<mlir::LLVM::DINodeAttr> entities) {
+ llvm::ArrayRef<mlir::Attribute> entities) {
// When we process the DeclareOp inside the OpenMP target region, all the
// variables get the DISubprogram of the parent function of the target op as
// the scope. In the codegen (to llvm ir), OpenMP target op results in the
@@ -717,8 +717,8 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
// Make sure that information about the imported modules is copied in the
// new function.
- llvm::SmallVector<mlir::LLVM::DINodeAttr> opEntities;
- for (mlir::LLVM::DINodeAttr N : entities) {
+ llvm::SmallVector<mlir::Attribute> opEntities;
+ for (mlir::Attribute N : entities) {
if (auto entity = mlir::dyn_cast<mlir::LLVM::DIImportedEntityAttr>(N)) {
auto importedEntity = mlir::LLVM::DIImportedEntityAttr::get(
context, entity.getTag(), spAttr, entity.getEntity(),
@@ -756,7 +756,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
});
mlir::LLVM::DISubprogramAttr spAttr;
- llvm::SmallVector<mlir::LLVM::DINodeAttr> retainedNodes;
+ llvm::SmallVector<mlir::Attribute> retainedNodes;
if (hasUseStmts) {
mlir::DistinctAttr recId =
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index e0573fb4081d4..20d75adfdb9f8 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -53,7 +53,7 @@ namespace llvm {
/// Track the RetainTypes, since they can be updated later on.
SmallVector<TrackingMDNodeRef, 4> AllRetainTypes;
SmallVector<DISubprogram *, 4> AllSubprograms;
- SmallVector<Metadata *, 4> AllGVs;
+ SmallVector<Metadata *, 4> Globals;
SmallVector<TrackingMDNodeRef, 4> ImportedModules;
/// Map Macro parent (which can be DIMacroFile or nullptr) to a list of
/// Metadata all of type DIMacroNode.
@@ -64,8 +64,8 @@ namespace llvm {
SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;
bool AllowUnresolvedNodes;
- /// Each subprogram's preserved local variables, labels, imported entities,
- /// and types.
+ /// Each subprogram's preserved local and static local variables, labels,
+ /// imported entities, and types.
///
/// Do not use a std::vector. Some versions of libc++ apparently copy
/// instead of move on grow operations, and TrackingMDRef is expensive to
diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h
index 01f8e97d24bce..18b94f8f66e48 100644
--- a/llvm/include/llvm/IR/DebugInfo.h
+++ b/llvm/include/llvm/IR/DebugInfo.h
@@ -124,6 +124,7 @@ class DebugInfoFinder {
private:
void processCompileUnit(DICompileUnit *CU);
+ void processGlobalVariableExpression(DIGlobalVariableExpression *GVE);
void processScope(DIScope *Scope);
void processType(DIType *DT);
void processVariable(DIVariable *DV);
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 6dfbb2c7e1bc5..846342bee6071 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2339,7 +2339,7 @@ class DISubprogram : public DILocalScope {
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
DISPFlags SPFlags, DICompileUnit *Unit,
DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
- DINodeArray RetainedNodes, DITypeArray ThrownTypes,
+ MDNodeArray RetainedNodes, DITypeArray ThrownTypes,
DINodeArray Annotations, StringRef TargetFuncName,
bool UsesKeyInstructions, StorageType Storage,
bool ShouldCreate = true) {
@@ -2380,7 +2380,7 @@ class DISubprogram : public DILocalScope {
DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
DITemplateParameterArray TemplateParams = nullptr,
- DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
+ DISubprogram *Declaration = nullptr, MDNodeArray RetainedNodes = nullptr,
DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr,
StringRef TargetFuncName = "", bool UsesKeyInstructions = false),
(Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
@@ -2509,7 +2509,7 @@ class DISubprogram : public DILocalScope {
return cast_or_null<DISubprogram>(getRawDeclaration());
}
void replaceDeclaration(DISubprogram *Decl) { replaceOperandWith(6, Decl); }
- DINodeArray getRetainedNodes() const {
+ MDNodeArray getRetainedNodes() const {
return cast_or_null<MDTuple>(getRawRetainedNodes());
}
DITypeArray getThrownTypes() const {
@@ -2548,19 +2548,24 @@ class DISubprogram : public DILocalScope {
void replaceRawLinkageName(MDString *LinkageName) {
replaceOperandWith(3, LinkageName);
}
- void replaceRetainedNodes(DINodeArray N) {
- replaceOperandWith(7, N.get());
+ void replaceRetainedNodes(MDNodeArray N) { replaceOperandWith(7, N.get()); }
+
+ template <typename IterT> void retainNodes(IterT NodesBegin, IterT NodesEnd) {
+ auto RetainedNodes = getRetainedNodes();
+ SmallVector<Metadata *> MDs(RetainedNodes.begin(), RetainedNodes.end());
+ MDs.append(NodesBegin, NodesEnd);
+ replaceRetainedNodes(MDNode::get(getContext(), MDs));
}
/// For the given retained node of DISubprogram, applies one of the
/// given functions depending on the type of the node.
template <typename T, typename MetadataT, typename FuncLVT,
typename FuncLabelT, typename FuncImportedEntityT,
- typename FuncTypeT, typename FuncUnknownT>
+ typename FuncTypeT, typename FuncGVET, typename FuncUnknownT>
static T visitRetainedNode(MetadataT *N, FuncLVT &&FuncLV,
FuncLabelT &&FuncLabel,
FuncImportedEntityT &&FuncIE, FuncTypeT &&FuncType,
- FuncUnknownT &&FuncUnknown) {
+ FuncGVET &&FuncGVE, FuncUnknownT &&FuncUnknown) {
static_assert(std::is_base_of_v<Metadata, MetadataT>,
"N must point to Metadata or const Metadata");
@@ -2572,6 +2577,8 @@ class DISubprogram : public DILocalScope {
return FuncIE(IE);
if (auto *Ty = dyn_cast<DIType>(N))
return FuncType(Ty);
+ if (auto *GVE = dyn_cast<DIGlobalVariableExpression>(N))
+ return FuncGVE(GVE);
return FuncUnknown(N);
}
@@ -2585,12 +2592,13 @@ class DISubprogram : public DILocalScope {
/// For each retained node, applies one of the given functions depending
/// on the type of a node.
template <typename FuncLVT, typename FuncLabelT, typename FuncImportedEntityT,
- typename FuncTypeT>
+ typename FuncTypeT, typename FuncGVET>
void forEachRetainedNode(FuncLVT &&FuncLV, FuncLabelT &&FuncLabel,
- FuncImportedEntityT &&FuncIE, FuncTypeT &&FuncType) {
+ FuncImportedEntityT &&FuncIE, FuncTypeT &&FuncType,
+ FuncGVET &&FuncGVE) {
for (MDNode *N : getRetainedNodes())
visitRetainedNode<void>(
- N, FuncLV, FuncLabel, FuncIE, FuncType,
+ N, FuncLV, FuncLabel, FuncIE, FuncType, FuncGVE,
[](auto *N) { llvm_unreachable("Unexpected retained node!"); });
}
@@ -2622,6 +2630,17 @@ class DISubprogram : public DILocalScope {
/// of a current scope for expression evaluation.
LLVM_ABI void cleanupRetainedNodes();
+ template <typename T> void cleanupRetainedNodesIf(T &&Pred) {
+ MDTuple *RetainedNodes = dyn_cast_or_null<MDTuple>(getRawRetainedNodes());
+ // As this is expected to be called during module loading, before
+ // stripping old or incorrect debug info, perform minimal sanity check.
+ if (!RetainedNodes)
+ return;
+ // replaceRetainedNodes() should not re-unique DISubprogram if new list is
+ // the same pointer.
+ replaceRetainedNodes(RetainedNodes->filter(Pred));
+ }
+
/// Calls SP->cleanupRetainedNodes() for a range of DISubprograms.
template <typename RangeT>
static void cleanupRetainedNodes(const RangeT &NewDistinctSPs) {
@@ -4817,6 +4836,24 @@ class DebugVariableAggregate : public DebugVariable {
template <>
struct DenseMapInfo<DebugVariableAggregate>
: public DenseMapInfo<DebugVariable> {};
+
+template <typename NodeT> static const DIScope *getScope(const NodeT *N) {
+ return N->getScope();
+}
+
+template <typename NodeT> static DIScope *getScope(NodeT *N) {
+ return N->getScope();
+}
+
+template <>
+[[maybe_unused]] const DIScope *
+getScope<>(const DIGlobalVariableExpression *N) {
+ return N->getVariable()->getScope();
+}
+template <>
+[[maybe_unused]] DIScope *getScope<>(DIGlobalVariableExpression *N) {
+ return N->getVariable()->getScope();
+}
} // end namespace llvm
#undef DEFINE_MDNODE_GET_UNPACK_IMPL
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 73adeb3416ab1..c0d0703135f68 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1546,6 +1546,17 @@ class MDTuple : public MDNode {
/// Shrink the operands by 1.
void pop_back() { resize(getNumOperands() - 1); }
+ /// Filter out tuple elements that do not satisfy predicate.
+ /// Return this if no elements should be filtered out (without re-uniquing).
+ template <typename T> MDTuple *filter(T &&Pred) {
+ ArrayRef<MDOperand> Ops = operands();
+ // Exit if no nodes should be removed.
+ if (llvm::all_of(Ops, Pred))
+ return this;
+ return get(getContext(),
+ to_vector_of<Metadata *>(llvm::make_filter_range(Ops, Pred)));
+ }
+
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind;
}
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 33062a0256bb8..40bc930d124f0 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -546,85 +546,64 @@ class MetadataLoader::MetadataLoaderImpl {
llvm::dyn_cast_or_null<DISubprogram>(S);
}
- /// Move local imports from DICompileUnit's 'imports' field to
- /// DISubprogram's retainedNodes.
- /// Move function-local enums from DICompileUnit's enums
- /// to DISubprogram's retainedNodes.
+ /// Map SP -> {Metadata} to store CU locals that should be attached to
+ /// subprogram retainedNodes list during CU upgrade.
+ using SPToEntitiesMap =
+ SmallDenseMap<DISubprogram *, SmallVector<Metadata *>>;
+
+ /// Retrieve the CU operand at position ListIndex, treat it as an MDTuple, and
+ /// remove all local debug info nodes from it. Fill SPToEntities map with
+ /// removed local nodes.
+ template <typename NodeT>
+ void upgradeOneCULocalsList(SPToEntitiesMap &SPToEntities, DICompileUnit *CU,
+ unsigned ListIndex) {
+ MDTuple *List = cast_if_present<MDTuple>(CU->getOperand(ListIndex));
+ if (!List)
+ return;
+
+ if (llvm::all_of(List->operands(), [](Metadata *MD) {
+ return !isa_and_nonnull<DILocalScope>(getScope(cast<NodeT>(MD)));
+ }))
+ return;
+
+ SmallVector<Metadata *> MDs;
+ for (Metadata *MD : List->operands()) {
+ DILocalScope *LS =
+ dyn_cast_or_null<DILocalScope>(getScope(cast<NodeT>(MD)));
+ if (!LS)
+ MDs.push_back(MD);
+ else if (auto *SP = findEnclosingSubprogram(LS))
+ SPToEntities[SP].push_back(MD);
+ }
+
+ CU->replaceOperandWith(ListIndex, MDNode::get(CU->getContext(), MDs));
+ }
+
+ /// Move function-local entities from DICompileUnit's 'imports',
+ /// 'enums', and 'globals' fields to DISubprogram's retainedNodes.
void upgradeCULocals() {
NamedMDNode *CUNodes = TheModule.getNamedMetadata("llvm.dbg.cu");
if (!CUNodes)
return;
- // Filter out elements of ToRemove from tuple T.
- auto FilterTuple = [this](MDNode *T,
- const SetVector<Metadata *> &ToRemove) {
- SmallVector<Metadata *> Result;
- for (Metadata *Op : T->operands())
- if (!ToRemove.contains(Op))
- Result.push_back(Op);
- return MDTuple::get(Context, Result);
- };
-
- // For each CU:
- // - Collect local metadata nodes from CU's imports: and enums: lists in
- // MetadataToRemove set.
- // - Remove metadata nodes of MetadataToRemove set from CU's imports: and
- // enums: lists.
- // - Group MetadataToRemove items by their parent subprograms (in
- // SPToEntities map).
- // - For each subprogram SP in SPToEntities:
- // - Append collected local metadata nodes to SP's retainedNodes: list.
+ SPToEntitiesMap SPToEntities;
for (MDNode *N : CUNodes->operands()) {
auto *CU = dyn_cast<DICompileUnit>(N);
if (!CU)
continue;
- SetVector<Metadata *> MetadataToRemove;
- // Collect imported entities to be moved.
- if (CU->getRawImportedEntities())
- for (Metadata *Op : CU->getImportedEntities()->operands()) {
- auto *IE = cast<DIImportedEntity>(Op);
- if (isa_and_nonnull<DILocalScope>(IE->getScope()))
- MetadataToRemove.insert(IE);
- }
- // Collect enums to be moved.
- if (CU->getRawEnumTypes())
- for (Metadata *Op : CU->getEnumTypes()->operands()) {
- auto *Enum = cast<DICompositeType>(Op);
- if (isa_and_nonnull<DILocalScope>(Enum->getScope()))
- MetadataToRemove.insert(Enum);
- }
-
- if (MetadataToRemove.empty())
- continue;
-
- // Remove entities with local scope from CU.
- if (CU->getRawImportedEntities())
- CU->replaceImportedEntities(
- FilterTuple(CU->getImportedEntities().get(), MetadataToRemove));
-
- // Remove enums with local scope from CU.
- if (CU->getRawEnumTypes())
- CU->replaceEnumTypes(
- FilterTuple(CU->getEnumTypes().get(), MetadataToRemove));
-
- // Find DISubprogram corresponding to each entity.
- SmallDenseMap<DISubprogram *, SmallVector<Metadata *>> SPToEntities;
- for (auto *I : MetadataToRemove) {
- DILocalScope *Scope =
- DISubprogram::getRetainedNodeScope(cast<DINode>(I));
- if (auto *SP = findEnclosingSubprogram(Scope))
- SPToEntities[SP].push_back(I);
- }
-
- // Update DISubprograms' retainedNodes.
- for (auto I = SPToEntities.begin(); I != SPToEntities.end(); ++I) {
- auto *SP = I->first;
- auto RetainedNodes = SP->getRetainedNodes();
- SmallVector<Metadata *> MDs(RetainedNodes.begin(), RetainedNodes.end());
- MDs.append(I->second);
- SP->replaceRetainedNodes(MDNode::get(Context, MDs));
- }
+ // Remove all static local variables from CU's globals list.
+ upgradeOneCULocalsList<DIGlobalVariableExpression>(SPToEntities, CU, 6);
+ // Remove all local imports from CU's imports list.
+ upgradeOneCULocalsList<DIImportedEntity>(SPToEntities, CU, 7);
+ // Remove all local types from CU's enums list.
+ upgradeOneCULocalsList<DICompositeType>(SPToEntities, CU, 4);
+
+ // Retain local entities removed from the CU in their corresponding
+ // subprograms.
+ for (auto &[SP, Nodes] : SPToEntities)
+ SP->retainNodes(Nodes.begin(), Nodes.end());
+ SPToEntities.clear();
}
ParentSubprogram.clear();
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 06353a0e039db..193379d7170d6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1451,6 +1451,10 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
// Grab the variable info that was squirreled away in the MMI side-table.
collectVariableInfoFromMFTable(Processed);
+ for (const MDNode *N : SP->getRetainedNodes())
+ if (const auto *GVE = dyn_cast<DIGlobalVariableExpression>(N))
+ collectGlobalOrStaticLocalVariableInfo(GVE);
+
for (const auto &I : DbgValues) {
InlinedEntity IV = I.first;
if (Processed.count(IV))
@@ -3236,9 +3240,54 @@ void CodeViewDebug::emitDebugInfoForUDTs(
}
}
+void CodeViewDebug::collectGlobalOrStaticLocalVariableInfo(
+ const DIGlobalVariableExpression *GVE) {
+ const DIGlobalVariable *DIGV = GVE->getVariable();
+ const DIExpression *DIE = GVE->getExpression();
+ // Don't emit string literals in CodeView, as the only useful parts are
+ // generally the filename and line number, which isn't possible to output
+ // in CodeView. String literals should be the only unnamed GlobalVariable
+ // with debug info.
+ if (DIGV->getName().empty())
+ return;
+
+ if ((DIE->getNumElements() == 2) &&
+ (DIE->getElement(0) == dwarf::DW_OP_plus_uconst))
+ // Record the constant offset for the variable.
+ //
+ // A Fortran common block uses this idiom to encode the offset
+ // of a variable from the common block's starting address.
+ CVGlobalVariableOffsets.insert(std::make_pair(DIGV, DIE->getElement(1)));
+
+ // Emit constant global variables in a global symbol section.
+ if (!GlobalMap.count(GVE) && DIE->isConstant())
+ GlobalVariables.emplace_back(CVGlobalVariable{DIGV, DIE});
+
+ const auto *GV = GlobalMap.lookup(GVE);
+ if (!GV || GV->isDeclarationForLinker())
+ return;
+
+ DIScope *Scope = DIGV->getScope();
+ SmallVector<CVGlobalVariable, 1> *VariableList;
+ if (Scope && isa<DILocalScope>(Scope)) {
+ // Locate a global variable list for this scope, creating one if
+ // necessary.
+ auto Insertion =
+ ScopeGlobals.insert({Scope, std::unique_ptr<GlobalVariableList>()});
+ if (Insertion.second)
+ Insertion.first->second = std::make_unique<GlobalVariableList>();
+ VariableList = Insertion.first->second.get();
+ } else if (GV->hasComdat()) {
+ // Emit this global variable into a COMDAT section.
+ VariableList = &ComdatVariables;
+ } else {
+ // Emit this global variable in a single global symbol section.
+ VariableList = &GlobalVariables;
+ }
+ VariableList->emplace_back(CVGlobalVariable{DIGV, GV});
+}
+
void CodeViewDebug::collectGlobalVariableInfo() {
- DenseMap<const DIGlobalVariableExpression *, const GlobalVariable *>
- GlobalMap;
for (const GlobalVariable &GV : MMI->getModule()->globals()) {
SmallVector<DIGlobalVariableExpression *, 1> GVEs;
GV.getDebugInfo(GVEs);
@@ -3250,51 +3299,7 @@ void CodeViewDebug::collectGlobalVariableInfo() {
for (const MDNode *Node : CUs->operands()) {
const auto *CU = cast<DICompileUnit>(Node);
for (const auto *GVE : CU->getGlobalVariables()) {
- const DIGlobalVariable *DIGV = GVE->getVariable();
- const DIExpression *DIE = GVE->getExpression();
- // Don't emit string literals in CodeView, as the only useful parts are
- // generally the filename and line number, which isn't possible to output
- // in CodeView. String literals should be the only unnamed GlobalVariable
- // with debug info.
- if (DIGV->getName().empty()) continue;
-
- if ((DIE->getNumElements() == 2) &&
- (DIE->getElement(0) == dwarf::DW_OP_plus_uconst))
- // Record the constant offset for the variable.
- //
- // A Fortran common block uses this idiom to encode the offset
- // of a variable from the common block's starting address.
- CVGlobalVariableOffsets.insert(
- std::make_pair(DIGV, DIE->getElement(1)));
-
- // Emit constant global variables in a global symbol section.
- if (GlobalMap.count(GVE) == 0 && DIE->isConstant()) {
- CVGlobalVariable CVGV = {DIGV, DIE};
- GlobalVariables.emplace_back(std::move(CVGV));
- }
-
- const auto *GV = GlobalMap.lookup(GVE);
- if (!GV || GV->isDeclarationForLinker())
- continue;
-
- DIScope *Scope = DIGV->getScope();
- SmallVector<CVGlobalVariable, 1> *VariableList;
- if (Scope && isa<DILocalScope>(Scope)) {
- // Locate a global variable list for this scope, creating one if
- // necessary.
- auto Insertion = ScopeGlobals.insert(
- {Scope, std::unique_ptr<GlobalVariableList>()});
- if (Insertion.second)
- Insertion.first->second = std::make_unique<GlobalVariableList>();
- VariableList = Insertion.first->second.get();
- } else if (GV->hasComdat())
- // Emit this global variable into a COMDAT section.
- VariableList = &ComdatVariables;
- else
- // Emit this global variable in a single global symbol section.
- VariableList = &GlobalVariables;
- CVGlobalVariable CVGV = {DIGV, GV};
- VariableList->emplace_back(std::move(CVGV));
+ collectGlobalOrStaticLocalVariableInfo(GVE);
}
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 04a75a21d7679..e28e0ab6da36b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -252,6 +252,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
// belong in. A null local scope represents the global scope.
typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList;
DenseMap<const DIScope*, std::unique_ptr<GlobalVariableList> > ScopeGlobals;
+ DenseMap<const DIGlobalVariableExpression *, const GlobalVariable *>
+ GlobalMap;
// Array of global variables which need to be emitted into a COMDAT section.
SmallVector<CVGlobalVariable, 1> ComdatVariables;
@@ -404,6 +406,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
void collectGlobalVariableInfo();
+ void
+ collectGlobalOrStaticLocalVariableInfo(const DIGlobalVariableExpression *GVE);
void collectVariableInfo(const DISubprogram *SP);
void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index cfd5dfa746c70..cfbb35d516534 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1522,6 +1522,8 @@ void DwarfDebug::endModule() {
DenseSet<DIGlobalVariable *> Processed;
for (auto *GVE : CUNode->getGlobalVariables()) {
DIGlobalVariable *GV = GVE->getVariable();
+ assert(!isa_and_nonnull<DILocalScope>(GV->getScope()) &&
+ "Unexpected function-local entity in 'globals' CU field.");
if (Processed.insert(GV).second)
CU->getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV]));
}
@@ -1534,14 +1536,20 @@ void DwarfDebug::endModule() {
}
// Emit function-local entities.
- for (const auto *D : CU->getDeferredLocalDecls()) {
- if (auto *IE = dyn_cast<DIImportedEntity>(D))
- CU->getOrCreateImportedEntityDIE(IE);
- else if (auto *Ty = dyn_cast<DIType>(D))
- CU->getOrCreateTypeDIE(Ty);
- else
- llvm_unreachable("Unexpected local retained node!");
- }
+ const auto Unexpected = [](const Metadata *N) {
+ llvm_unreachable("Unexpected local retained node!");
+ };
+ for (const auto *D : CU->getDeferredLocalDecls())
+ DISubprogram::visitRetainedNode<void>(
+ D, Unexpected, Unexpected,
+ [CU](const auto *IE) { CU->getOrCreateImportedEntityDIE(IE); },
+ [CU](const auto *Ty) { CU->getOrCreateTypeDIE(Ty); },
+ [&](const auto *GVE) {
+ DIGlobalVariable *GV = GVE->getVariable();
+ if (Processed.insert(GV).second)
+ CU->getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV]));
+ },
+ Unexpected);
// Emit base types.
CU->createBaseTypeDIEs();
@@ -2088,16 +2096,17 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
}
// Collect info for retained nodes.
- for (const DINode *DN : SP->getRetainedNodes()) {
- const auto *LS = getRetainedNodeScope(DN);
- if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
+ for (const MDNode *N : SP->getRetainedNodes()) {
+ const auto *LS = getRetainedNodeScope(N);
+ if (isa<DILocalVariable>(N) || isa<DILabel>(N)) {
+ auto *DN = cast<DINode>(N);
if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
continue;
LexicalScope *LexS = LScopes.findLexicalScope(LS);
if (LexS)
createConcreteEntity(TheCU, *LexS, DN, nullptr);
} else {
- LocalDeclsPerLS[LS].insert(DN);
+ LocalDeclsPerLS[LS].insert(N);
}
}
}
@@ -2897,12 +2906,13 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
#endif
for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
const auto *SP = cast<DISubprogram>(AScope->getScopeNode());
- for (const DINode *DN : SP->getRetainedNodes()) {
- const auto *LS = getRetainedNodeScope(DN);
+ for (const MDNode *N : SP->getRetainedNodes()) {
+ const auto *LS = getRetainedNodeScope(N);
// Ensure LexicalScope is created for the scope of this node.
auto *LexS = LScopes.getOrCreateAbstractScope(LS);
assert(LexS && "Expected the LexicalScope to be created.");
- if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
+ if (isa<DILocalVariable>(N) || isa<DILabel>(N)) {
+ auto *DN = cast<DINode>(N);
// Collect info for variables/labels that were optimized out.
if (!Processed.insert(InlinedEntity(DN, nullptr)).second ||
TheCU.getExistingAbstractEntity(DN))
@@ -2910,7 +2920,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
TheCU.createAbstractEntity(DN, LexS);
} else {
// Remember the node if this is a local declarations.
- LocalDeclsPerLS[LS].insert(DN);
+ LocalDeclsPerLS[LS].insert(N);
}
assert(
LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp
index eb9fa3c89a44e..5726955a029ef 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp
@@ -1447,13 +1447,15 @@ LVScope *LVIRReader::getOrCreateSubprogram(LVScope *Function,
}
// Check for additional retained nodes.
- for (const DINode *DN : SP->getRetainedNodes()) {
+ for (const MDNode *DN : SP->getRetainedNodes()) {
if (const auto *IE = dyn_cast<DIImportedEntity>(DN))
constructImportedEntity(Function, IE);
else if (const auto *TTP = dyn_cast<DITemplateTypeParameter>(DN))
constructTemplateTypeParameter(Function, TTP);
else if (const auto *TVP = dyn_cast<DITemplateValueParameter>(DN))
constructTemplateValueParameter(Function, TVP);
+ else if (const auto *GVE = dyn_cast<DIGlobalVariableExpression>(DN))
+ getOrCreateVariable(GVE);
}
applySubprogramAttributes(Function, SP);
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 5e9c3f627e10c..60854c11ff014 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -33,7 +33,7 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)
if (const auto &RTs = CUNode->getRetainedTypes())
AllRetainTypes.assign(RTs.begin(), RTs.end());
if (const auto &GVs = CUNode->getGlobalVariables())
- AllGVs.assign(GVs.begin(), GVs.end());
+ Globals.assign(GVs.begin(), GVs.end());
if (const auto &IMs = CUNode->getImportedEntities())
ImportedModules.assign(IMs.begin(), IMs.end());
if (const auto &MNs = CUNode->getMacros())
@@ -56,20 +56,19 @@ void DIBuilder::finalizeSubprogram(DISubprogram *SP) {
if (PN == SubprogramTrackedNodes.end())
return;
- SmallVector<Metadata *, 16> RetainedNodes;
- for (MDNode *N : PN->second) {
+ SetVector<Metadata *> RetainedNodes;
+ for (MDNode *N : llvm::concat<MDNode *>(SP->getRetainedNodes(), PN->second)) {
// If the tracked node N was temporary, and the DIBuilder user replaced it
// with a node that does not belong to SP or is non-local, do not add N to
// SP's retainedNodes list.
DILocalScope *Scope = dyn_cast_or_null<DILocalScope>(
DISubprogram::getRawRetainedNodeScope(N));
- if (!Scope || Scope->getSubprogram() != SP)
- continue;
-
- RetainedNodes.push_back(N);
+ if (Scope && Scope->getSubprogram() == SP)
+ RetainedNodes.insert(N);
}
- SP->replaceRetainedNodes(MDTuple::get(VMContext, RetainedNodes));
+ SP->replaceRetainedNodes(
+ MDTuple::get(VMContext, RetainedNodes.getArrayRef()));
}
void DIBuilder::finalize() {
@@ -103,8 +102,8 @@ void DIBuilder::finalize() {
if (auto *SP = dyn_cast<DISubprogram>(N))
finalizeSubprogram(SP);
- if (!AllGVs.empty())
- CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs));
+ if (!Globals.empty())
+ CUNode->replaceGlobalVariables(MDTuple::get(VMContext, Globals));
if (!ImportedModules.empty())
CUNode->replaceImportedEntities(MDTuple::get(
@@ -961,7 +960,10 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(
if (!Expr)
Expr = createExpression();
auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);
- AllGVs.push_back(N);
+ if (isa_and_nonnull<DILocalScope>(Context))
+ getSubprogramNodesTrackingVector(Context).emplace_back(N);
+ else
+ Globals.push_back(N);
return N;
}
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 0cd8351c52469..3adcab2c62888 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -197,13 +197,8 @@ void DebugInfoFinder::processModule(const Module &M) {
void DebugInfoFinder::processCompileUnit(DICompileUnit *CU) {
if (!addCompileUnit(CU))
return;
- for (auto *DIG : CU->getGlobalVariables()) {
- if (!addGlobalVariable(DIG))
- continue;
- auto *GV = DIG->getVariable();
- processScope(GV->getScope());
- processType(GV->getType());
- }
+ for (auto *GVE : CU->getGlobalVariables())
+ processGlobalVariableExpression(GVE);
for (auto *ET : CU->getEnumTypes())
processType(ET);
for (auto *RT : CU->getRetainedTypes())
@@ -217,6 +212,15 @@ void DebugInfoFinder::processCompileUnit(DICompileUnit *CU) {
processMacroNode(Macro, nullptr);
}
+void DebugInfoFinder::processGlobalVariableExpression(
+ DIGlobalVariableExpression *GVE) {
+ if (!addGlobalVariable(GVE))
+ return;
+ auto *GV = GVE->getVariable();
+ processScope(GV->getScope());
+ processType(GV->getType());
+}
+
void DebugInfoFinder::processInstruction(const Module &M,
const Instruction &I) {
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
@@ -407,7 +411,8 @@ void DebugInfoFinder::processSubprogram(DISubprogram *SP) {
SP->forEachRetainedNode(
[this](DILocalVariable *LV) { processVariable(LV); }, [](DILabel *L) {},
[this](DIImportedEntity *IE) { processImportedEntity(IE); },
- [this](DIType *T) { processType(T); });
+ [this](DIType *T) { processType(T); },
+ [this](auto *GVE) { return processGlobalVariableExpression(GVE); });
}
void DebugInfoFinder::processVariable(const DILocalVariable *DV) {
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 79b7ce040b552..88f7f2f6240e0 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1451,11 +1451,10 @@ bool DISubprogram::describes(const Function *F) const {
template <typename ScopeT, typename NodeT>
static ScopeT getRawRetainedNodeScopeInternal(NodeT *N) {
- auto getScope = [](auto *N) { return N->getScope(); };
-
+ auto getScopeLambda = [](auto *N) { return getScope(N); };
return DISubprogram::visitRetainedNode<ScopeT>(
- N, getScope, getScope, getScope, getScope,
- [](auto *N) { return nullptr; });
+ N, getScopeLambda, getScopeLambda, getScopeLambda, getScopeLambda,
+ getScopeLambda, [](auto *N) { return nullptr; });
}
const DIScope *DISubprogram::getRawRetainedNodeScope(const MDNode *N) {
@@ -1475,41 +1474,22 @@ DILocalScope *DISubprogram::getRetainedNodeScope(MDNode *N) {
}
void DISubprogram::cleanupRetainedNodes() {
- // Checks if a metadata node from retainedTypes is a type not belonging to
+ // Checks if a metadata node from retainedTypes is a type belonging to
// this subprogram.
- auto IsAlienType = [this](DINode *N) {
+ auto IsTypeInSP = [this](Metadata *N) {
auto *T = dyn_cast_or_null<DIType>(N);
if (!T)
- return false;
+ return true;
DISubprogram *TypeSP = nullptr;
// The type might have been global in the previously loaded IR modules.
if (auto *LS = dyn_cast_or_null<DILocalScope>(T->getScope()))
TypeSP = LS->getSubprogram();
- return this != TypeSP;
+ return this == TypeSP;
};
- // As this is expected to be called during module loading, before
- // stripping old or incorrect debug info, perform minimal sanity check.
- if (!isa_and_present<MDTuple>(getRawRetainedNodes()))
- return;
-
- MDTuple *RetainedNodes = cast<MDTuple>(getRawRetainedNodes());
- SmallVector<Metadata *> MDs;
- MDs.reserve(RetainedNodes->getNumOperands());
- for (const MDOperand &Node : RetainedNodes->operands()) {
- // Ignore malformed retainedNodes.
- if (Node && !isa<DINode>(Node))
- return;
-
- auto *N = cast_or_null<DINode>(Node);
- if (!IsAlienType(N))
- MDs.push_back(N);
- }
-
- if (MDs.size() != RetainedNodes->getNumOperands())
- replaceRetainedNodes(MDNode::get(getContext(), MDs));
+ cleanupRetainedNodesIf(IsTypeInSP);
}
DILexicalBlockBase::DILexicalBlockBase(LLVMContext &C, unsigned ID,
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 0744a91710b2e..0661a8316d740 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1464,8 +1464,12 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) {
if (auto *Array = N.getRawGlobalVariables()) {
CheckDI(isa<MDTuple>(Array), "invalid global variable list", &N, Array);
for (Metadata *Op : N.getGlobalVariables()->operands()) {
- CheckDI(Op && (isa<DIGlobalVariableExpression>(Op)),
- "invalid global variable ref", &N, Op);
+ auto *GVE = dyn_cast_or_null<DIGlobalVariableExpression>(Op);
+ CheckDI(GVE, "invalid global variable ref", &N, Op);
+ CheckDI(!isa_and_nonnull<DILocalScope>(GVE->getVariable()->getScope()),
+ "function-local variables are not allowed in a DICompileUnit's "
+ "global variables list",
+ &N, Op);
}
}
if (auto *Array = N.getRawImportedEntities()) {
@@ -1516,13 +1520,13 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
auto True = [](const Metadata *) { return true; };
auto False = [](const Metadata *) { return false; };
bool IsTypeCorrect = DISubprogram::visitRetainedNode<bool>(
- Op, True, True, True, True, False);
+ Op, True, True, True, True, True, False);
CheckDI(IsTypeCorrect,
"invalid retained nodes, expected DILocalVariable, DILabel, "
- "DIImportedEntity or DIType",
+ "DIImportedEntity, DIType or DIGlobalVariableExpression",
&N, Node, Op);
- auto *RetainedNode = cast<DINode>(Op);
+ auto *RetainedNode = cast<MDNode>(Op);
auto *RetainedNodeScope = dyn_cast_or_null<DILocalScope>(
DISubprogram::getRawRetainedNodeScope(RetainedNode));
CheckDI(RetainedNodeScope,
diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
index d65726bc59d68..a38d94b0da7ee 100644
--- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
+++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
@@ -209,7 +209,7 @@ bool BPFAbstractMemberAccess::run(Function &F) {
if (SP && SP->isDefinition()) {
for (DIType *Ty: SP->getType()->getTypeArray())
CheckAnonRecordType(nullptr, Ty);
- for (const DINode *DN : SP->getRetainedNodes()) {
+ for (const MDNode *DN : SP->getRetainedNodes()) {
if (const auto *DV = dyn_cast<DILocalVariable>(DN))
CheckAnonRecordType(nullptr, DV->getType());
}
diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index 53cd46f614b78..6de1d1eee7cc4 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -913,7 +913,7 @@ uint32_t BTFDebug::processDISubprogram(
uint32_t FuncId = addType(std::move(FuncTypeEntry));
// Process argument annotations.
- for (const DINode *DN : SP->getRetainedNodes()) {
+ for (const MDNode *DN : SP->getRetainedNodes()) {
if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
uint32_t Arg = DV->getArg();
if (Arg) {
@@ -1584,7 +1584,7 @@ void BTFDebug::beginFunctionImpl(const MachineFunction *MF) {
// Use RetainedNodes so we can collect all argument names
// even if the argument is not used.
SmallDenseMap<uint32_t, StringRef> FuncArgNames;
- for (const DINode *DN : SP->getRetainedNodes()) {
+ for (const MDNode *DN : SP->getRetainedNodes()) {
if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
// Collect function arguments for subprogram func type.
uint32_t Arg = DV->getArg();
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 3e3960ea24e88..4a9727f100e28 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -743,11 +743,7 @@ static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
// If we don't add __coro_frame to the RetainedNodes, user may get
// `no symbol __coro_frame in context` rather than `__coro_frame`
// is optimized out, which is more precise.
- auto RetainedNodes = DIS->getRetainedNodes();
- SmallVector<Metadata *, 32> RetainedNodesVec(RetainedNodes.begin(),
- RetainedNodes.end());
- RetainedNodesVec.push_back(FrameDIVar);
- DIS->replaceOperandWith(7, (MDTuple::get(F.getContext(), RetainedNodesVec)));
+ DIS->retainNodes(&FrameDIVar, &FrameDIVar + 1);
// Construct the location for the frame debug variable. The column number
// is fake but it should be fine.
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 73a8182949910..5e58b5c95f776 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -1904,6 +1904,7 @@ InstrLowerer::getOrCreateRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc) {
/*Decl=*/nullptr, /*TemplateParams=*/nullptr, /*AlignInBits=*/0,
Annotations);
BitmapPtr->addDebugInfo(DICounter);
+ DB.finalizeSubprogram(SP);
DB.finalize();
}
@@ -1980,6 +1981,7 @@ InstrLowerer::getOrCreateRegionCounters(InstrProfCntrInstBase *Inc) {
/*Decl=*/nullptr, /*TemplateParams=*/nullptr, /*AlignInBits=*/0,
Annotations);
CounterPtr->addDebugInfo(DICounter);
+ DB.finalizeSubprogram(SP);
DB.finalize();
}
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 75342a5d1894f..35de43f14bb23 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -105,6 +105,12 @@ createIdentityMDPredicate(const Function &F, CloneFunctionChangeType Changes) {
if (auto *S = dyn_cast_or_null<DILocalScope>(DV->getScope()))
return ShouldKeep(S->getSubprogram());
+ // DIGlobalVariableExpression representing static local variable may be
+ // encountered in DISubprogram's retainedNodes list. Do not remap it, and
+ // remove it from retainedNodes after mapping.
+ if (isa<DIGlobalVariableExpression>(MD))
+ return true;
+
// Clone types that are local to subprograms being cloned.
// Avoid cloning other types.
auto *Type = dyn_cast<DIType>(MD);
@@ -351,6 +357,15 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
NameSuffix, CodeInfo, TypeMapper, Materializer,
&IdentityMD);
+ // DIGlobalVariableExpressions representing static locals stay in the scope of
+ // OldSP after function cloning. Remove them from retainedNodes of NewSP.
+ if (DISubprogram *NewSP = NewFunc->getSubprogram())
+ NewSP->cleanupRetainedNodesIf([NewSP](Metadata *N) {
+ auto *GVE = dyn_cast_or_null<DIGlobalVariableExpression>(N);
+ return !GVE ||
+ DISubprogram::getRetainedNodeScope(GVE)->getSubprogram() == NewSP;
+ });
+
// Only update !llvm.dbg.cu for DifferentModule (not CloneModule). In the
// same module, the compile unit will already be listed (or not). When
// cloning a module, CloneModule() will handle creating the named metadata.
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp b/llvm/lib/Transforms/Utils/Debugify.cpp
index 8656a7c973451..a428ff4f451a4 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -440,7 +440,7 @@ bool llvm::collectDebugInfoMetadata(Module &M,
DebugInfoBeforePass.DIFunctions.insert({&F, SP});
if (SP) {
LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n');
- for (const DINode *DN : SP->getRetainedNodes()) {
+ for (const MDNode *DN : SP->getRetainedNodes()) {
if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
DebugInfoBeforePass.DIVariables[DV] = 0;
}
@@ -658,7 +658,7 @@ bool llvm::checkDebugInfoMetadata(Module &M,
if (SP) {
LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n');
- for (const DINode *DN : SP->getRetainedNodes()) {
+ for (const MDNode *DN : SP->getRetainedNodes()) {
if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
DebugInfoAfterPass.DIVariables[DV] = 0;
}
diff --git a/llvm/test/Bitcode/DIModule-fortran-external-module.ll b/llvm/test/Bitcode/DIModule-fortran-external-module.ll
index 5ca6031d6a1e3..c41e38d9bc136 100644
--- a/llvm/test/Bitcode/DIModule-fortran-external-module.ll
+++ b/llvm/test/Bitcode/DIModule-fortran-external-module.ll
@@ -41,12 +41,11 @@ attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
!3 = !DIFile(filename: "em.f90", directory: "tests")
!4 = !DISubroutineType(types: !5)
!5 = !{null}
-!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, imports: !7, splitDebugInlining: false, nameTableKind: None)
+!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !7, imports: !7, splitDebugInlining: false, nameTableKind: None)
!7 = !{}
-!8 = !{!0}
!10 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2)
!11 = !DIModule(scope: !2, name: "external_module", isDecl: true)
-!12 = !{!10, !13}
+!12 = !{!0, !10, !13}
!13 = !DILocalVariable(name: "x", scope: !2, file: !3, line: 5, type: !14)
!14 = !DIBasicType(name: "REAL*4", size: 32, encoding: DW_ATE_float)
!15 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/llvm/test/Bitcode/upgrade-cu-static-locals.ll b/llvm/test/Bitcode/upgrade-cu-static-locals.ll
new file mode 100644
index 0000000000000..54757b15642a0
--- /dev/null
+++ b/llvm/test/Bitcode/upgrade-cu-static-locals.ll
@@ -0,0 +1,108 @@
+; Test moving of local static variables from DICompileUnit 'globals' to DISubprogram's 'retainedNodes'
+;
+; RUN: llvm-dis -o - %s.bc | FileCheck %s
+
+; Function Attrs: norecurse nounwind
+define dso_local i32 @foo() local_unnamed_addr #0 !dbg !2 {
+ ret i32 0
+}
+
+define dso_local i32 @abc() local_unnamed_addr #0 !dbg !31 {
+ ret i32 0
+}
+
+define dso_local i32 @xyz() local_unnamed_addr #0 !dbg !32 {
+ ret i32 0
+}
+
+attributes #0 = { noinline optnone }
+
+!llvm.dbg.cu = !{!7, !30}
+!llvm.module.flags = !{!16, !17, !18}
+!llvm.ident = !{!19}
+
+; CHECK: ![[CU:[0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: ![[F_TEST:[0-9]+]], producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !{{.*}}, globals: ![[CU_GLOBALS:[0-9]+]]
+; CHECK: ![[CU_GLOBALS]] = !{![[AEXPR:[0-9]+]]}
+; CHECK: ![[AEXPR]] = !DIGlobalVariableExpression(var: ![[A:[0-9]+]]
+; CHECK: ![[A]] = distinct !DIGlobalVariable(name: "a", scope: ![[CU]]
+
+; CHECK: ![[CU30:[0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: ![[F_TEST2:[0-9]+]], producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !{{.*}}, globals: ![[CU30_GLOBALS:[0-9]+]]
+; CHECK: ![[CU30_GLOBALS]] = !{![[CAP_A_EXPR:[0-9]+]], ![[CAP_B_EXPR:[0-9]+]]}
+; CHECK: ![[CAP_A_EXPR]] = !DIGlobalVariableExpression(var: ![[CAP_A:[0-9]+]]
+; CHECK: ![[CAP_A]] = distinct !DIGlobalVariable(name: "A", scope: ![[CU30_GLOBALS:[0-9]+]]
+; CHECK: ![[CAP_B_EXPR]] = !DIGlobalVariableExpression(var: ![[CAP_B:[0-9]+]]
+; CHECK: ![[CAP_B]] = distinct !DIGlobalVariable(name: "B", scope: ![[CU30_GLOBALS:[0-9]+]]
+
+; CHECK: ![[FOO:[0-9]+]] = distinct !DISubprogram(name: "foo", scope: ![[F_TEST]], file: ![[F_TEST]], line: 2, type: !{{.*}}, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU]], retainedNodes: ![[FOO_RETAINED:[0-9]+]])
+; CHECK: ![[FOO_RETAINED]] = !{![[B_EXPR:[0-9]+]]}
+; CHECK: ![[B_EXPR]] = !DIGlobalVariableExpression(var: ![[B:[0-9]+]]
+; CHECK: ![[B]] = distinct !DIGlobalVariable(name: "b", scope: ![[FOO:[0-9]+]]
+
+; CHECK: ![[ABC:[0-9]+]] = distinct !DISubprogram(name: "abc", scope: ![[CU30]], file: ![[F_TEST2]], line: 2, type: !{{.*}}, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU30]], retainedNodes: ![[ABC_RETAINED:[0-9]+]])
+; CHECK: ![[ABC_RETAINED]] = !{![[ABC_A_EXPR:[0-9]+]], ![[ABC_B_EXPR:[0-9]+]]}
+; CHECK: ![[ABC_A_EXPR]] = !DIGlobalVariableExpression(var: ![[ABC_A:[0-9]+]]
+; CHECK: ![[ABC_A]] = distinct !DIGlobalVariable(name: "a", scope: ![[ABC]]
+; CHECK: ![[ABC_B_EXPR]] = !DIGlobalVariableExpression(var: ![[ABC_B:[0-9]+]]
+; CHECK: ![[ABC_B]] = distinct !DIGlobalVariable(name: "b", scope: ![[ABC]]
+
+; CHECK: ![[XYZ:[0-9]+]] = distinct !DISubprogram(name: "xyz", scope: ![[CU30]], file: ![[F_TEST2]], line: 2, type: !{{.*}}, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU30]], retainedNodes: ![[XYZ_RETAINED:[0-9]+]])
+; CHECK: ![[XYZ_RETAINED]] = !{![[XYZ_I:[0-9]+]], ![[XYZ_C_EXPR:[0-9]+]]}
+; CHECK: ![[XYZ_I]] = !DILocalVariable(name: "i", arg: 1, scope: ![[XYZ]], file: ![[F_TEST2]]
+; CHECK: ![[XYZ_C_EXPR]] = !DIGlobalVariableExpression(var: ![[XYZ_C:[0-9]+]]
+; CHECK: ![[XYZ_C]] = distinct !DIGlobalVariable(name: "c", scope: ![[XYZ]]
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true)
+!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8)
+!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
+!4 = !DISubroutineType(types: !5)
+!5 = !{!6}
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None)
+!8 = !{}
+!9 = !{!0, !10}
+!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
+!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true)
+!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13)
+!13 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!14 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !15)
+!15 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed)
+!16 = !{i32 2, !"Dwarf Version", i32 4}
+!17 = !{i32 2, !"Debug Info Version", i32 3}
+!18 = !{i32 1, !"wchar_size", i32 4}
+!19 = !{!"clang version 8.0.20181009 "}
+!20 = !DILocation(line: 4, column: 10, scope: !2)
+!21 = !{!22, !22, i64 0}
+!22 = !{!"omnipotent char", !23, i64 0}
+!23 = !{!"Simple C/C++ TBAA"}
+!24 = !DILocation(line: 4, column: 14, scope: !2)
+!25 = !{!26, !26, i64 0}
+!26 = !{!"short", !22, i64 0}
+!27 = !DILocation(line: 4, column: 12, scope: !2)
+
+; Check CU with several global and several local static variables.
+!30 = distinct !DICompileUnit(language: DW_LANG_C99, file: !50, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !45, nameTableKind: None)
+
+!31 = distinct !DISubprogram(name: "abc", scope: !30, file: !50, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !30, retainedNodes: !8)
+!32 = distinct !DISubprogram(name: "xyz", scope: !30, file: !50, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !30, retainedNodes: !46)
+
+; Globals
+!33 = !DIGlobalVariableExpression(var: !34, expr: !DIExpression())
+!34 = distinct !DIGlobalVariable(name: "A", scope: !30, file: !50, line: 1, type: !12, isLocal: true, isDefinition: true)
+!35 = !DIGlobalVariableExpression(var: !36, expr: !DIExpression())
+!36 = distinct !DIGlobalVariable(name: "B", scope: !30, file: !50, line: 1, type: !12, isLocal: true, isDefinition: true)
+
+; Static locals of abc
+!37 = !DIGlobalVariableExpression(var: !38, expr: !DIExpression())
+!38 = distinct !DIGlobalVariable(name: "a", scope: !31, file: !50, line: 3, type: !14, isLocal: true, isDefinition: true)
+!39 = !DIGlobalVariableExpression(var: !40, expr: !DIExpression())
+!40 = distinct !DIGlobalVariable(name: "b", scope: !31, file: !50, line: 3, type: !14, isLocal: true, isDefinition: true)
+
+; Locals of xyz
+!41 = !DIGlobalVariableExpression(var: !42, expr: !DIExpression())
+!42 = distinct !DIGlobalVariable(name: "c", scope: !32, file: !50, line: 3, type: !14, isLocal: true, isDefinition: true)
+!43 = !DILocalVariable(name: "i", line: 2, arg: 1, scope: !32, file: !50, type: !14)
+
+!45 = !{!37, !33, !39, !35, !41}
+!46 = !{!43}
+!50 = !DIFile(filename: "test2.c", directory: "/home/yhs/work/tests/llvm/bug")
diff --git a/llvm/test/Bitcode/upgrade-cu-static-locals.ll.bc b/llvm/test/Bitcode/upgrade-cu-static-locals.ll.bc
new file mode 100644
index 0000000000000..1c57ea7cea417
Binary files /dev/null and b/llvm/test/Bitcode/upgrade-cu-static-locals.ll.bc
diff er
diff --git a/llvm/test/CodeGen/AArch64/arm64-2011-03-17-AsmPrinterCrash.ll b/llvm/test/CodeGen/AArch64/arm64-2011-03-17-AsmPrinterCrash.ll
index 86658680fdf5a..b5398b1d49520 100644
--- a/llvm/test/CodeGen/AArch64/arm64-2011-03-17-AsmPrinterCrash.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-2011-03-17-AsmPrinterCrash.ll
@@ -28,12 +28,12 @@ attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!9, !10}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
!1 = !DIFile(filename: "print.i", directory: "/Volumes/Ebi/echeng/radars/r9146594")
!2 = !{!3}
!3 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression())
!4 = !DIGlobalVariable(name: "vsplive", scope: !5, file: !1, line: 617, type: !8, isLocal: true, isDefinition: true)
-!5 = distinct !DISubprogram(name: "drt_vsprintf", scope: !1, file: !1, line: 616, type: !6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0)
+!5 = distinct !DISubprogram(name: "drt_vsprintf", scope: !1, file: !1, line: 616, type: !6, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
!6 = !DISubroutineType(types: !7)
!7 = !{!8}
!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
diff --git a/llvm/test/CodeGen/BPF/BTF/static-var-inited-sec.ll b/llvm/test/CodeGen/BPF/BTF/static-var-inited-sec.ll
index deef48adee9ae..25e62b402dac4 100644
--- a/llvm/test/CodeGen/BPF/BTF/static-var-inited-sec.ll
+++ b/llvm/test/CodeGen/BPF/BTF/static-var-inited-sec.ll
@@ -99,14 +99,14 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8)
+!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !29)
!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None)
!8 = !{}
-!9 = !{!0, !10}
+!9 = !{!10}
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true)
!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13)
@@ -126,3 +126,4 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!26 = !{!"short", !22, i64 0}
!27 = !DILocation(line: 4, column: 12, scope: !2)
!28 = !DILocation(line: 4, column: 3, scope: !2)
+!29 = !{!0}
diff --git a/llvm/test/CodeGen/BPF/BTF/static-var-inited.ll b/llvm/test/CodeGen/BPF/BTF/static-var-inited.ll
index 8f29a83fedb13..9c7e492e170b4 100644
--- a/llvm/test/CodeGen/BPF/BTF/static-var-inited.ll
+++ b/llvm/test/CodeGen/BPF/BTF/static-var-inited.ll
@@ -99,14 +99,14 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8)
+!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !29)
!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None)
!8 = !{}
-!9 = !{!0, !10}
+!9 = !{!10}
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true)
!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13)
@@ -126,3 +126,4 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!26 = !{!"short", !22, i64 0}
!27 = !DILocation(line: 4, column: 12, scope: !2)
!28 = !DILocation(line: 4, column: 3, scope: !2)
+!29 = !{!0}
diff --git a/llvm/test/CodeGen/BPF/BTF/static-var-readonly-sec.ll b/llvm/test/CodeGen/BPF/BTF/static-var-readonly-sec.ll
index e16b4672f53d3..603673eee966e 100644
--- a/llvm/test/CodeGen/BPF/BTF/static-var-readonly-sec.ll
+++ b/llvm/test/CodeGen/BPF/BTF/static-var-readonly-sec.ll
@@ -105,14 +105,14 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !15, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8)
+!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !31)
!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None)
!8 = !{}
-!9 = !{!0, !10}
+!9 = !{!10}
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true)
!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13)
@@ -134,3 +134,4 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!28 = !{!"short", !24, i64 0}
!29 = !DILocation(line: 4, column: 12, scope: !2)
!30 = !DILocation(line: 4, column: 3, scope: !2)
+!31 = !{!0}
diff --git a/llvm/test/CodeGen/BPF/BTF/static-var-readonly.ll b/llvm/test/CodeGen/BPF/BTF/static-var-readonly.ll
index 1ddd49904135b..e5df7c1dc8c11 100644
--- a/llvm/test/CodeGen/BPF/BTF/static-var-readonly.ll
+++ b/llvm/test/CodeGen/BPF/BTF/static-var-readonly.ll
@@ -105,14 +105,14 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !15, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8)
+!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !31)
!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None)
!8 = !{}
-!9 = !{!0, !10}
+!9 = !{!10}
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true)
!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13)
@@ -134,3 +134,4 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!28 = !{!"short", !24, i64 0}
!29 = !DILocation(line: 4, column: 12, scope: !2)
!30 = !DILocation(line: 4, column: 3, scope: !2)
+!31 = !{!0}
diff --git a/llvm/test/CodeGen/BPF/BTF/static-var-sec.ll b/llvm/test/CodeGen/BPF/BTF/static-var-sec.ll
index 0ff8f2eb7db84..0168d30fffc2a 100644
--- a/llvm/test/CodeGen/BPF/BTF/static-var-sec.ll
+++ b/llvm/test/CodeGen/BPF/BTF/static-var-sec.ll
@@ -99,14 +99,14 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8)
+!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !29)
!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None)
!8 = !{}
-!9 = !{!0, !10}
+!9 = !{!10}
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true)
!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13)
@@ -126,3 +126,4 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!26 = !{!"short", !22, i64 0}
!27 = !DILocation(line: 4, column: 12, scope: !2)
!28 = !DILocation(line: 4, column: 3, scope: !2)
+!29 = !{!0}
diff --git a/llvm/test/CodeGen/BPF/BTF/static-var.ll b/llvm/test/CodeGen/BPF/BTF/static-var.ll
index f7710e3f3ce45..43781e4d91183 100644
--- a/llvm/test/CodeGen/BPF/BTF/static-var.ll
+++ b/llvm/test/CodeGen/BPF/BTF/static-var.ll
@@ -99,14 +99,14 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 3, type: !14, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !8)
+!2 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !7, retainedNodes: !29)
!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9, nameTableKind: None)
!8 = !{}
-!9 = !{!0, !10}
+!9 = !{!10}
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
!11 = distinct !DIGlobalVariable(name: "a", scope: !7, file: !3, line: 1, type: !12, isLocal: true, isDefinition: true)
!12 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !13)
@@ -126,3 +126,4 @@ define dso_local i32 @foo() local_unnamed_addr !dbg !2 {
!26 = !{!"short", !22, i64 0}
!27 = !DILocation(line: 4, column: 12, scope: !2)
!28 = !DILocation(line: 4, column: 3, scope: !2)
+!29 = !{!0}
diff --git a/llvm/test/CodeGen/BPF/dwarfdump.ll b/llvm/test/CodeGen/BPF/dwarfdump.ll
index d50c025c4e6f8..68b0779450eac 100644
--- a/llvm/test/CodeGen/BPF/dwarfdump.ll
+++ b/llvm/test/CodeGen/BPF/dwarfdump.ll
@@ -34,10 +34,9 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
!4 = !DISubroutineType(types: !5)
!5 = !{!6, !6, !6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 4.0.0 (trunk 287518) (llvm/trunk 287520)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, globals: !9)
+!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 4.0.0 (trunk 287518) (llvm/trunk 287520)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !8)
!8 = !{}
-!9 = !{!0}
-!10 = !{!11, !12}
+!10 = !{!0, !11, !12}
!11 = !DILocalVariable(name: "myvar_a", arg: 1, scope: !2, file: !3, line: 1, type: !6)
!12 = !DILocalVariable(name: "myvar_b", arg: 2, scope: !2, file: !3, line: 1, type: !6)
!13 = !{i32 2, !"Dwarf Version", i32 4}
diff --git a/llvm/test/CodeGen/PowerPC/pr24546.ll b/llvm/test/CodeGen/PowerPC/pr24546.ll
index a84b2e894f111..e4ff2ff9fe8a8 100644
--- a/llvm/test/CodeGen/PowerPC/pr24546.ll
+++ b/llvm/test/CodeGen/PowerPC/pr24546.ll
@@ -56,7 +56,7 @@ attributes #3 = { nounwind }
!llvm.module.flags = !{!29, !30}
!llvm.ident = !{!31}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, globals: !23)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3)
!1 = !DIFile(filename: "testcase.i", directory: "/tmp/glibc.build")
!2 = !{}
!3 = !{!4}
@@ -76,9 +76,8 @@ attributes #3 = { nounwind }
!18 = distinct !DISubprogram(name: "php_intpow10", scope: !1, file: !1, line: 1, type: !19, isLocal: true, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !21)
!19 = !DISubroutineType(types: !20)
!20 = !{!4, !9}
-!21 = !{!22}
+!21 = !{!22, !24}
!22 = !DILocalVariable(name: "power", arg: 1, scope: !18, file: !1, line: 1, type: !9)
-!23 = !{!24}
!24 = !DIGlobalVariableExpression(var: !DIGlobalVariable(name: "powers", scope: !18, file: !1, line: 3, type: !25, isLocal: true, isDefinition: true), expr: !DIExpression())
!25 = !DICompositeType(tag: DW_TAG_array_type, baseType: !26, size: 1472, align: 64, elements: !27)
!26 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !4)
diff --git a/llvm/test/CodeGen/X86/dbg-distringtype-uint.ll b/llvm/test/CodeGen/X86/dbg-distringtype-uint.ll
index 47b32967e68f7..f229ab1a6e34f 100644
--- a/llvm/test/CodeGen/X86/dbg-distringtype-uint.ll
+++ b/llvm/test/CodeGen/X86/dbg-distringtype-uint.ll
@@ -84,10 +84,9 @@ attributes #3 = { nofree nosync nounwind readnone speculatable willreturn }
!5 = !DISubroutineType(types: !6)
!6 = !{!7}
!7 = !DIStringType(name: "CHARACTER_0", size: 64)
-!8 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2745", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !9, globals: !10, splitDebugInlining: false, nameTableKind: None)
+!8 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2745", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !9, splitDebugInlining: false, nameTableKind: None)
!9 = !{}
-!10 = !{!0}
-!11 = !{!12, !14}
+!11 = !{!0, !12, !14}
!12 = !DILocalVariable(name: "esym", arg: 1, scope: !2, file: !3, line: 15, type: !13, flags: DIFlagArtificial)
!13 = !DIStringType(name: "CHARACTER_1", size: 64)
!14 = !DILocalVariable(name: "i", arg: 2, scope: !2, file: !3, line: 15, type: !15)
diff --git a/llvm/test/DebugInfo/COFF/fortran-basic.ll b/llvm/test/DebugInfo/COFF/fortran-basic.ll
index 8fa7a12e66919..854ba151039de 100644
--- a/llvm/test/DebugInfo/COFF/fortran-basic.ll
+++ b/llvm/test/DebugInfo/COFF/fortran-basic.ll
@@ -145,7 +145,7 @@ attributes #3 = { nocallback nofree nosync nounwind readnone speculatable willre
!5 = !DISubroutineType(types: !6)
!6 = !{null}
!7 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !4, producer: "Fortran", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false, nameTableKind: None)
-!8 = !{!0, !9, !12, !15, !21}
+!8 = !{!0, !9, !12}
!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression(DW_OP_plus_uconst, 8))
!10 = distinct !DIGlobalVariable(name: "L", linkageName: "COM", scope: !2, file: !4, line: 6, type: !11, isLocal: false, isDefinition: true)
!11 = !DIBasicType(name: "LOGICAL*4", size: 32, encoding: DW_ATE_boolean)
@@ -163,7 +163,7 @@ attributes #3 = { nocallback nofree nosync nounwind readnone speculatable willre
!23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, elements: !24)
!24 = !{!25}
!25 = !DISubrange(count: 10, lowerBound: 1)
-!26 = !{!27, !29, !31}
+!26 = !{!15, !21, !27, !29, !31}
!27 = !DILocalVariable(name: "CMP32", scope: !3, file: !4, line: 10, type: !28)
!28 = !DIBasicType(name: "COMPLEX*32", size: 256, encoding: DW_ATE_complex_float)
!29 = !DILocalVariable(name: "CMP16", scope: !3, file: !4, line: 9, type: !30)
diff --git a/llvm/test/DebugInfo/COFF/fortran-contained-proc.ll b/llvm/test/DebugInfo/COFF/fortran-contained-proc.ll
index 9d79d913ba57b..a9371cd7b0886 100644
--- a/llvm/test/DebugInfo/COFF/fortran-contained-proc.ll
+++ b/llvm/test/DebugInfo/COFF/fortran-contained-proc.ll
@@ -86,11 +86,11 @@ attributes #4 = { nounwind }
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "A", linkageName: "IF_TEST$A", scope: !2, file: !3, line: 11, type: !9, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "IF_TEST", linkageName: "MAIN__", scope: !3, file: !3, line: 9, type: !4, scopeLine: 9, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !6, retainedNodes: !8)
+!2 = distinct !DISubprogram(name: "IF_TEST", linkageName: "MAIN__", scope: !3, file: !3, line: 9, type: !4, scopeLine: 9, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !6, retainedNodes: !7)
!3 = !DIFile(filename: "tr1.f90", directory: "d:\\iusers\\cchen15\\examples\\tests\\jr14335")
!4 = !DISubroutineType(types: !5)
!5 = !{null}
-!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 22.0-1087", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !7, splitDebugInlining: false, nameTableKind: None)
+!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 22.0-1087", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false, nameTableKind: None)
!7 = !{!0}
!8 = !{}
!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
diff --git a/llvm/test/DebugInfo/COFF/global_visibility.ll b/llvm/test/DebugInfo/COFF/global_visibility.ll
index 499690a854eeb..12ff172fb5a02 100644
--- a/llvm/test/DebugInfo/COFF/global_visibility.ll
+++ b/llvm/test/DebugInfo/COFF/global_visibility.ll
@@ -208,10 +208,10 @@ attributes #2 = { nounwind readnone speculatable willreturn }
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 202f144bffd0be254a829924195e1b8ebabcbb79)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None)
!3 = !DIFile(filename: "a.cpp", directory: "F:\\llvm-project\\__test", checksumkind: CSK_MD5, checksum: "66a5399777dc9d37656fb00438bca542")
!4 = !{}
-!5 = !{!0, !6, !12, !14, !17, !19, !29}
+!5 = !{!0, !19, !29}
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
!7 = distinct !DIGlobalVariable(name: "local_int", scope: !8, file: !3, line: 15, type: !11, isLocal: true, isDefinition: true)
-!8 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAXXZ", scope: !3, file: !3, line: 14, type: !9, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !4)
+!8 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAXXZ", scope: !3, file: !3, line: 14, type: !9, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67)
!9 = !DISubroutineType(types: !10)
!10 = !{null}
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
@@ -219,7 +219,7 @@ attributes #2 = { nounwind readnone speculatable willreturn }
!13 = distinct !DIGlobalVariable(name: "nested_int", scope: !8, file: !3, line: 17, type: !11, isLocal: true, isDefinition: true)
!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression())
!15 = distinct !DIGlobalVariable(name: "local_int", scope: !16, file: !3, line: 24, type: !11, isLocal: true, isDefinition: true)
-!16 = distinct !DISubprogram(name: "bar", linkageName: "?bar@@YAXXZ", scope: !3, file: !3, line: 23, type: !9, scopeLine: 23, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !4)
+!16 = distinct !DISubprogram(name: "bar", linkageName: "?bar@@YAXXZ", scope: !3, file: !3, line: 23, type: !9, scopeLine: 23, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !68)
!17 = !DIGlobalVariableExpression(var: !18, expr: !DIExpression())
!18 = distinct !DIGlobalVariable(name: "nested_int", scope: !16, file: !3, line: 26, type: !11, isLocal: true, isDefinition: true)
!19 = !DIGlobalVariableExpression(var: !20, expr: !DIExpression())
@@ -270,3 +270,5 @@ attributes #2 = { nounwind readnone speculatable willreturn }
!64 = !DILocation(line: 6, scope: !60)
!65 = !DILocation(line: 7, scope: !60)
!66 = !DILocation(line: 8, scope: !60)
+!67 = !{!6, !12}
+!68 = !{!14, !17}
diff --git a/llvm/test/DebugInfo/COFF/type-quals.ll b/llvm/test/DebugInfo/COFF/type-quals.ll
index bca2590ea7969..fd71796ed567c 100644
--- a/llvm/test/DebugInfo/COFF/type-quals.ll
+++ b/llvm/test/DebugInfo/COFF/type-quals.ll
@@ -487,14 +487,14 @@ attributes #2 = { argmemonly nounwind }
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "str", scope: !2, file: !3, line: 18, type: !12, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "g", linkageName: "\01?g@@YAXAEIAH at Z", scope: !3, file: !3, line: 16, type: !4, isLocal: false, isDefinition: true, scopeLine: 16, flags: DIFlagPrototyped, isOptimized: false, unit: !9, retainedNodes: !10)
+!2 = distinct !DISubprogram(name: "g", linkageName: "\01?g@@YAXAEIAH at Z", scope: !3, file: !3, line: 16, type: !4, isLocal: false, isDefinition: true, scopeLine: 16, flags: DIFlagPrototyped, isOptimized: false, unit: !9, retainedNodes: !11)
!3 = !DIFile(filename: "m.cpp", directory: "C:\5CUsers\5CHui\5Ctmp\5Chui", checksumkind: CSK_MD5, checksum: "a8da0f4dca948db1ef1129c8728a881c")
!4 = !DISubroutineType(types: !5)
!5 = !{null, !6}
!6 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !7)
!7 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !8, size: 64)
!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!9 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !10, globals: !11)
+!9 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !10, globals: !10)
!10 = !{}
!11 = !{!0}
!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 32, elements: !15)
diff --git a/llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll b/llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll
index c26cba6be3b30..dd107d1adc627 100644
--- a/llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll
+++ b/llvm/test/DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll
@@ -14,13 +14,13 @@ attributes #0 = { nounwind readnone ssp uwtable }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!10}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.0 (trunk 139632)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !3)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.0 (trunk 139632)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2)
!1 = !DIFile(filename: "fb.c", directory: "/private/tmp")
!2 = !{}
!3 = !{!4}
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
!5 = !DIGlobalVariable(name: "bar", scope: !6, file: !1, line: 2, type: !9, isLocal: true, isDefinition: true)
-!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, unit: !0)
+!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, unit: !0, retainedNodes: !3)
!7 = !DISubroutineType(types: !8)
!8 = !{!9}
!9 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
diff --git a/llvm/test/DebugInfo/Generic/global-var-in-abstract-lexical-block.ll b/llvm/test/DebugInfo/Generic/global-var-in-abstract-lexical-block.ll
index e31fd295a4c94..4c4225264ab42 100644
--- a/llvm/test/DebugInfo/Generic/global-var-in-abstract-lexical-block.ll
+++ b/llvm/test/DebugInfo/Generic/global-var-in-abstract-lexical-block.ll
@@ -47,13 +47,13 @@ entry:
!1 = distinct !DIGlobalVariable(name: "static_local", linkageName: "_ZZ3fooPiE12static_local", scope: !2, file: !3, line: 3, type: !9, isLocal: true, isDefinition: true)
!2 = distinct !DILexicalBlock(scope: !4, file: !3, line: 2, column: 1)
!3 = !DIFile(filename: "test.cu", directory: "/")
-!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooPi", scope: !3, file: !3, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !10, retainedNodes: !12)
+!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooPi", scope: !3, file: !3, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !10, retainedNodes: !11)
!5 = !DISubroutineType(types: !6)
!6 = !{!7, !8}
!7 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "void")
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64, align: 64, dwarfAddressSpace: 12)
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!10 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "lgenfe: EDG 6.8", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !11)
+!10 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "lgenfe: EDG 6.8", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !12)
!11 = !{!0}
!12 = !{}
!13 = !{i32 1, !"Debug Info Version", i32 3}
diff --git a/llvm/test/DebugInfo/Generic/inlined-static-var.ll b/llvm/test/DebugInfo/Generic/inlined-static-var.ll
index 60c986fc2b648..99bca52c975dc 100644
--- a/llvm/test/DebugInfo/Generic/inlined-static-var.ll
+++ b/llvm/test/DebugInfo/Generic/inlined-static-var.ll
@@ -59,17 +59,17 @@ define dso_local i32 @_Z3foov() !dbg !26 {
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "B", scope: !2, file: !3, line: 5, type: !6, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "not_removed", linkageName: "_Z11not_removedv", scope: !3, file: !3, line: 5, type: !4, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
+!2 = distinct !DISubprogram(name: "not_removed", linkageName: "_Z11not_removedv", scope: !3, file: !3, line: 5, type: !4, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !9)
!3 = !DIFile(filename: "example.cpp", directory: "")
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None)
+!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
!8 = !DIFile(filename: "example.cpp", directory: "")
-!9 = !{!0, !10}
+!9 = !{!0}
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
!11 = distinct !DIGlobalVariable(name: "A", scope: !12, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true)
-!12 = distinct !DISubprogram(name: "removed", linkageName: "_Z7removedv", scope: !3, file: !3, line: 2, type: !4, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
+!12 = distinct !DISubprogram(name: "removed", linkageName: "_Z7removedv", scope: !3, file: !3, line: 2, type: !4, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !33)
!13 = !{}
!14 = !{i32 7, !"Dwarf Version", i32 4}
!15 = !{i32 2, !"Debug Info Version", i32 3}
@@ -90,3 +90,4 @@ define dso_local i32 @_Z3foov() !dbg !26 {
!30 = distinct !DILocation(line: 7, column: 32, scope: !26)
!31 = !DILocation(line: 7, column: 30, scope: !26)
!32 = !DILocation(line: 7, column: 13, scope: !26)
+!33 = !{!10}
diff --git a/llvm/test/DebugInfo/Generic/verifier-invalid-dicompileunit.ll b/llvm/test/DebugInfo/Generic/verifier-invalid-dicompileunit.ll
new file mode 100644
index 0000000000000..4535309a2f635
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/verifier-invalid-dicompileunit.ll
@@ -0,0 +1,65 @@
+; RUN: llvm-as -disable-output %s 2>&1 | FileCheck --match-full-lines %s
+
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!2, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !17, !20, !22}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !DIFile(filename: "-", directory: "")
+
+; CHECK: invalid file
+!2 = distinct !DICompileUnit(language: 0, file: !{})
+
+; CHECK: invalid filename
+!3 = !DIFile(filename: "", directory: "")
+!4 = distinct !DICompileUnit(language: 0, file: !3)
+
+; CHECK: invalid enum list
+!5 = distinct !DICompileUnit(language: 0, file: !1, enums: !1)
+
+; CHECK: invalid enum type
+!6 = distinct !DICompileUnit(language: 0, file: !1, enums: !{!1})
+
+; CHECK: invalid retained type list
+!7 = distinct !DICompileUnit(language: 0, file: !1, retainedTypes: !1)
+
+; CHECK: invalid retained type
+!8 = distinct !DICompileUnit(language: 0, file: !1, retainedTypes: !{!1})
+
+; CHECK: invalid global variable list
+!9 = distinct !DICompileUnit(language: 0, file: !1, globals: !1)
+
+; CHECK: invalid global variable ref
+!10 = distinct !DICompileUnit(language: 0, file: !1, globals: !{!1})
+
+; CHECK: invalid imported entity list
+!11 = distinct !DICompileUnit(language: 0, file: !1, imports: !1)
+
+; CHECK: invalid imported entity ref
+!12 = distinct !DICompileUnit(language: 0, file: !1, imports: !{!1})
+
+; CHECK: invalid macro list
+!13 = distinct !DICompileUnit(language: 0, file: !1, macros: !1)
+
+; CHECK: invalid macro ref
+!14 = distinct !DICompileUnit(language: 0, file: !1, macros: !{!1})
+
+define void @foo() !dbg !15 { ret void }
+!15 = distinct !DISubprogram(file: !1, type: !23)
+
+; CHECK: function-local imports are not allowed in a DICompileUnit's imported entities list
+!16 = distinct !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !15, entity: !15)
+!17 = distinct !DICompileUnit(language: 0, file: !1, imports: !{!16})
+
+; CHECK: function-local variables are not allowed in a DICompileUnit's global variables list
+!18 = !DIGlobalVariableExpression(var: !19, expr: !DIExpression())
+!19 = distinct !DIGlobalVariable(scope: !15)
+!20 = distinct !DICompileUnit(language: 0, file: !1, globals: !{!18})
+
+; CHECK: function-local enum in a DICompileUnit's enum list
+!21 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, scope: !15)
+!22 = distinct !DICompileUnit(language: 0, file: !1, enums: !{!21})
+
+; CHECK: warning: ignoring invalid debug info{{.*}}
+
+!23 = !DISubroutineType(types: !24)
+!24 = !{null}
diff --git a/llvm/test/DebugInfo/Generic/verifier-invalid-disubprogram.ll b/llvm/test/DebugInfo/Generic/verifier-invalid-disubprogram.ll
index 0a15453951749..4e5f0af1f051d 100644
--- a/llvm/test/DebugInfo/Generic/verifier-invalid-disubprogram.ll
+++ b/llvm/test/DebugInfo/Generic/verifier-invalid-disubprogram.ll
@@ -40,7 +40,7 @@ define void @invalid_subprogram_declaration() !dbg !9 { ret void }
define void @invalid_retained_nodes_list() !dbg !10 { ret void }
!10 = distinct !DISubprogram(type: !21, retainedNodes: !0)
-; CHECK: invalid retained nodes, expected DILocalVariable, DILabel, DIImportedEntity or DIType
+; CHECK: invalid retained nodes, expected DILocalVariable, DILabel, DIImportedEntity, DIType or DIGlobalVariableExpression
define void @invalid_retained_nodes_expected() !dbg !11 { ret void }
!11 = distinct !DISubprogram(type: !21, retainedNodes: !{!0})
diff --git a/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll b/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll
index 1a467ec72a75d..3a8ee66e9b797 100644
--- a/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll
+++ b/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll
@@ -116,7 +116,7 @@ attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memo
!1 = distinct !DIGlobalVariable(name: "bss_global", scope: !2, file: !3, line: 1, type: !7, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
!3 = !DIFile(filename: "t.cpp", directory: "/")
-!4 = !{!0, !5, !8, !15, !18, !24, !26}
+!4 = !{!0, !5, !8, !15, !24, !26}
!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
!6 = distinct !DIGlobalVariable(name: "data_global", scope: !2, file: !3, line: 2, type: !7, isLocal: false, isDefinition: true)
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
@@ -132,7 +132,7 @@ attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memo
!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 32)
!18 = !DIGlobalVariableExpression(var: !19, expr: !DIExpression())
!19 = distinct !DIGlobalVariable(name: "function_global", scope: !20, file: !3, line: 8, type: !7, isLocal: true, isDefinition: true)
-!20 = distinct !DISubprogram(name: "f", linkageName: "_Z1fv", scope: !3, file: !3, line: 7, type: !21, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!20 = distinct !DISubprogram(name: "f", linkageName: "_Z1fv", scope: !3, file: !3, line: 7, type: !21, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !47)
!21 = !DISubroutineType(types: !22)
!22 = !{!23}
!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32)
@@ -159,3 +159,4 @@ attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memo
!44 = !{!"int", !45, i64 0}
!45 = !{!"omnipotent char", !46, i64 0}
!46 = !{!"Simple C++ TBAA"}
+!47 = !{!18}
diff --git a/llvm/test/DebugInfo/X86/DW_AT_specification.ll b/llvm/test/DebugInfo/X86/DW_AT_specification.ll
index 826ec11782032..a8d01bb715c6d 100644
--- a/llvm/test/DebugInfo/X86/DW_AT_specification.ll
+++ b/llvm/test/DebugInfo/X86/DW_AT_specification.ll
@@ -23,13 +23,13 @@ entry:
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = !DIGlobalVariable(name: "x", scope: !2, file: !3, line: 5, type: !14, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", scope: null, file: !3, line: 4, type: !4, isLocal: false, isDefinition: true, scopeLine: 4, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !8, declaration: !11)
+!2 = distinct !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", scope: null, file: !3, line: 4, type: !4, isLocal: false, isDefinition: true, scopeLine: 4, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !8, declaration: !11, retainedNodes: !10)
!3 = !DIFile(filename: "nsNativeAppSupportBase.ii", directory: "/Users/espindola/mozilla-central/obj-x86_64-apple-darwin11.2.0/toolkit/library")
!4 = !DISubroutineType(types: !5)
!5 = !{null, !6}
!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, align: 64, flags: DIFlagArtificial)
!7 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !3, line: 1, flags: DIFlagFwdDecl)
-!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 3.0 ()", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !9, retainedTypes: !9, globals: !10, imports: !9)
+!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 3.0 ()", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !9, retainedTypes: !9, imports: !9)
!9 = !{}
!10 = !{!0}
!11 = !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", scope: !12, file: !3, line: 2, type: !4, isLocal: false, isDefinition: false, scopeLine: 2, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false)
diff --git a/llvm/test/DebugInfo/X86/dbg-value-transfer-order.ll b/llvm/test/DebugInfo/X86/dbg-value-transfer-order.ll
index 1261bc3a1cf6f..56e6be7489e48 100644
--- a/llvm/test/DebugInfo/X86/dbg-value-transfer-order.ll
+++ b/llvm/test/DebugInfo/X86/dbg-value-transfer-order.ll
@@ -97,13 +97,13 @@ attributes #1 = { nounwind readnone speculatable }
!llvm.module.flags = !{!14, !15, !16, !17}
!llvm.ident = !{!18}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2)
!1 = !DIFile(filename: "t.c", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "f80d0003faf76554dfdec6c95da285cc")
!2 = !{}
!3 = !{!4}
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
!5 = distinct !DIGlobalVariable(name: "pages", scope: !6, file: !1, line: 18, type: !10, isLocal: true, isDefinition: true)
-!6 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !7, isLocal: false, isDefinition: true, scopeLine: 17, isOptimized: true, unit: !0, retainedNodes: !2)
+!6 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !7, isLocal: false, isDefinition: true, scopeLine: 17, isOptimized: true, unit: !0, retainedNodes: !3)
!7 = !DISubroutineType(types: !8)
!8 = !{!9}
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
diff --git a/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll b/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll
index 60010c50a8f12..c8e1cb29e5df9 100644
--- a/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll
+++ b/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll
@@ -73,13 +73,12 @@ attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
!3 = !DIFile(filename: "em.f90", directory: "tests")
!4 = !DISubroutineType(types: !5)
!5 = !{null}
-!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, splitDebugInlining: false, nameTableKind: None)
+!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, splitDebugInlining: false, nameTableKind: None)
!7 = !{}
-!8 = !{!0}
!9 = !{}
!10 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2)
!11 = !DIModule(scope: !2, name: "external_module", isDecl: true)
-!12 = !{!10, !13}
+!12 = !{!0, !10, !13}
!13 = !DILocalVariable(name: "x", scope: !2, file: !3, line: 5, type: !14)
!14 = !DIBasicType(name: "REAL*4", size: 32, encoding: DW_ATE_float)
!15 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/llvm/test/DebugInfo/X86/distringtype.ll b/llvm/test/DebugInfo/X86/distringtype.ll
index 80ec7d628a0ee..2930c3aed0485 100644
--- a/llvm/test/DebugInfo/X86/distringtype.ll
+++ b/llvm/test/DebugInfo/X86/distringtype.ll
@@ -145,11 +145,11 @@ attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "deferred", linkageName: "assumedlength_$DEFERRED", scope: !2, file: !3, line: 2, type: !9, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "assumedlength", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !7)
+!2 = distinct !DISubprogram(name: "assumedlength", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !8)
!3 = !DIFile(filename: "distring.f90", directory: "/iusers/cchen15/examples/tests")
!4 = !DISubroutineType(types: !5)
!5 = !{null}
-!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2142", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, splitDebugInlining: false, nameTableKind: None)
+!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2142", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, splitDebugInlining: false, nameTableKind: None)
!7 = !{}
!8 = !{!0}
!9 = !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
diff --git a/llvm/test/DebugInfo/X86/global-sra-struct-fit-segment.ll b/llvm/test/DebugInfo/X86/global-sra-struct-fit-segment.ll
index ab48ef2411f35..f1d619e7cb187 100644
--- a/llvm/test/DebugInfo/X86/global-sra-struct-fit-segment.ll
+++ b/llvm/test/DebugInfo/X86/global-sra-struct-fit-segment.ll
@@ -90,9 +90,9 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata)
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "nodea", scope: !2, file: !3, line: 3, type: !9, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "sub", scope: !4, file: !3, line: 1, type: !12, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition, unit: !4)
+!2 = distinct !DISubprogram(name: "sub", scope: !4, file: !3, line: 1, type: !12, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition, unit: !4, retainedNodes: !6)
!3 = !DIFile(filename: "global-sra-struct-fit-segment.f90", directory: "/tmp")
-!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g -O0 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5, nameTableKind: None)
+!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g -O0 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !5, imports: !5, nameTableKind: None)
!5 = !{}
!6 = !{!0, !7, !10, !29}
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4))
diff --git a/llvm/test/DebugInfo/X86/global-sra-struct-part-overlap-segment.ll b/llvm/test/DebugInfo/X86/global-sra-struct-part-overlap-segment.ll
index 9dd865edbbdad..3dd4d9c6cca7f 100644
--- a/llvm/test/DebugInfo/X86/global-sra-struct-part-overlap-segment.ll
+++ b/llvm/test/DebugInfo/X86/global-sra-struct-part-overlap-segment.ll
@@ -171,10 +171,10 @@ declare void @llvm.experimental.noalias.scope.decl(metadata)
!3 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !4, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: true, flags: "'+flang -g -O3 -S -emit-llvm -o -O1'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5, nameTableKind: None)
!4 = !DIFile(filename: "global-sra-struct-part-overlap-segment_0.f90", directory: "/tmp")
!5 = !{}
-!6 = !{!0, !7, !29}
+!6 = !{!0}
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
!8 = distinct !DIGlobalVariable(name: "rvar", scope: !9, file: !4, line: 13, type: !19, isLocal: true, isDefinition: true)
-!9 = distinct !DISubprogram(name: "bar", scope: !2, file: !4, line: 10, type: !10, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3)
+!9 = distinct !DISubprogram(name: "bar", scope: !2, file: !4, line: 10, type: !10, scopeLine: 10, retainedNodes: !32, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3)
!10 = !DISubroutineType(types: !11)
!11 = !{null, !12, !16}
!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 96, align: 32, elements: !14)
@@ -197,3 +197,4 @@ declare void @llvm.experimental.noalias.scope.decl(metadata)
!29 = !DIGlobalVariableExpression(var: !30, expr: !DIExpression(DW_OP_plus_uconst, 4))
!30 = distinct !DIGlobalVariable(name: "ivar", scope: !9, file: !4, line: 13, type: !31, isLocal: true, isDefinition: true)
!31 = !DIBasicType(name: "integer*8", size: 64, align: 32, encoding: DW_ATE_signed)
+!32 = !{!7, !29}
diff --git a/llvm/test/DebugInfo/X86/gnu-public-names.ll b/llvm/test/DebugInfo/X86/gnu-public-names.ll
index 5d81468f55379..1c3ac763c6dc6 100644
--- a/llvm/test/DebugInfo/X86/gnu-public-names.ll
+++ b/llvm/test/DebugInfo/X86/gnu-public-names.ll
@@ -332,7 +332,7 @@ attributes #1 = { nounwind readnone speculatable }
!14 = !{!15}
!15 = !DIEnumerator(name: "named_enum_class_enumerator", value: 0)
!16 = !{!13}
-!17 = !{!0, !18, !29, !32, !37, !44, !47, !50}
+!17 = !{!0, !18, !29, !32, !44, !47, !50}
!18 = !DIGlobalVariableExpression(var: !19, expr: !DIExpression())
!19 = distinct !DIGlobalVariable(name: "global_variable", scope: !2, file: !3, line: 13, type: !20, isLocal: false, isDefinition: true)
!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C", file: !3, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !21, identifier: "_ZTS1C")
@@ -354,7 +354,7 @@ attributes #1 = { nounwind readnone speculatable }
!36 = !DIDerivedType(tag: DW_TAG_member, name: "A", scope: !34, file: !3, line: 22, baseType: !13, size: 32)
!37 = !DIGlobalVariableExpression(var: !38, expr: !DIExpression())
!38 = distinct !DIGlobalVariable(name: "z", scope: !39, file: !3, line: 33, type: !13, isLocal: true, isDefinition: true)
-!39 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !3, file: !3, line: 32, type: !40, scopeLine: 32, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !43)
+!39 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !3, file: !3, line: 32, type: !40, scopeLine: 32, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !91)
!40 = !DISubroutineType(types: !41)
!41 = !{!42}
!42 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
@@ -406,3 +406,4 @@ attributes #1 = { nounwind readnone speculatable }
!88 = !DILocation(line: 59, column: 68, scope: !78)
!89 = !DILocation(line: 60, column: 32, scope: !78)
!90 = !DILocation(line: 59, column: 3, scope: !78)
+!91 = !{!37}
diff --git a/llvm/test/DebugInfo/X86/lexical-block-static-var.ll b/llvm/test/DebugInfo/X86/lexical-block-static-var.ll
new file mode 100644
index 0000000000000..2c90ac02d4306
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/lexical-block-static-var.ll
@@ -0,0 +1,145 @@
+; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s
+
+; inline __attribute__((always_inline))
+; int removed() {
+; {
+; static int A;
+; return A++;
+; }
+; }
+;
+; __attribute__((always_inline))
+; int not_removed() {
+; {
+; static int B;
+; return B++;
+; }
+; }
+;
+; int foo() {
+; {
+; static int C;
+; return ++C + removed() + not_removed();
+; }
+; }
+
+; CHECK: DW_TAG_compile_unit
+
+; Out-of-line definition of `not_removed()`.
+; The empty lexical block is created to match abstract origin.
+; CHECK: DW_TAG_subprogram
+; CHECK: DW_AT_abstract_origin {{.*}} "_Z11not_removedv"
+; CHECK: DW_TAG_lexical_block
+; CHECK: NULL
+
+; Abstract definition of `removed()`
+; CHECK: DW_TAG_subprogram
+; CHECK: DW_AT_name ("removed")
+; CHECK: DW_AT_inline (DW_INL_inlined)
+; CHECK: DW_TAG_lexical_block
+; CHECK: DW_TAG_variable
+; CHECK: DW_AT_name ("A")
+; CHECK: DW_AT_location (DW_OP_addr 0x0)
+; CHECK: NULL
+; CHECK: NULL
+; CHECK: DW_TAG_base_type
+
+; Abstract definition of `not_removed()`
+; CHECK: DW_TAG_subprogram
+; CHECK: DW_AT_name ("not_removed")
+; CHECK: DW_AT_inline (DW_INL_inlined)
+; CHECK: DW_TAG_lexical_block
+; CHECK: DW_TAG_variable
+; CHECK: DW_AT_name ("B")
+; CHECK: DW_AT_location (DW_OP_addr 0x0)
+; CHECK: NULL
+; CHECK: NULL
+
+; Definition of foo().
+; CHECK: DW_TAG_subprogram
+; CHECK: DW_AT_name ("foo")
+; CHECK: DW_TAG_lexical_block
+; CHECK: DW_TAG_inlined_subroutine
+; CHECK: DW_TAG_lexical_block
+; CHECK: NULL
+; CHECK: DW_TAG_inlined_subroutine
+; CHECK: DW_TAG_lexical_block
+; CHECK: NULL
+; CHECK: DW_TAG_variable
+; CHECK: DW_AT_name ("C")
+; CHECK: DW_AT_location (DW_OP_addr 0x0)
+; CHECK: NULL
+; CHECK: NULL
+; CHECK: NULL
+
+target triple = "x86_64-unknown-linux-gnu"
+
+ at _ZZ11not_removedvE1B = internal global i32 0, align 4, !dbg !0
+ at _ZZ3foovE1C = internal global i32 0, align 4, !dbg !10
+ at _ZZ7removedvE1A = linkonce_odr dso_local global i32 0, align 4, !dbg !15
+
+define dso_local i32 @_Z11not_removedv() !dbg !4 {
+entry:
+ %0 = load i32, i32* @_ZZ11not_removedvE1B, align 4, !dbg !25
+ %inc = add nsw i32 %0, 1, !dbg !25
+ store i32 %inc, i32* @_ZZ11not_removedvE1B, align 4, !dbg !25
+ ret i32 %0, !dbg !26
+}
+
+define dso_local i32 @_Z3foov() !dbg !13 {
+entry:
+ %0 = load i32, i32* @_ZZ3foovE1C, align 4, !dbg !27
+ %inc = add nsw i32 %0, 1, !dbg !27
+ store i32 %inc, i32* @_ZZ3foovE1C, align 4, !dbg !27
+ %1 = load i32, i32* @_ZZ7removedvE1A, align 4, !dbg !28
+ %inc.i3 = add nsw i32 %1, 1, !dbg !28
+ store i32 %inc.i3, i32* @_ZZ7removedvE1A, align 4, !dbg !28
+ %add = add nsw i32 %inc, %1, !dbg !30
+ %2 = load i32, i32* @_ZZ11not_removedvE1B, align 4, !dbg !31
+ %inc.i = add nsw i32 %2, 1, !dbg !31
+ store i32 %inc.i, i32* @_ZZ11not_removedvE1B, align 4, !dbg !31
+ %add2 = add nsw i32 %add, %2, !dbg !33
+ ret i32 %add2, !dbg !34
+}
+
+!llvm.dbg.cu = !{!8}
+!llvm.module.flags = !{!19, !20, !21, !22, !23}
+!llvm.ident = !{!24}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "B", scope: !2, file: !3, line: 13, type: !7, isLocal: true, isDefinition: true)
+!2 = distinct !DILexicalBlock(scope: !4, file: !3, line: 12, column: 3)
+!3 = !DIFile(filename: "test_static.cpp", directory: "/")
+!4 = distinct !DISubprogram(name: "not_removed", linkageName: "_Z11not_removedv", scope: !3, file: !3, line: 11, type: !5, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !8, retainedNodes: !35)
+!5 = !DISubroutineType(types: !6)
+!6 = !{!7}
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!9 = !{!15}
+!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
+!11 = distinct !DIGlobalVariable(name: "C", scope: !12, file: !3, line: 20, type: !7, isLocal: true, isDefinition: true)
+!12 = distinct !DILexicalBlock(scope: !13, file: !3, line: 19, column: 3)
+!13 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !3, file: !3, line: 18, type: !5, scopeLine: 18, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !8, retainedNodes: !36)
+!14 = !{}
+!15 = !DIGlobalVariableExpression(var: !16, expr: !DIExpression())
+!16 = distinct !DIGlobalVariable(name: "A", scope: !17, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true)
+!17 = distinct !DILexicalBlock(scope: !18, file: !3, line: 4, column: 3)
+!18 = distinct !DISubprogram(name: "removed", linkageName: "_Z7removedv", scope: !3, file: !3, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !8, retainedNodes: !9)
+!19 = !{i32 7, !"Dwarf Version", i32 4}
+!20 = !{i32 2, !"Debug Info Version", i32 3}
+!21 = !{i32 1, !"wchar_size", i32 4}
+!22 = !{i32 7, !"uwtable", i32 1}
+!23 = !{i32 7, !"frame-pointer", i32 2}
+!24 = !{!"clang version 14.0.0"}
+!25 = !DILocation(line: 14, column: 13, scope: !2)
+!26 = !DILocation(line: 14, column: 5, scope: !2)
+!27 = !DILocation(line: 21, column: 12, scope: !12)
+!28 = !DILocation(line: 6, column: 13, scope: !17, inlinedAt: !29)
+!29 = distinct !DILocation(line: 21, column: 18, scope: !12)
+!30 = !DILocation(line: 21, column: 16, scope: !12)
+!31 = !DILocation(line: 14, column: 13, scope: !2, inlinedAt: !32)
+!32 = distinct !DILocation(line: 21, column: 30, scope: !12)
+!33 = !DILocation(line: 21, column: 28, scope: !12)
+!34 = !DILocation(line: 21, column: 5, scope: !12)
+!35 = !{!0}
+!36 = !{!10}
diff --git a/llvm/test/DebugInfo/X86/namelist1.ll b/llvm/test/DebugInfo/X86/namelist1.ll
index 5132c894e8138..8e70809f67e9a 100644
--- a/llvm/test/DebugInfo/X86/namelist1.ll
+++ b/llvm/test/DebugInfo/X86/namelist1.ll
@@ -47,9 +47,9 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_plus_uconst, 120))
!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 3, type: !9, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 1, type: !7, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4)
+!2 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 1, type: !7, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4, retainedNodes: !6)
!3 = !DIFile(filename: "namelist.f90", directory: "/dir")
-!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g namelist.f90 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5, nameTableKind: None)
+!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g namelist.f90 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, imports: !5, nameTableKind: None)
!5 = !{}
!6 = !{!0}
!7 = !DISubroutineType(cc: DW_CC_program, types: !8)
diff --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
index 786c78d33337b..99c24b08c0d75 100644
--- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
+++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
@@ -19,39 +19,39 @@
; INSTRREF-SAME: debug-instr-number 2
; CHECK-NEXT: [[REG3:%[0-9]+]]:gr32 = PHI
; INSTRREF-SAME: debug-instr-number 3
-; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(2, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 16), dbg-instr-ref(3, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 10, 32), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 42, 13), dbg-instr-ref(2, 0)
-; DBGVALUE-NEXT: DBG_VALUE [[REG1]], $noreg, !13, !DIExpression(DW_OP_LLVM_fragment, 0, 32)
-; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, !13, !DIExpression(DW_OP_LLVM_fragment, 32, 32)
-; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg, !13, !DIExpression(DW_OP_LLVM_fragment, 64, 16)
-; DBGVALUE-NEXT: DBG_VALUE [[REG1]], $noreg, !12, !DIExpression(DW_OP_LLVM_fragment, 10, 32)
-; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, !12, !DIExpression(DW_OP_LLVM_fragment, 42, 13)
+; INSTRREF-NEXT: DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(2, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 16), dbg-instr-ref(3, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !15, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 10, 32), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !15, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 42, 13), dbg-instr-ref(2, 0)
+; DBGVALUE-NEXT: DBG_VALUE [[REG1]], $noreg, !16, !DIExpression(DW_OP_LLVM_fragment, 0, 32)
+; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, !16, !DIExpression(DW_OP_LLVM_fragment, 32, 32)
+; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg, !16, !DIExpression(DW_OP_LLVM_fragment, 64, 16)
+; DBGVALUE-NEXT: DBG_VALUE [[REG1]], $noreg, !15, !DIExpression(DW_OP_LLVM_fragment, 10, 32)
+; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, !15, !DIExpression(DW_OP_LLVM_fragment, 42, 13)
; CHECK-NOT: DBG_
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-w64-windows-gnu"
; Function Attrs: nounwind readnone
-define dso_local i64 @nextafterl(i80 %a, i1 %arg) local_unnamed_addr #0 !dbg !6 {
+define dso_local i64 @nextafterl(i80 %a, i1 %arg) local_unnamed_addr #0 !dbg !5 {
entry:
- br i1 %arg, label %if.else, label %if.then13, !dbg !28
+ br i1 %arg, label %if.else, label %if.then13, !dbg !27
if.then13: ; preds = %entry
- %u.sroa.0.8.insert.insert = or i80 %a, 2222, !dbg !29
- br label %if.end36, !dbg !33
+ %u.sroa.0.8.insert.insert = or i80 %a, 2222, !dbg !28
+ br label %if.end36, !dbg !32
if.else: ; preds = %entry
br label %if.end36
if.end36: ; preds = %if.else, %if.then13
%u.sroa.0.1.in = phi i80 [ %u.sroa.0.8.insert.insert, %if.then13 ], [ 1234567, %if.else ]
- call void @llvm.dbg.value(metadata i80 %u.sroa.0.1.in, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 80)), !dbg !34
- call void @llvm.dbg.value(metadata i80 %u.sroa.0.1.in, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 10, 45)), !dbg !34
- %u.sroa.0.0.extract.ashr = ashr i80 %u.sroa.0.1.in, 8, !dbg !35
- %u.sroa.0.0.extract.trunc = trunc i80 %u.sroa.0.0.extract.ashr to i64, !dbg !35
+ call void @llvm.dbg.value(metadata i80 %u.sroa.0.1.in, metadata !16, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 80)), !dbg !33
+ call void @llvm.dbg.value(metadata i80 %u.sroa.0.1.in, metadata !15, metadata !DIExpression(DW_OP_LLVM_fragment, 10, 45)), !dbg !33
+ %u.sroa.0.0.extract.ashr = ashr i80 %u.sroa.0.1.in, 8, !dbg !34
+ %u.sroa.0.0.extract.trunc = trunc i80 %u.sroa.0.0.extract.ashr to i64, !dbg !34
ret i64 %u.sroa.0.0.extract.trunc
}
@@ -62,42 +62,41 @@ attributes #0 = { nounwind readnone }
attributes #1 = { nounwind readnone speculatable }
!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!26, !27}
+!llvm.module.flags = !{!4, !3}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 (trunk 330808) (llvm/trunk 330813)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 (trunk 330808) (llvm/trunk 330813)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2)
!1 = !DIFile(filename: "pr37321.c", directory: "")
!2 = !{}
-!3 = !{!4}
-!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
-!5 = distinct !DIGlobalVariable(name: "normal_bit", scope: !6, file: !1, line: 31, type: !25, isLocal: true, isDefinition: true)
-!6 = distinct !DISubprogram(name: "nextafterl", scope: !1, file: !1, line: 17, type: !7, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !10)
-!7 = !DISubroutineType(types: !8)
-!8 = !{!9, !9, !9}
-!9 = !DIBasicType(name: "long double", size: 96, encoding: DW_ATE_float)
-!10 = !{!11, !12, !13}
-!11 = !DILocalVariable(name: "x", arg: 1, scope: !6, file: !1, line: 17, type: !9)
-!12 = !DILocalVariable(name: "y", arg: 2, scope: !6, file: !1, line: 17, type: !9)
-!13 = !DILocalVariable(name: "u", scope: !6, file: !1, line: 27, type: !14)
-!14 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !6, file: !1, line: 19, size: 128, elements: !15)
-!15 = !{!16, !17}
-!16 = !DIDerivedType(tag: DW_TAG_member, name: "ld", scope: !14, file: !1, line: 20, baseType: !9, size: 96)
-!17 = !DIDerivedType(tag: DW_TAG_member, name: "parts", scope: !14, file: !1, line: 26, baseType: !18, size: 128)
-!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !14, file: !1, line: 21, size: 128, elements: !19)
-!19 = !{!20, !22, !24}
-!20 = !DIDerivedType(tag: DW_TAG_member, name: "mantissa", scope: !18, file: !1, line: 23, baseType: !21, size: 64)
-!21 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
-!22 = !DIDerivedType(tag: DW_TAG_member, name: "expn", scope: !18, file: !1, line: 24, baseType: !23, size: 16, offset: 64)
-!23 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned)
-!24 = !DIDerivedType(tag: DW_TAG_member, name: "pad", scope: !18, file: !1, line: 25, baseType: !23, size: 16, offset: 80)
-!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !21)
-!26 = !{i32 2, !"Debug Info Version", i32 3}
-!27 = !{i32 1, !"wchar_size", i32 2}
-!28 = !DILocation(line: 47, column: 7, scope: !6)
-!29 = !DILocation(line: 51, column: 14, scope: !30)
-!30 = distinct !DILexicalBlock(scope: !31, file: !1, line: 50, column: 11)
-!31 = distinct !DILexicalBlock(scope: !32, file: !1, line: 48, column: 5)
-!32 = distinct !DILexicalBlock(scope: !6, file: !1, line: 47, column: 7)
-!33 = !DILocation(line: 51, column: 2, scope: !30)
-!34 = !DILocation(line: 27, column: 5, scope: !6)
-!35 = !DILocation(line: 63, column: 22, scope: !36)
-!36 = distinct !DILexicalBlock(scope: !6, file: !1, line: 62, column: 7)
+!3 = !{i32 1, !"wchar_size", i32 2}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = distinct !DISubprogram(name: "nextafterl", scope: !1, file: !1, line: 17, type: !6, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !9)
+!6 = !DISubroutineType(types: !7)
+!7 = !{!8, !8, !8}
+!8 = !DIBasicType(name: "long double", size: 96, encoding: DW_ATE_float)
+!9 = !{!10, !14, !15, !16}
+!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
+!11 = distinct !DIGlobalVariable(name: "normal_bit", scope: !5, file: !1, line: 31, type: !12, isLocal: true, isDefinition: true)
+!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13)
+!13 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
+!14 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !1, line: 17, type: !8)
+!15 = !DILocalVariable(name: "y", arg: 2, scope: !5, file: !1, line: 17, type: !8)
+!16 = !DILocalVariable(name: "u", scope: !5, file: !1, line: 27, type: !24)
+!17 = !DIDerivedType(tag: DW_TAG_member, name: "parts", scope: !24, file: !1, line: 26, baseType: !18, size: 128)
+!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !24, file: !1, line: 21, size: 128, elements: !19)
+!19 = !{!20, !21, !23}
+!20 = !DIDerivedType(tag: DW_TAG_member, name: "mantissa", scope: !18, file: !1, line: 23, baseType: !13, size: 64)
+!21 = !DIDerivedType(tag: DW_TAG_member, name: "expn", scope: !18, file: !1, line: 24, baseType: !22, size: 16, offset: 64)
+!22 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned)
+!23 = !DIDerivedType(tag: DW_TAG_member, name: "pad", scope: !18, file: !1, line: 25, baseType: !22, size: 16, offset: 80)
+!24 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !5, file: !1, line: 19, size: 128, elements: !25)
+!25 = !{!26, !17}
+!26 = !DIDerivedType(tag: DW_TAG_member, name: "ld", scope: !24, file: !1, line: 20, baseType: !8, size: 96)
+!27 = !DILocation(line: 47, column: 7, scope: !5)
+!28 = !DILocation(line: 51, column: 14, scope: !29)
+!29 = distinct !DILexicalBlock(scope: !30, file: !1, line: 50, column: 11)
+!30 = distinct !DILexicalBlock(scope: !31, file: !1, line: 48, column: 5)
+!31 = distinct !DILexicalBlock(scope: !5, file: !1, line: 47, column: 7)
+!32 = !DILocation(line: 51, column: 2, scope: !29)
+!33 = !DILocation(line: 27, column: 5, scope: !5)
+!34 = !DILocation(line: 63, column: 22, scope: !35)
+!35 = distinct !DILexicalBlock(scope: !5, file: !1, line: 62, column: 7)
diff --git a/llvm/test/DebugInfo/duplicate_dbgvalue.ll b/llvm/test/DebugInfo/duplicate_dbgvalue.ll
index 8fb3eeb74e012..21d97aef2c810 100644
--- a/llvm/test/DebugInfo/duplicate_dbgvalue.ll
+++ b/llvm/test/DebugInfo/duplicate_dbgvalue.ll
@@ -107,11 +107,11 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "res", scope: !2, file: !3, type: !9, isLocal: true, isDefinition: true)
-!2 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 1, type: !12, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4)
+!2 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 1, type: !12, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4, retainedNodes: !60)
!3 = !DIFile(filename: "duplicate-dbgvalue.f90", directory: "/dir")
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5)
!5 = !{}
-!6 = !{!0, !7, !10}
+!6 = !{!7, !10}
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
!8 = distinct !DIGlobalVariable(name: "res", scope: !4, file: !3, type: !9, isLocal: true, isDefinition: true)
!9 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
@@ -165,3 +165,4 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
!57 = !{!"unlimited ptr", !58, i64 0}
!58 = !{!"Flang FAA 3"}
!59 = !DILocation(line: 15, column: 1, scope: !52)
+!60 = !{!0}
diff --git a/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-bitmap.ll b/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-bitmap.ll
index 29bd0037a7e8b..43a1db5b2cf4e 100644
--- a/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-bitmap.ll
+++ b/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-bitmap.ll
@@ -22,7 +22,7 @@ define void @_Z3foov() !dbg !12 {
call void @llvm.instrprof.increment(ptr @__profn_foo, i64 12345678, i32 2, i32 0)
call void @llvm.instrprof.mcdc.parameters(ptr @__profn_foo, i64 12345678, i32 1)
call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @__profn_foo, i64 12345678, i32 0, ptr %mcdc.addr)
- ret void
+ ret void, !dbg !17
}
declare void @llvm.instrprof.increment(ptr, i64, i32, i32)
@@ -50,6 +50,7 @@ declare void @llvm.instrprof.mcdc.tvbitmap.update(ptr, i64, i32, ptr)
!14 = !DISubroutineType(types: !15)
!15 = !{null}
!16 = !{}
+!17 = !DILocation(line: 1, column: 1, scope: !12)
; CHECK-DWARF: DW_TAG_compile_unit
; CHECK-DWARF: DW_TAG_subprogram
diff --git a/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll b/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
index 84eaab33701a4..c1a610791be2b 100644
--- a/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
+++ b/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
@@ -20,7 +20,7 @@
define void @_Z3foov() !dbg !12 {
call void @llvm.instrprof.increment(ptr @__profn_foo, i64 12345678, i32 2, i32 0)
- ret void
+ ret void, !dbg !17
}
declare void @llvm.instrprof.increment(ptr, i64, i32, i32)
@@ -46,6 +46,7 @@ declare void @llvm.instrprof.increment(ptr, i64, i32, i32)
!14 = !DISubroutineType(types: !15)
!15 = !{null}
!16 = !{}
+!17 = !DILocation(line: 1, scope: !12)
; CHECK-DWARF: DW_TAG_compile_unit
; CHECK-DWARF: DW_TAG_subprogram
diff --git a/llvm/test/Transforms/Util/clone-dicompileunit.ll b/llvm/test/Transforms/Util/clone-dicompileunit.ll
index c417aafdaced3..ba40aa32c1428 100644
--- a/llvm/test/Transforms/Util/clone-dicompileunit.ll
+++ b/llvm/test/Transforms/Util/clone-dicompileunit.ll
@@ -25,18 +25,23 @@
; CHECK: DICompileUnit
; CHECK-NOT: DICompileUnit
+; CHECK: DISubprogram
+; CHECK-NOT: DICompileUnit
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux"
+define void @foo() !dbg !6 {
+ ret void
+}
+
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!28, !29}
!llvm.ident = !{!30}
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3)
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2)
!1 = !DIFile(filename: "p.cpp", directory: "/usr/local/google/home/pcc/b682773-2-repro/small2")
!2 = !{}
-!3 = !{!4}
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
!5 = distinct !DIGlobalVariable(name: "a", scope: !6, file: !1, line: 5, type: !27, isLocal: true, isDefinition: true)
!6 = distinct !DISubprogram(name: "m_fn2<B>", linkageName: "_ZN1A5m_fn2IZ3foovE1BEEvv", scope: !7, file: !1, line: 5, type: !8, isLocal: true, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !11, declaration: !23, retainedNodes: !24)
@@ -57,7 +62,7 @@ target triple = "x86_64-unknown-linux"
!21 = !{null, !22}
!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
!23 = !DISubprogram(name: "m_fn2<B>", linkageName: "_ZN1A5m_fn2IZ3foovE1BEEvv", scope: !7, file: !1, line: 5, type: !8, isLocal: false, isDefinition: false, scopeLine: 5, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: true, templateParams: !11)
-!24 = !{!25}
+!24 = !{!25, !4}
!25 = !DILocalVariable(name: "this", arg: 1, scope: !6, type: !26, flags: DIFlagArtificial | DIFlagObjectPointer)
!26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
!27 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll
index 45b7574f1843e..aeee0b3d95764 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll
@@ -25,7 +25,7 @@ declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
!1 = distinct !DIGlobalVariable(name: "TGlobal", scope: !2, file: !3, line: 1, type: !7, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, emissionKind: FullDebug, globals: !4)
!3 = !DIFile(filename: "ThreadLocalStorage.cpp", directory: "")
-!4 = !{!0, !5, !8}
+!4 = !{!0, !5}
!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
!6 = distinct !DIGlobalVariable(name: "NGlobal", scope: !2, file: !3, line: 2, type: !7, isLocal: false, isDefinition: true)
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
@@ -34,7 +34,7 @@ declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
!10 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !13)
!11 = !DISubroutineType(types: !12)
!12 = !{null}
-!13 = !{}
+!13 = !{!8}
!14 = !{i32 7, !"Dwarf Version", i32 5}
!15 = !{i32 2, !"Debug Info Version", i32 3}
!22 = !DILocation(line: 5, scope: !10)
diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp
index 38888cd9e3666..667bbff2a41d1 100644
--- a/llvm/unittests/Transforms/Utils/CloningTest.cpp
+++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp
@@ -835,7 +835,7 @@ TEST(CloneFunction, CloneFunctionWithRetainedNodes) {
!6 = distinct !DILexicalBlock(scope: !4, file: !1, line: 1)
!7 = !DILocation(line: 1, scope: !6, inlinedAt: !8)
!8 = !DILocation(line: 10, scope: !3)
- !9 = !{!15, !17, !18, !23, !26, !28, !30}
+ !9 = !{!15, !17, !18, !23, !26, !28, !30, !33}
!14 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, scope: !0, file: !1, line: 13, size: 200, elements: !{})
!15 = !DILocalVariable(name: "a", scope: !3)
!16 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, scope: !3, file: !1, line: 13, size: 208, elements: !{})
@@ -853,6 +853,8 @@ TEST(CloneFunction, CloneFunctionWithRetainedNodes) {
!30 = !DILocalVariable(name: "const_ptr", scope: !3, type: !29)
!31 = !DISubroutineType(types: !32)
!32 = !{null}
+ !33 = !DIGlobalVariableExpression(var: !34, expr: !DIExpression())
+ !34 = distinct !DIGlobalVariable(name: "global_var", scope: !3, file: !1, line: 5, type: !22, isLocal: true, isDefinition: true)
)";
LLVMContext Context;
@@ -880,8 +882,10 @@ TEST(CloneFunction, CloneFunctionWithRetainedNodes) {
DISubprogram *ClonedSP = ClonedFunc->getSubprogram();
EXPECT_NE(FuncSP, nullptr);
EXPECT_NE(ClonedSP, nullptr);
- EXPECT_EQ(FuncSP->getRetainedNodes().size(), 7u);
- EXPECT_EQ(FuncSP->getRetainedNodes().size(),
+ EXPECT_EQ(FuncSP->getRetainedNodes().size(), 8u);
+ // DIGlobalVariableExpressions should be excluded from retainedNodes of the
+ // cloned DISubprogram, as we don't clone them.
+ EXPECT_EQ(FuncSP->getRetainedNodes().size() - 1,
ClonedSP->getRetainedNodes().size());
// Ensure that Orig node is a clone of Copy by checking that they are
@@ -896,17 +900,20 @@ TEST(CloneFunction, CloneFunctionWithRetainedNodes) {
// Check that retained nodes are cloned.
unsigned I = 0;
- auto CheckRetainedNode = [&](auto *Node) {
+ auto CheckRetainedNode = [&](auto *Copy) {
// The order of retained nodes should be preserved.
- auto *Copy =
- cast<std::decay_t<decltype(*Node)>>(ClonedSP->getRetainedNodes()[I]);
+ auto *Node =
+ cast<std::decay_t<decltype(*Copy)>>(FuncSP->getRetainedNodes()[I]);
CheckNodeIsCloned(Node, Copy);
++I;
};
- FuncSP->forEachRetainedNode(CheckRetainedNode, CheckRetainedNode,
- CheckRetainedNode, CheckRetainedNode);
+ ClonedSP->forEachRetainedNode(
+ CheckRetainedNode, CheckRetainedNode, CheckRetainedNode,
+ CheckRetainedNode, [](MDNode *_) {
+ FAIL() << "DIGlobalVariableExpression should not be cloned.";
+ });
auto ToDerived = [](const DIType *Ty) { return cast<DIDerivedType>(Ty); };
@@ -1195,6 +1202,15 @@ TEST_F(CloneModule, Subprogram) {
EXPECT_EQ(SP->getName(), "f");
EXPECT_EQ(SP->getFile()->getFilename(), "filename.c");
EXPECT_EQ(SP->getLine(), (unsigned)4);
+
+ // Check static locals have the correct scope.
+ MDNodeArray LocalDeclsArray = SP->getRetainedNodes();
+ EXPECT_EQ(LocalDeclsArray.size(), 2U);
+ for (auto *Node : LocalDeclsArray) {
+ auto *GVExpr = cast<DIGlobalVariableExpression>(Node);
+ DIGlobalVariable *GV = GVExpr->getVariable();
+ EXPECT_EQ(GV->getScope(), SP);
+ }
}
TEST_F(CloneModule, FunctionDeclarationMetadata) {
@@ -1252,14 +1268,6 @@ TEST_F(CloneModule, CompileUnit) {
DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
EXPECT_TRUE(SP != nullptr);
EXPECT_EQ(SP->getUnit(), CU);
-
- // Check globals listed in CU have the correct scope
- DIGlobalVariableExpressionArray GlobalArray = CU->getGlobalVariables();
- EXPECT_EQ(GlobalArray.size(), 2U);
- for (DIGlobalVariableExpression *GVExpr : GlobalArray) {
- DIGlobalVariable *GV = GVExpr->getVariable();
- EXPECT_EQ(GV->getScope(), SP);
- }
}
TEST_F(CloneModule, Comdat) {
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 9474afb897119..72497a5328f78 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -710,36 +710,34 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
[LLVM_DIRecursiveTypeAttrInterface],
"DILocalScopeAttr"> {
let parameters = (ins
- // DIRecursiveTypeAttrInterface specific parameters.
- OptionalParameter<"DistinctAttr">:$recId,
- OptionalParameter<"bool">:$isRecSelf,
- // DISubprogramAttr specific parameters.
- OptionalParameter<"DistinctAttr">:$id,
- OptionalParameter<"DICompileUnitAttr">:$compileUnit,
- OptionalParameter<"DIScopeAttr">:$scope,
- OptionalParameter<"StringAttr">:$name,
- OptionalParameter<"StringAttr">:$linkageName,
- OptionalParameter<"DIFileAttr">:$file,
- OptionalParameter<"unsigned">:$line,
- OptionalParameter<"unsigned">:$scopeLine,
- OptionalParameter<"DISubprogramFlags">:$subprogramFlags,
- OptionalParameter<"DISubroutineTypeAttr">:$type,
- OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes,
- OptionalArrayRefParameter<"DINodeAttr">:$annotations
- );
- let builders = [
- AttrBuilder<(ins
- "DistinctAttr":$id, "DICompileUnitAttr":$compileUnit,
- "DIScopeAttr":$scope, "StringAttr":$name, "StringAttr":$linkageName,
- "DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
- "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type,
- "ArrayRef<DINodeAttr>":$retainedNodes, "ArrayRef<DINodeAttr>":$annotations
- ), [{
+ // DIRecursiveTypeAttrInterface specific parameters.
+ OptionalParameter<"DistinctAttr">:$recId,
+ OptionalParameter<"bool">:$isRecSelf,
+ // DISubprogramAttr specific parameters.
+ OptionalParameter<"DistinctAttr">:$id,
+ OptionalParameter<"DICompileUnitAttr">:$compileUnit,
+ OptionalParameter<"DIScopeAttr">:$scope,
+ OptionalParameter<"StringAttr">:$name,
+ OptionalParameter<"StringAttr">:$linkageName,
+ OptionalParameter<"DIFileAttr">:$file,
+ OptionalParameter<"unsigned">:$line,
+ OptionalParameter<"unsigned">:$scopeLine,
+ OptionalParameter<"DISubprogramFlags">:$subprogramFlags,
+ OptionalParameter<"DISubroutineTypeAttr">:$type,
+ OptionalArrayRefParameter<"Attribute">:$retainedNodes,
+ OptionalArrayRefParameter<"DINodeAttr">:$annotations);
+ let builders = [AttrBuilder<
+ (ins "DistinctAttr":$id, "DICompileUnitAttr":$compileUnit,
+ "DIScopeAttr":$scope, "StringAttr":$name, "StringAttr":$linkageName,
+ "DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
+ "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type,
+ "ArrayRef<Attribute>":$retainedNodes,
+ "ArrayRef<DINodeAttr>":$annotations),
+ [{
return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/false, id, compileUnit,
scope, name, linkageName, file, line, scopeLine,
subprogramFlags, type, retainedNodes, annotations);
- }]>
- ];
+ }]>];
let assemblyFormat = "`<` struct(params) `>`";
let extraClassDeclaration = [{
/// Requirements of DIRecursiveTypeAttrInterface.
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index a5040d5104ab9..b25a8c8a9829e 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -150,23 +150,21 @@ def DICompileUnitAttr : DialectAttribute<(attr
// DISubprogramAttr
//===----------------------------------------------------------------------===//
-def DISubprogramAttr : DialectAttribute<(attr
- OptionalAttribute<"DistinctAttr">:$recId,
- Bool:$isRecSelf,
- OptionalAttribute<"DistinctAttr">:$id,
- OptionalAttribute<"DICompileUnitAttr">:$compileUnit,
- OptionalAttribute<"DIScopeAttr">:$scope,
- OptionalAttribute<"StringAttr">:$name,
- OptionalAttribute<"StringAttr">:$linkageName,
- OptionalAttribute<"DIFileAttr">:$file,
- VarInt:$line,
- VarInt:$scopeLine,
- EnumClassFlag<"DISubprogramFlags", "getSubprogramFlags()">:$_rawflags,
- LocalVar<"DISubprogramFlags", "(DISubprogramFlags)_rawflags">:$subprogramFlags,
- OptionalAttribute<"DISubroutineTypeAttr">:$type,
- OptionalArrayRef<"DINodeAttr">:$retainedNodes,
- OptionalArrayRef<"DINodeAttr">:$annotations
-)>;
+def DISubprogramAttr
+ : DialectAttribute<(attr OptionalAttribute<"DistinctAttr">:$recId,
+ Bool:$isRecSelf, OptionalAttribute<"DistinctAttr">:$id,
+ OptionalAttribute<"DICompileUnitAttr">:$compileUnit,
+ OptionalAttribute<"DIScopeAttr">:$scope,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"StringAttr">:$linkageName,
+ OptionalAttribute<"DIFileAttr">:$file, VarInt:$line,
+ VarInt:$scopeLine,
+ EnumClassFlag<"DISubprogramFlags", "getSubprogramFlags()">:$_rawflags,
+ LocalVar<"DISubprogramFlags",
+ "(DISubprogramFlags)_rawflags">:$subprogramFlags,
+ OptionalAttribute<"DISubroutineTypeAttr">:$type,
+ OptionalArrayRef<"Attribute">:$retainedNodes,
+ OptionalArrayRef<"DINodeAttr">:$annotations)>;
//===----------------------------------------------------------------------===//
// DICompositeTypeAttr
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index 6b8cac201d8bf..8082de122e74e 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -467,7 +467,7 @@ MlirAttribute mlirLLVMDISubprogramAttrGet(
cast<DISubroutineTypeAttr>(unwrap(type)),
llvm::map_to_vector(
unwrapList(nRetainedNodes, retainedNodes, nodesStorage),
- llvm::CastTo<DINodeAttr>),
+ llvm::CastTo<Attribute>),
llvm::map_to_vector(
unwrapList(nAnnotations, annotations, annotationsStorage),
llvm::CastTo<DINodeAttr>)));
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 82e100d254218..85df880d2712a 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -259,9 +259,15 @@ DISubprogramAttr DebugImporter::translateImpl(llvm::DISubprogram *node) {
return nullptr;
// Convert the retained nodes but drop all of them if one of them is invalid.
- SmallVector<DINodeAttr> retainedNodes;
- for (llvm::DINode *retainedNode : node->getRetainedNodes())
+ SmallVector<Attribute> retainedNodes;
+ auto add = [this, &retainedNodes](llvm::DINode *retainedNode) {
retainedNodes.push_back(translate(retainedNode));
+ };
+ auto addGVE = [](llvm::DIGlobalVariableExpression *GVE) {
+ // FIXME Import DIGlobalVariableExpressions from retainedNodes without
+ // duplicating them.
+ };
+ node->forEachRetainedNode(add, add, add, add, addGVE);
if (llvm::is_contained(retainedNodes, nullptr))
retainedNodes.clear();
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 38d8b96e82d82..442f5b6b137e6 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -114,6 +114,23 @@ DebugTranslation::getMDTupleOrNull(ArrayRef<DINodeAttr> elements) {
return llvm::MDNode::get(llvmCtx, llvmElements);
}
+llvm::MDTuple *
+DebugTranslation::getRetainedNodesOrNull(ArrayRef<Attribute> retainedNodes) {
+ if (retainedNodes.empty())
+ return nullptr;
+ SmallVector<llvm::Metadata *> llvmElements = llvm::map_to_vector(
+ retainedNodes, [&](Attribute attr) -> llvm::Metadata * {
+ if (auto GVE = dyn_cast<DIGlobalVariableExpressionAttr>(attr))
+ return translateGlobalVariableExpression(GVE);
+
+ auto diAttr = dyn_cast<DINodeAttr>(attr);
+ if (!diAttr)
+ llvm_unreachable("unknown retained node kind");
+ return translate(diAttr);
+ });
+ return llvm::MDNode::get(llvmCtx, llvmElements);
+}
+
llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
return llvm::DIBasicType::get(
llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()),
@@ -400,7 +417,7 @@ llvm::DISubprogram *DebugTranslation::translateImpl(DISubprogramAttr attr) {
/*ThisAdjustment=*/0, llvm::DINode::FlagZero,
static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
compileUnit, /*TemplateParams=*/nullptr, /*Declaration=*/nullptr,
- getMDTupleOrNull(attr.getRetainedNodes()), nullptr,
+ getRetainedNodesOrNull(attr.getRetainedNodes()), nullptr,
getMDTupleOrNull(attr.getAnnotations()));
if (attr.getId())
distinctAttrToNode.try_emplace(attr.getId(), node);
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h
index c12ddb42fe238..c1fdbd89087da 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.h
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h
@@ -114,6 +114,10 @@ class DebugTranslation {
/// `elements` is empty.
llvm::MDTuple *getMDTupleOrNull(ArrayRef<DINodeAttr> elements);
+ /// Consturct a DISubprogram's retainedNodes metadata node from the
+ /// `retainedNodes`. Returns nullptr if `retainedNodes` is empty.
+ llvm::MDTuple *getRetainedNodesOrNull(ArrayRef<Attribute> retainedNodes);
+
/// Constructs a DIExpression metadata node from the DIExpressionAttr. Returns
/// nullptr if `DIExpressionAttr` is null.
llvm::DIExpression *getExpressionAttrOrNull(DIExpressionAttr attr);
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 442e6e16e955e..a9ca4a57e8e8a 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1198,7 +1198,9 @@ convertMLIRAttributesToLLVM(Location loc, llvm::LLVMContext &ctx,
LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
// Mapping from compile unit to its respective set of global variables.
- DenseMap<llvm::DICompileUnit *, SmallVector<llvm::Metadata *>> allGVars;
+ DenseMap<llvm::DICompileUnit *, SmallVector<llvm::Metadata *>> globalGVars;
+ // Mapping from subprogram to its respective set of static local variables.
+ DenseMap<llvm::DISubprogram *, SmallVector<llvm::Metadata *>> staticLocals;
// First, create all global variables and global aliases in LLVM IR. A global
// or alias body may refer to another global/alias or itself, so all the
@@ -1291,7 +1293,7 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
//
// 3. For entities like static local variables in C or variable with
// SAVE attribute in Fortran, the scope hierarchy can be
- // variable -> DISubprogram -> DICompileUnit
+ // variable (-> DILocalScope)* -> DISubprogram
llvm::DIScope *scope = diGlobalVar->getScope();
if (auto *mod = dyn_cast_if_present<llvm::DIModule>(scope))
scope = mod->getScope();
@@ -1299,15 +1301,23 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
if (auto *sp =
dyn_cast_if_present<llvm::DISubprogram>(cb->getScope()))
scope = sp->getUnit();
- } else if (auto *sp = dyn_cast_if_present<llvm::DISubprogram>(scope))
- scope = sp->getUnit();
+ } else if (auto *lbb =
+ dyn_cast_if_present<llvm::DILexicalBlockBase>(scope)) {
+ scope = lbb->getSubprogram();
+ }
- // Get the compile unit (scope) of the the global variable.
+ // Get the compile unit (scope) of the the global variable, or the
+ // subprogram of the static local variable.
if (llvm::DICompileUnit *compileUnit =
dyn_cast_if_present<llvm::DICompileUnit>(scope)) {
// Update the compile unit with this incoming global variable
// expression during the finalizing step later.
- allGVars[compileUnit].push_back(diGlobalExpr);
+ globalGVars[compileUnit].push_back(diGlobalExpr);
+ } else if (llvm::DISubprogram *sp =
+ dyn_cast_if_present<llvm::DISubprogram>(scope)) {
+ // Update the subprogram with this incoming static local variable
+ // expression during the finalizing step later.
+ staticLocals[sp].push_back(diGlobalExpr);
}
}
}
@@ -1499,10 +1509,14 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
// Finally, update the compile units their respective sets of global variables
// created earlier.
- for (const auto &[compileUnit, globals] : allGVars) {
+ for (const auto &[compileUnit, globals] : globalGVars)
compileUnit->replaceGlobalVariables(
llvm::MDTuple::get(getLLVMContext(), globals));
- }
+
+ // And update the subprograms with their respective sets of static local
+ // variables.
+ for (const auto &[sp, globals] : staticLocals)
+ sp->retainNodes(globals.begin(), globals.end());
// Convert global alias bodies.
for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index 643d504bcb2ac..28c25809002cd 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -1014,3 +1014,35 @@ define void @variant_part_import() !dbg !3 {
!11 = !DIBasicType(name: "float64", size: 64, encoding: DW_ATE_float)
!12 = !DIDerivedType(tag: DW_TAG_member, name: "_int64", baseType: !10, size: 64, offset: 64, extraData: i8 1)
!13 = !DIDerivedType(tag: DW_TAG_member, name: "_float64", baseType: !11, size: 64, offset: 64, extraData: i8 2)
+
+; // -----
+
+; Test that static local DIGlobalVariable listed in DISubprogram's retainedNodes does not get duplicated after import.
+
+; CHECK-DAG: #[[LVAR:.+]] = #llvm.di_local_variable<{{.*}}name = "unused_local"{{.*}}>
+; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<{{.*}}name = "fn_with_static_local"{{.*}}retainedNodes = [#[[LVAR]]]>
+; CHECK-DAG: #[[GVAR:.+]] = #llvm.di_global_variable<scope = #[[SP]], name = "static_local"{{.*}}>
+; CHECK-DAG: #[[GEXPR:.+]] = #llvm.di_global_variable_expression<var = #[[GVAR]], expr = <>>
+; CHECK-DAG-COUNT-1: {{#llvm\.di_global_variable_expression<}}
+; CHECK-DAG-COUNT-1: {{#llvm\.di_global_variable<}}
+
+ at static_local = internal global i64 0, align 8, !dbg !0
+
+define void @fn_with_static_local() !dbg !3 {
+ ret void
+}
+
+!llvm.dbg.cu = !{!7}
+!llvm.module.flags = !{!10}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "static_local", linkageName: "static_local", scope: !3, file: !4, line: 121, type: !9, isLocal: true, isDefinition: true)
+!3 = distinct !DISubprogram(name: "fn_with_static_local", scope: !4, file: !4, spFlags: DISPFlagDefinition, unit: !7, type: !13, retainedNodes: !11)
+!4 = !DIFile(filename: "test.c", directory: "")
+!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !4)
+!9 = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_signed)
+!10 = !{i32 2, !"Debug Info Version", i32 3}
+!11 = !{!0, !12}
+!12 = !DILocalVariable(name: "unused_local", scope: !3, file: !4, line: 122, type: !9)
+!13 = !DISubroutineType(types: !14)
+!14 = !{null}
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index 27dcf6979d7bb..72dadb2602c52 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -365,10 +365,12 @@ llvm.mlir.global external @module_global() {dbg_exprs = [#llvm.di_global_variabl
// -----
// CHECK: @func_global = external global i64, !dbg {{.*}}
-// CHECK-DAG: ![[CU:.*]] = distinct !DICompileUnit({{.*}}globals: ![[GVALS:[0-9]+]], debugInfoForProfiling: true)
-// CHECK-DAG: ![[SP:.*]] = distinct !DISubprogram(name: "fn_with_gl"{{.*}}unit: ![[CU]])
+// CHECK-DAG: ![[SP:.*]] = distinct !DISubprogram(name: "fn_with_gl"{{.*}}unit: ![[CU:.*]], {{.*}}retainedNodes: ![[GVALS:.*]])
// CHECK-DAG: ![[GVAR:.*]] = distinct !DIGlobalVariable(name: "func_global"{{.*}}, scope: ![[SP]]{{.*}})
// CHECK-DAG: ![[GEXPR:.*]] = !DIGlobalVariableExpression(var: ![[GVAR]], expr: !DIExpression())
+// CHECK-DAG: ![[CU]] = distinct !DICompileUnit(
+// CHECK-NOT: globals:
+// CHECK-SAME: emissionKind: FullDebug, debugInfoForProfiling: true)
// CHECK-DAG: ![[GVALS]] = !{![[GEXPR]]}
#file = #llvm.di_file<"test.f90" in "existence">
More information about the flang-commits
mailing list