diff --git a/include/LLVMSPIRVExtensions.inc b/include/LLVMSPIRVExtensions.inc index d338f0c1a5..d8c2d89b38 100644 --- a/include/LLVMSPIRVExtensions.inc +++ b/include/LLVMSPIRVExtensions.inc @@ -37,3 +37,4 @@ EXT(SPV_INTEL_fp_fast_math_mode) EXT(SPV_INTEL_optnone) EXT(SPV_INTEL_memory_access_aliasing) EXT(SPV_INTEL_bfloat16_conversion) +EXT(SPV_INTEL_debug_module) diff --git a/lib/SPIRV/LLVMToSPIRVDbgTran.cpp b/lib/SPIRV/LLVMToSPIRVDbgTran.cpp index 7f982a7aff..4d60031ae3 100644 --- a/lib/SPIRV/LLVMToSPIRVDbgTran.cpp +++ b/lib/SPIRV/LLVMToSPIRVDbgTran.cpp @@ -343,6 +343,12 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgEntryImpl(const MDNode *MDN) { case dwarf::DW_TAG_imported_declaration: return transDbgImportedEntry(cast(DIEntry)); + case dwarf::DW_TAG_module: { + if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_debug_module)) + return transDbgModule(cast(DIEntry)); + return getDebugInfoNone(); + } + default: return getDebugInfoNone(); } @@ -811,9 +817,10 @@ LLVMToSPIRVDbgTran::transDbgGlobalVariable(const DIGlobalVariable *GV) { // Parent scope DIScope *Context = GV->getScope(); SPIRVEntry *Parent = SPIRVCU; - // Global variable may be declared in scope of a namespace or it may be a - // static variable declared in scope of a function - if (Context && (isa(Context) || isa(Context))) + // Global variable may be declared in scope of a namespace or imported module, + // it may also be a static variable declared in scope of a function. + if (Context && (isa(Context) || isa(Context) || + isa(Context))) Parent = transDbgEntry(Context); Ops[ParentIdx] = Parent->getId(); @@ -1026,3 +1033,19 @@ LLVMToSPIRVDbgTran::transDbgImportedEntry(const DIImportedEntity *IE) { Ops[ParentIdx] = getScope(IE->getScope())->getId(); return BM->addDebugInfo(SPIRVDebug::ImportedEntity, getVoidTy(), Ops); } + +SPIRVEntry *LLVMToSPIRVDbgTran::transDbgModule(const DIModule *Module) { + using namespace SPIRVDebug::Operand::ModuleINTEL; + SPIRVWordVec Ops(OperandCount); + Ops[NameIdx] = BM->getString(Module->getName().str())->getId(); + Ops[SourceIdx] = getSource(Module->getFile())->getId(); + Ops[LineIdx] = Module->getLineNo(); + Ops[ParentIdx] = getScope(Module->getScope())->getId(); + Ops[ConfigMacrosIdx] = + BM->getString(Module->getConfigurationMacros().str())->getId(); + Ops[IncludePathIdx] = BM->getString(Module->getIncludePath().str())->getId(); + Ops[ApiNotesIdx] = BM->getString(Module->getAPINotesFile().str())->getId(); + BM->addExtension(ExtensionID::SPV_INTEL_debug_module); + BM->addCapability(spv::internal::CapabilityDebugInfoModuleINTEL); + return BM->addDebugInfo(SPIRVDebug::ModuleINTEL, getVoidTy(), Ops); +} diff --git a/lib/SPIRV/LLVMToSPIRVDbgTran.h b/lib/SPIRV/LLVMToSPIRVDbgTran.h index bc60e63144..03d62a2d79 100644 --- a/lib/SPIRV/LLVMToSPIRVDbgTran.h +++ b/lib/SPIRV/LLVMToSPIRVDbgTran.h @@ -143,6 +143,9 @@ class LLVMToSPIRVDbgTran { // Imported declarations and modules SPIRVEntry *transDbgImportedEntry(const DIImportedEntity *IE); + // A module in programming language. Example - Fortran module, clang module. + SPIRVEntry *transDbgModule(const DIModule *IE); + SPIRVModule *BM; Module *M; LLVMToSPIRVBase *SPIRVWriter; diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp index aefa794a68..b7ebf031d1 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp @@ -779,6 +779,8 @@ DINode *SPIRVToLLVMDbgTran::transImportedEntry(const SPIRVExtInst *DebugInst) { if (!Entity) return Builder.createImportedModule( Scope, static_cast(nullptr), File, Line); + if (DIModule *DM = dyn_cast(Entity)) + return Builder.createImportedModule(Scope, DM, File, Line); if (DIImportedEntity *IE = dyn_cast(Entity)) return Builder.createImportedModule(Scope, IE, File, Line); if (DINamespace *NS = dyn_cast(Entity)) @@ -795,6 +797,22 @@ DINode *SPIRVToLLVMDbgTran::transImportedEntry(const SPIRVExtInst *DebugInst) { llvm_unreachable("Unexpected kind of imported entity!"); } +DINode *SPIRVToLLVMDbgTran::transModule(const SPIRVExtInst *DebugInst) { + using namespace SPIRVDebug::Operand::ModuleINTEL; + const SPIRVWordVec &Ops = DebugInst->getArguments(); + assert(Ops.size() >= OperandCount && "Invalid number of operands"); + DIScope *Scope = getScope(BM->getEntry(Ops[ParentIdx])); + unsigned Line = Ops[LineIdx]; + DIFile *File = getFile(Ops[SourceIdx]); + StringRef Name = getString(Ops[NameIdx]); + StringRef ConfigMacros = getString(Ops[ConfigMacrosIdx]); + StringRef IncludePath = getString(Ops[IncludePathIdx]); + StringRef ApiNotes = getString(Ops[ApiNotesIdx]); + + return Builder.createModule(Scope, Name, ConfigMacros, IncludePath, ApiNotes, + File, Line); +} + MDNode *SPIRVToLLVMDbgTran::transExpression(const SPIRVExtInst *DebugInst) { const SPIRVWordVec &Args = DebugInst->getArguments(); std::vector Ops; @@ -891,6 +909,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) { case SPIRVDebug::ImportedEntity: return transImportedEntry(DebugInst); + case SPIRVDebug::ModuleINTEL: + return transModule(DebugInst); + case SPIRVDebug::Operation: // To be translated with transExpression case SPIRVDebug::Source: // To be used by other instructions return nullptr; diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.h b/lib/SPIRV/SPIRVToLLVMDbgTran.h index 8fe3ebf04d..db204f85d4 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.h +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.h @@ -142,6 +142,8 @@ class SPIRVToLLVMDbgTran { DINode *transImportedEntry(const SPIRVExtInst *DebugInst); + DINode *transModule(const SPIRVExtInst *DebugInst); + MDNode *transExpression(const SPIRVExtInst *DebugInst); SPIRVModule *BM; diff --git a/lib/SPIRV/libSPIRV/SPIRV.debug.h b/lib/SPIRV/libSPIRV/SPIRV.debug.h index 26e22e57a8..a02edc9eb2 100644 --- a/lib/SPIRV/libSPIRV/SPIRV.debug.h +++ b/lib/SPIRV/libSPIRV/SPIRV.debug.h @@ -48,7 +48,8 @@ enum Instruction { MacroUndef = 33, ImportedEntity = 34, Source = 35, - InstCount = 36 + ModuleINTEL = 36, + InstCount = 37 }; enum Flag { @@ -770,6 +771,19 @@ enum { }; } +namespace ModuleINTEL { +enum { + NameIdx = 0, + SourceIdx = 1, + LineIdx = 2, + ParentIdx = 3, + ConfigMacrosIdx = 4, + IncludePathIdx = 5, + ApiNotesIdx = 6, + OperandCount = 7 +}; +} + } // namespace Operand } // namespace SPIRVDebug diff --git a/lib/SPIRV/libSPIRV/SPIRVExtInst.h b/lib/SPIRV/libSPIRV/SPIRVExtInst.h index 89581f46ff..9f1aa91a96 100644 --- a/lib/SPIRV/libSPIRV/SPIRVExtInst.h +++ b/lib/SPIRV/libSPIRV/SPIRVExtInst.h @@ -253,6 +253,7 @@ template <> inline void SPIRVMap::init() { add(SPIRVDebug::NoScope, "DebugNoScope"); add(SPIRVDebug::InlinedAt, "DebugInlinedAt"); add(SPIRVDebug::ImportedEntity, "DebugImportedEntity"); + add(SPIRVDebug::ModuleINTEL, "DebugModuleINTEL"); add(SPIRVDebug::Expression, "DebugExpression"); add(SPIRVDebug::Operation, "DebugOperation"); } diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index 6a2afe904a..25f1fd203b 100644 --- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -568,6 +568,7 @@ template <> inline void SPIRVMap::init() { add(CapabilityMax, "Max"); add(internal::CapabilityBfloat16ConversionINTEL, "Bfloat16ConversionINTEL"); + add(internal::CapabilityDebugInfoModuleINTEL, "DebugInfoModuleINTEL"); } SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap) diff --git a/lib/SPIRV/libSPIRV/spirv_internal.hpp b/lib/SPIRV/libSPIRV/spirv_internal.hpp index ce66f243cc..b9dad88fbc 100644 --- a/lib/SPIRV/libSPIRV/spirv_internal.hpp +++ b/lib/SPIRV/libSPIRV/spirv_internal.hpp @@ -52,6 +52,7 @@ enum InternalDecoration { enum InternalCapability { ICapMemoryAccessAliasingINTEL = 5910, ICapOptNoneINTEL = 6094, + ICapDebugInfoModuleINTEL = 6114, ICapBfloat16ConversionINTEL = 6115 }; @@ -86,6 +87,8 @@ constexpr Capability CapabilityMemoryAccessAliasingINTEL = static_cast(ICapMemoryAccessAliasingINTEL); constexpr Capability CapabilityBfloat16ConversionINTEL = static_cast(ICapBfloat16ConversionINTEL); +constexpr Capability CapabilityDebugInfoModuleINTEL = + static_cast(ICapDebugInfoModuleINTEL); constexpr FunctionControlMask FunctionControlOptNoneINTELMask = static_cast(IFunctionControlOptNoneINTELMask); diff --git a/test/DebugInfo/DebugInfoNoneEntity.ll b/test/DebugInfo/DebugInfoNoneEntity.ll index 674817de8c..731d7c407a 100644 --- a/test/DebugInfo/DebugInfoNoneEntity.ll +++ b/test/DebugInfo/DebugInfoNoneEntity.ll @@ -4,6 +4,9 @@ ; RUN: llvm-spirv %t.bc -o %t.spv ; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-spirv -spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc + source_filename = "llvm-link" target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" target triple = "spir64" diff --git a/test/DebugInfo/X86/DIModule.ll b/test/DebugInfo/X86/DIModule.ll new file mode 100644 index 0000000000..1988059eaa --- /dev/null +++ b/test/DebugInfo/X86/DIModule.ll @@ -0,0 +1,48 @@ +; ModuleID = '/Volumes/Data/apple-internal/llvm/tools/clang/test/Modules/debug-info-moduleimport.m' +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll + +; RUN: llc -mtriple=x86_64-apple-macosx %t.ll -accel-tables=Dwarf -o %t -filetype=obj +; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s +; RUN: llvm-dwarfdump -verify %t + +; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -spirv-text -o - | FileCheck %s --check-prefix CHECK-SPIRV + +; CHECK: DW_TAG_compile_unit +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_module +; CHECK-NEXT: DW_AT_name {{.*}}"DebugModule" +; CHECK-NEXT: DW_AT_LLVM_config_macros {{.*}}"-DMODULES=0" +; CHECK-NEXT: DW_AT_LLVM_include_path {{.*}}"/llvm/tools/clang/test/Modules/Inputs" +; CHECK-NEXT: DW_AT_LLVM_apinotes {{.*}}"m.apinotes" + +; CHECK-SPIRV: Capability DebugInfoModuleINTEL +; CHECK-SPIRV: Extension "SPV_INTEL_debug_module" + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "spir64-unknown-unknown" + +; CHECK-SPIRV: String [[FileName:[0-9]+]] "/llvm/tools/clang/test/Modules/" +; CHECK-SPIRV: String [[EmptyStr:[0-9]+]] "" +; CHECK-SPIRV: String [[Name:[0-9]+]] "DebugModule" +; CHECK-SPIRV: String [[Defines:[0-9]+]] "-DMODULES=0" +; CHECK-SPIRV: String [[IncludePath:[0-9]+]] "/llvm/tools/clang/test/Modules/Inputs" +; CHECK-SPIRV: String [[ApiNotes:[0-9]+]] "m.apinotes" + +; CHECK-SPIRV: ExtInst {{[0-9]+}} [[Module:[0-9]+]] {{[0-9]+}} DebugModuleINTEL [[Name]] {{[0-9]+}} 0 {{[0-9]+}} [[Defines]] [[IncludePath]] [[ApiNotes]] +; CHECK-SPIRV: ExtInst {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} DebugImportedEntity {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} [[Module]] + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7} +!llvm.ident = !{!8} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "LLVM version 3.7.0", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !3, sysroot: "/") +!1 = !DIFile(filename: "/llvm/tools/clang/test/Modules/", directory: "/") +!2 = !{} +!3 = !{!4} +!4 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !5, file: !1, line: 5) +!5 = !DIModule(scope: null, name: "DebugModule", configMacros: "-DMODULES=0", includePath: "/llvm/tools/clang/test/Modules/Inputs", apinotes: "m.apinotes") +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{!"LLVM version 3.7.0"} diff --git a/test/DebugInfo/X86/DIModuleContext.ll b/test/DebugInfo/X86/DIModuleContext.ll new file mode 100644 index 0000000000..71569a2769 --- /dev/null +++ b/test/DebugInfo/X86/DIModuleContext.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll + +; RUN: llc -mtriple=x86_64-apple-macosx %t.ll -o - -filetype=obj \ +; RUN: | llvm-dwarfdump -debug-info - | FileCheck %s +; CHECK: DW_TAG_module +; CHECK-NOT: NULL +; CHECK: DW_TAG_structure_type + +; Hand-crafted based on +; struct s; +; struct s *s; + +source_filename = "test/DebugInfo/X86/DIModuleContext.ll" +target triple = "spir64-unknown-unknown" + +%struct.s = type opaque + +@i = common addrspace(1) global %struct.s* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, imports: !6) +!3 = !DIFile(filename: "test.c", directory: "/") +!4 = !{} +!5 = !{!0} +!6 = !{!7} +!7 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !2, entity: !8, file: !3, line: 11) +!8 = !DIModule(scope: null, name: "Module", includePath: ".") +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, align: 64) +!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "s", scope: !8, file: !3, line: 1, flags: DIFlagFwdDecl) +!11 = !{i32 2, !"Dwarf Version", i32 2} +!12 = !{i32 2, !"Debug Info Version", i32 3} + diff --git a/test/DebugInfo/X86/Fortran-DIModule.ll b/test/DebugInfo/X86/Fortran-DIModule.ll new file mode 100644 index 0000000000..e22e1b7198 --- /dev/null +++ b/test/DebugInfo/X86/Fortran-DIModule.ll @@ -0,0 +1,48 @@ +; This test checks attributes of a Fortran module. +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll + +; RUN: llc -mtriple=x86_64-unknown-linux-gnu %t.ll -filetype=obj -o - | \ +; RUN: llvm-dwarfdump - | FileCheck %s + +; CHECK: DW_TAG_module +; CHECK-NEXT: DW_AT_name ("dummy") +; CHECK-NEXT: DW_AT_decl_file ("/fortran{{[/\\]}}module.f90") +; CHECK-NEXT: DW_AT_decl_line (2) + +; Generated from flang compiler, Fortran source to regenerate: +; module dummy +; integer :: foo +; end module dummy + +; ModuleID = '/tmp/module-b198fa.ll' +source_filename = "/tmp/module-b198fa.ll" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "spir64-unknown-unknown" + +%struct_dummy_0_ = type <{ [4 x i8] }> + +@_dummy_0_ = common addrspace(1) global %struct_dummy_0_ zeroinitializer, align 64, !dbg !0 + +; Function Attrs: noinline +define float @dummy_() #0 { +.L.entry: + ret float undef +} + +attributes #0 = { noinline "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } + +!llvm.module.flags = !{!8, !9} +!llvm.dbg.cu = !{!3} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !4, type: !7, isLocal: false, isDefinition: true) +!2 = !DIModule(scope: !3, name: "dummy", file: !4, line: 2) +!3 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !4, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5) +!4 = !DIFile(filename: "module.f90", directory: "/fortran") +!5 = !{} +!6 = !{!0} +!7 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/test/DebugInfo/X86/dimodule-external-fortran.ll b/test/DebugInfo/X86/dimodule-external-fortran.ll new file mode 100644 index 0000000000..df5912b3df --- /dev/null +++ b/test/DebugInfo/X86/dimodule-external-fortran.ll @@ -0,0 +1,93 @@ +; This test verifies that the debug info for an external Fortran module +; is correctly generated. +; +; To generate the test source, compile the following two files in order in +; the same directory (as the second compilation uses the .mod from the first): +; external_module.f90 (to compile: -g -c external_module.f90) +; module external_module +; real :: dummy +; end module external_module +; +; em.f90 (to compile: -g -llvm-emit -c -S em.f90) +; program use_external_module +; use external_module +; implicit none +; +; real :: x +; x = 2.0 + dummy +; +; end program use_external_module +; +; The test would be in em.ll. + +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=obj %t.ll -o - | llvm-dwarfdump - | FileCheck %s + +; CHECK: [[DIE_ID:0x[0-9a-f]+]]: DW_TAG_module +; CHECK-NEXT: DW_AT_name ("external_module") + +; CHECK: DW_TAG_imported_module +; CHECK-NEXT: DW_AT_decl_file +; CHECK-NEXT: DW_AT_decl_line +; CHECK-NEXT: DW_AT_import ([[DIE_ID]]) + +; When the debugger sees the module being imported is a declaration, +; it should go to the global scope to find the module's definition. + +; ModuleID = 'em.f90' +source_filename = "em.f90" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "spir64-unknown-unknown" + +@external_module_mp_dummy_ = available_externally global float 0.000000e+00, align 8, !dbg !0 +@0 = internal unnamed_addr constant i32 2 + +; Function Attrs: noinline nounwind uwtable +define void @MAIN__() #0 !dbg !2 { +alloca_0: + %"var$1" = alloca [8 x i64], align 8 + %"use_external_module_$X" = alloca float, align 8 + call void @llvm.dbg.declare(metadata float* %"use_external_module_$X", metadata !13, metadata !DIExpression()), !dbg !17 + %func_result = call i32 @for_set_reentrancy(i32* @0), !dbg !18 + %external_module_mp_dummy__fetch = load float, float* @external_module_mp_dummy_, align 1, !dbg !19 + %add = fadd reassoc ninf nsz arcp contract afn float 2.000000e+00, %external_module_mp_dummy__fetch, !dbg !20 + store float %add, float* %"use_external_module_$X", align 1, !dbg !19 + ret void, !dbg !21 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare i32 @for_set_reentrancy(i32*) + +attributes #0 = { noinline nounwind uwtable "intel-lang"="fortran" "min-legal-vector-width"="0" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.module.flags = !{!15, !16} +!llvm.dbg.cu = !{!6} +!omp_offload.info = !{} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "dummy", linkageName: "external_module_mp_dummy_", scope: !2, file: !3, line: 1, type: !14, isLocal: false, isDefinition: true) +!2 = distinct !DISubprogram(name: "use_external_module", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !12) +!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: !9, splitDebugInlining: false, nameTableKind: None) +!7 = !{} +!8 = !{!0} +!9 = !{!10} +!10 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2) +!11 = !DIModule(scope: !2, name: "external_module") +!12 = !{!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} +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !DILocation(line: 5, column: 12, scope: !2) +!18 = !DILocation(line: 1, column: 9, scope: !2) +!19 = !DILocation(line: 6, column: 4, scope: !2) +!20 = !DILocation(line: 6, column: 12, scope: !2) +!21 = !DILocation(line: 8, column: 1, scope: !2)