Index: include/llvm/IR/DIBuilder.h =================================================================== --- include/llvm/IR/DIBuilder.h +++ include/llvm/IR/DIBuilder.h @@ -105,13 +105,17 @@ /// out into. /// \param Kind The kind of debug information to generate. /// \param DWOId The DWOId if this is a split skeleton compile unit. + /// \param SplitDebugInlining Whether to emit inline debug info. + /// \param DebugInfoFOrProfiling Whether to emit extra debug info for + /// profile collection. DICompileUnit * createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RV, StringRef SplitName = StringRef(), DICompileUnit::DebugEmissionKind Kind = DICompileUnit::DebugEmissionKind::FullDebug, - uint64_t DWOId = 0, bool SplitDebugInlining = true); + uint64_t DWOId = 0, bool SplitDebugInlining = true, + bool DebugInfoForProfiling = false); /// Create a file descriptor to hold debugging information for a file. /// \param Filename File name. Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -1044,15 +1044,17 @@ unsigned EmissionKind; uint64_t DWOId; bool SplitDebugInlining; + bool DebugInfoForProfiling; DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage, bool IsOptimized, unsigned RuntimeVersion, unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining, - ArrayRef Ops) + bool DebugInfoForProfiling, ArrayRef Ops) : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), - DWOId(DWOId), SplitDebugInlining(SplitDebugInlining) { + DWOId(DWOId), SplitDebugInlining(SplitDebugInlining), + DebugInfoForProfiling(DebugInfoForProfiling) { assert(Storage != Uniqued); } ~DICompileUnit() = default; @@ -1065,15 +1067,16 @@ DIScopeArray RetainedTypes, DIGlobalVariableExpressionArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, - uint64_t DWOId, bool SplitDebugInlining, StorageType Storage, - bool ShouldCreate = true) { + uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, SourceLanguage, File, getCanonicalMDString(Context, Producer), IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion, getCanonicalMDString(Context, SplitDebugFilename), EmissionKind, EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(), ImportedEntities.get(), Macros.get(), - DWOId, SplitDebugInlining, Storage, ShouldCreate); + DWOId, SplitDebugInlining, DebugInfoForProfiling, Storage, + ShouldCreate); } static DICompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, @@ -1082,7 +1085,8 @@ unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, - StorageType Storage, bool ShouldCreate = true); + bool DebugInfoForProfiling, StorageType Storage, + bool ShouldCreate = true); TempDICompileUnit cloneImpl() const { return getTemporary(getContext(), getSourceLanguage(), getFile(), @@ -1090,7 +1094,8 @@ getRuntimeVersion(), getSplitDebugFilename(), getEmissionKind(), getEnumTypes(), getRetainedTypes(), getGlobalVariables(), getImportedEntities(), - getMacros(), DWOId, getSplitDebugInlining()); + getMacros(), DWOId, getSplitDebugInlining(), + getDebugInfoForProfiling()); } public: @@ -1105,10 +1110,11 @@ DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, DIGlobalVariableExpressionArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, - uint64_t DWOId, bool SplitDebugInlining), + uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, - GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining)) + GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, + DebugInfoForProfiling)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, @@ -1116,10 +1122,11 @@ MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, - bool SplitDebugInlining), + bool SplitDebugInlining, bool DebugInfoForProfiling), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, - GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining)) + GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, + DebugInfoForProfiling)) TempDICompileUnit clone() const { return cloneImpl(); } @@ -1129,6 +1136,7 @@ DebugEmissionKind getEmissionKind() const { return (DebugEmissionKind)EmissionKind; } + bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; } StringRef getProducer() const { return getStringOperand(1); } StringRef getFlags() const { return getStringOperand(2); } StringRef getSplitDebugFilename() const { return getStringOperand(3); } Index: include/llvm/Target/TargetOptions.h =================================================================== --- include/llvm/Target/TargetOptions.h +++ include/llvm/Target/TargetOptions.h @@ -108,7 +108,7 @@ DisableIntegratedAS(false), CompressDebugSections(false), RelaxELFRelocations(false), FunctionSections(false), DataSections(false), UniqueSectionNames(true), TrapUnreachable(false), - EmulatedTLS(false), EnableIPRA(false), DebugInfoForProfiling(false), + EmulatedTLS(false), EnableIPRA(false), FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard), ThreadModel(ThreadModel::POSIX), @@ -225,9 +225,6 @@ /// This flag enables InterProcedural Register Allocation (IPRA). unsigned EnableIPRA : 1; - /// This flag enables emitting extra debug info for sample profiling. - unsigned DebugInfoForProfiling : 1; - /// FloatABIType - This setting is set by -float-abi=xxx option is specfied /// on the command line. This setting may either be Default, Soft, or Hard. /// Default selects the target's default behavior. Soft selects the ABI for @@ -302,8 +299,7 @@ ARE_EQUAL(FPDenormalMode) && ARE_EQUAL(ExceptionModel) && ARE_EQUAL(MCOptions) && - ARE_EQUAL(EnableIPRA) && - ARE_EQUAL(DebugInfoForProfiling); + ARE_EQUAL(EnableIPRA); #undef ARE_EQUAL } Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -4029,7 +4029,8 @@ OPTIONAL(imports, MDField, ); \ OPTIONAL(macros, MDField, ); \ OPTIONAL(dwoId, MDUnsignedField, ); \ - OPTIONAL(splitDebugInlining, MDBoolField, = true); + OPTIONAL(splitDebugInlining, MDBoolField, = true); \ + OPTIONAL(debugInfoForProfiling, MDBoolField, = false); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4037,7 +4038,7 @@ Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, - splitDebugInlining.Val); + splitDebugInlining.Val, debugInfoForProfiling.Val); return false; } Index: lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- lib/Bitcode/Reader/MetadataLoader.cpp +++ lib/Bitcode/Reader/MetadataLoader.cpp @@ -1188,7 +1188,7 @@ break; } case bitc::METADATA_COMPILE_UNIT: { - if (Record.size() < 14 || Record.size() > 17) + if (Record.size() < 14 || Record.size() > 18) return error("Invalid record"); // Ignore Record[0], which indicates whether this compile unit is @@ -1201,7 +1201,8 @@ getMDOrNull(Record[12]), getMDOrNull(Record[13]), Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]), Record.size() <= 14 ? 0 : Record[14], - Record.size() <= 16 ? true : Record[16]); + Record.size() <= 16 ? true : Record[16], + Record.size() <= 17 ? false : Record[17]); MetadataList.assignValue(CU, NextMetadataNo++); Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1549,6 +1549,7 @@ Record.push_back(N->getDWOId()); Record.push_back(VE.getMetadataOrNullID(N->getMacros().get())); Record.push_back(N->getSplitDebugInlining()); + Record.push_back(N->getDebugInfoForProfiling()); Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1213,7 +1213,7 @@ // Under -gmlt, skip building the subprogram if there are no inlined // subroutines inside it. But with -fdebug-info-for-profiling, the subprogram // is still needed as we need its source location. - if (!Asm->TM.Options.DebugInfoForProfiling && + if (!TheCU.getCUNode()->getDebugInfoForProfiling() && TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly && LScopes.getAbstractScopesList().empty() && !IsDarwin) { assert(InfoHolder.getScopeVariables().empty()); Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1184,7 +1184,7 @@ // If -fdebug-info-for-profiling is enabled, need to emit the subprogram // and its source location. bool SkipSPSourceLocation = SkipSPAttributes && - !Asm->TM.Options.DebugInfoForProfiling; + !CUNode->getDebugInfoForProfiling(); if (!SkipSPSourceLocation) if (applySubprogramDefinitionAttributes(SP, SPDie)) return; Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -1688,6 +1688,8 @@ Printer.printMetadata("macros", N->getRawMacros()); Printer.printInt("dwoId", N->getDWOId()); Printer.printBool("splitDebugInlining", N->getSplitDebugInlining(), true); + Printer.printBool("debugInfoForProfiling", N->getDebugInfoForProfiling(), + false); Out << ")"; } Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -126,7 +126,7 @@ unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName, DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId, - bool SplitDebugInlining) { + bool SplitDebugInlining, bool DebugInfoForProfiling) { assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) || (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) && @@ -136,7 +136,7 @@ CUNode = DICompileUnit::getDistinct( VMContext, Lang, File, Producer, isOptimized, Flags, RunTimeVer, SplitName, Kind, nullptr, nullptr, nullptr, nullptr, nullptr, DWOId, - SplitDebugInlining); + SplitDebugInlining, DebugInfoForProfiling); // Create a named metadata so that it is easier to find cu in a module. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); Index: lib/IR/DebugInfo.cpp =================================================================== --- lib/IR/DebugInfo.cpp +++ lib/IR/DebugInfo.cpp @@ -410,7 +410,8 @@ CU->isOptimized(), CU->getFlags(), CU->getRuntimeVersion(), CU->getSplitDebugFilename(), DICompileUnit::LineTablesOnly, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros(), - CU->getDWOId(), CU->getSplitDebugInlining()); + CU->getDWOId(), CU->getSplitDebugInlining(), + CU->getDebugInfoForProfiling()); } DILocation *getReplacementMDLocation(DILocation *MLD) { Index: lib/IR/DebugInfoMetadata.cpp =================================================================== --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -383,8 +383,8 @@ unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, - uint64_t DWOId, bool SplitDebugInlining, StorageType Storage, - bool ShouldCreate) { + uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, + StorageType Storage, bool ShouldCreate) { assert(Storage != Uniqued && "Cannot unique DICompileUnit"); assert(isCanonical(Producer) && "Expected canonical MDString"); assert(isCanonical(Flags) && "Expected canonical MDString"); @@ -397,7 +397,8 @@ return storeImpl(new (array_lengthof(Ops)) DICompileUnit(Context, Storage, SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind, - DWOId, SplitDebugInlining, Ops), + DWOId, SplitDebugInlining, + DebugInfoForProfiling, Ops), Storage); } Index: lib/Target/TargetMachine.cpp =================================================================== --- lib/Target/TargetMachine.cpp +++ lib/Target/TargetMachine.cpp @@ -35,10 +35,6 @@ cl::desc("Enable interprocedural register allocation " "to reduce load/store at procedure calls.")); -cl::opt DebugInfoForProfiling( - "debug-info-for-profiling", cl::init(false), cl::Hidden, - cl::desc("Emit extra debug info to make sample profile more accurate.")); - //--------------------------------------------------------------------------- // TargetMachine Class // @@ -51,8 +47,6 @@ RequireStructuredCFG(false), DefaultOptions(Options), Options(Options) { if (EnableIPRA.getNumOccurrences()) this->Options.EnableIPRA = EnableIPRA; - if (DebugInfoForProfiling.getNumOccurrences()) - this->Options.DebugInfoForProfiling = DebugInfoForProfiling; } TargetMachine::~TargetMachine() { Index: test/Bitcode/upgrade-debug-info-for-profiling.ll =================================================================== --- /dev/null +++ test/Bitcode/upgrade-debug-info-for-profiling.ll @@ -0,0 +1,10 @@ +; RUN: llvm-dis < %s.bc | FileCheck %s +; RUN: verify-uselistorder < %s.bc + +!llvm.module.flags = !{!0} +!0 = !{i32 2, !"Debug Info Version", i32 3} + +!llvm.dbg.cu = !{!1} +; CHECK-NOT: DICompileUnit{{.*}} debugInfoForProfiling: true +!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, emissionKind: FullDebug) +!2 = !DIFile(filename: "foo.c", directory: "/path/to/dir") Index: test/DebugInfo/Generic/gmlt.ll =================================================================== --- test/DebugInfo/Generic/gmlt.ll +++ test/DebugInfo/Generic/gmlt.ll @@ -1,4 +1,8 @@ ; REQUIRES: object-emission +; RUN: %llc_dwarf -O0 -filetype=obj < %S/gmlt.ll | llvm-dwarfdump - | FileCheck %S/gmlt.ll + +; There's a darwin specific test in X86/gmlt, so it's okay to XFAIL this here. +; XFAIL: darwin ; Generated from the following source compiled with clang++ -gmlt: ; void f1() {} @@ -76,13 +80,6 @@ ; CHECK-NOT: {{DW_TAG|DW_AT}} ; CHECK: NULL -; PROFILING: DW_TAG_subprogram -; PROFILING: DW_AT_name {{.*}} "f1" -; With -debug-info-for-profiling, we need to emit decl_file a-nd decl_line -; of the subprogram. -; PROFILING: DW_AT_decl_file -; PROFILING: DW_AT_decl_line - ; CHECK: .debug_ranges contents: ; ... some addresses (depends on platform (such as platforms with function Index: test/DebugInfo/Generic/gmlt.test =================================================================== --- test/DebugInfo/Generic/gmlt.test +++ /dev/null @@ -1,6 +0,0 @@ -; REQUIRES: object-emission -; RUN: %llc_dwarf -O0 -filetype=obj < %S/../Inputs/gmlt.ll | llvm-dwarfdump - | FileCheck %S/../Inputs/gmlt.ll -; RUN: %llc_dwarf -O0 -filetype=obj -debug-info-for-profiling < %S/../Inputs/gmlt.ll | llvm-dwarfdump - | FileCheck %S/../Inputs/gmlt.ll --check-prefixes=PROFILING - -; There's a darwin specific test in X86/gmlt, so it's okay to XFAIL this here. -; XFAIL: darwin Index: test/DebugInfo/Generic/gmlt_profiling.ll =================================================================== --- /dev/null +++ test/DebugInfo/Generic/gmlt_profiling.ll @@ -0,0 +1,35 @@ +; REQUIRES: object-emission +; RUN: %llc_dwarf -O0 -filetype=obj < %S/gmlt_profiling.ll | llvm-dwarfdump - | FileCheck %S/gmlt_profiling.ll + +; There's a darwin specific test in X86/gmlt, so it's okay to XFAIL this here. +; XFAIL: darwin + +; CHECK: .debug_info +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "f1" +; With debug-info-for-profiling attribute, we need to emit decl_file and +; decl_line of the subprogram. +; CHECK-NEXT: DW_AT_decl_file +; CHECK-NEXT: DW_AT_decl_line + +; Function Attrs: nounwind uwtable +define void @_Z2f1v() !dbg !4 { +entry: + ret void, !dbg !13 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!10, !11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, emissionKind: LineTablesOnly, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2, debugInfoForProfiling: true) +!1 = !DIFile(filename: "gmlt.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!4 = distinct !DISubprogram(name: "f1", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !5, type: !6, variables: !2) +!5 = !DIFile(filename: "gmlt.cpp", directory: "/tmp/dbginfo") +!6 = !DISubroutineType(types: !2) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{!"clang version 3.6.0 "} +!13 = !DILocation(line: 1, column: 12, scope: !4) Index: test/DebugInfo/Inputs/gmlt.ll =================================================================== --- test/DebugInfo/Inputs/gmlt.ll +++ test/DebugInfo/Inputs/gmlt.ll @@ -1,157 +0,0 @@ -; REQUIRES: object-emission - -; Generated from the following source compiled with clang++ -gmlt: -; void f1() {} -; void __attribute__((section("__TEXT,__bar"))) f2() {} -; void __attribute__((always_inline)) f3() { f1(); } -; void f4() { f3(); } - -; Check that -; * -gmlt includes no DW_TAG_subprograms for subprograms without inlined -; subroutines. -; * yet still produces DW_AT_ranges and a range list in debug_ranges that -; describes those subprograms - -; CHECK: DW_TAG_compile_unit -; CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 -; CHECK-NOT: {{DW_TAG|NULL}} - -; Omitting the subprograms without inlined subroutines is not possible -; currently on Darwin as dsymutil will drop the whole CU if it has no subprograms -; (which happens with this optimization if there are no inlined subroutines). - -; DARWIN: DW_TAG_subprogram -; DARWIN-NOT: DW_TAG -; DARWIN: DW_AT_name {{.*}} "f1" -; DARWIN-NOT: {{DW_TAG|NULL}} -; DARWIN: DW_TAG_subprogram -; DARWIN-NOT: DW_TAG -; DARWIN: DW_AT_name {{.*}} "f2" -; DARWIN-NOT: {{DW_TAG|NULL}} -; DARWIN: DW_TAG_subprogram -; DARWIN-NOT: DW_TAG -; Can't check the abstract_origin value across the DARWIN/CHECK checking and -; ordering, so don't bother - just trust me, it refers to f3 down there. -; DARWIN: DW_AT_abstract_origin -; DARWIN-NOT: {{DW_TAG|NULL}} - - -; FIXME: Emitting separate abstract definitions is inefficient when we could -; just attach the DW_AT_name to the inlined_subroutine directly. Except that -; would produce many string relocations. Implement string indexing in the -; skeleton CU to address the relocation problem, then remove abstract -; definitions from -gmlt here. - -; CHECK: DW_TAG_subprogram -; CHECK-NEXT: DW_AT_name {{.*}} "f3" - -; FIXME: We don't really need DW_AT_inline, consumers can ignore this due to -; the absence of high_pc/low_pc/ranges and know that they just need it for -; retrieving the name of a concrete inlined instance - -; CHECK-NOT: {{DW_TAG|DW_AT|NULL}} - -; Check that we only provide the minimal attributes on a subprogram to save space. -; CHECK: DW_TAG_subprogram -; CHECK-NEXT: DW_AT_low_pc -; CHECK-NEXT: DW_AT_high_pc -; CHECK-NEXT: DW_AT_name -; CHECK-NOT: {{DW_TAG|DW_AT}} -; CHECK: DW_TAG_inlined_subroutine - -; As mentioned above - replace DW_AT_abstract_origin with DW_AT_name to save -; space once we have support for string indexing in non-dwo sections - -; CHECK-NEXT: DW_AT_abstract_origin {{.*}} "f3" -; CHECK-NEXT: DW_AT_low_pc -; CHECK-NEXT: DW_AT_high_pc -; CHECK-NEXT: DW_AT_call_file -; CHECK-NEXT: DW_AT_call_line - -; Make sure we don't have any other subprograms here (subprograms with no -; inlined subroutines are omitted by design to save space) - -; CHECK-NOT: {{DW_TAG|DW_AT}} -; CHECK: NULL -; CHECK-NOT: {{DW_TAG|DW_AT}} -; CHECK: NULL - -; PROFILING: DW_TAG_subprogram -; PROFILING: DW_AT_name {{.*}} "f1" -; With -debug-info-for-profiling, we need to emit decl_file a-nd decl_line -; of the subprogram. -; PROFILING: DW_AT_decl_file -; PROFILING: DW_AT_decl_line - -; CHECK: .debug_ranges contents: - -; ... some addresses (depends on platform (such as platforms with function -; reordering in the linker), and looks wonky on platforms with zero values -; written in relocation places (dumper needs to be fixed to read the -; relocations rather than interpret that as the end of a range list)) - -; CHECK: 00000000 - - -; Check that we don't emit any pubnames or pubtypes under -gmlt -; CHECK: .debug_pubnames contents: -; CHECK-NOT: Offset - -; CHECK: .debug_pubtypes contents: -; CHECK-NOT: Offset - -; CHECK: .apple{{.*}} contents: - -; Function Attrs: nounwind uwtable -define void @_Z2f1v() #0 !dbg !4 { -entry: - ret void, !dbg !13 -} - -; Function Attrs: nounwind uwtable -define void @_Z2f2v() #0 section "__TEXT,__bar" !dbg !7 { -entry: - ret void, !dbg !14 -} - -; Function Attrs: alwaysinline nounwind uwtable -define void @_Z2f3v() #1 !dbg !8 { -entry: - call void @_Z2f1v(), !dbg !15 - ret void, !dbg !16 -} - -; Function Attrs: nounwind uwtable -define void @_Z2f4v() #0 !dbg !9 { -entry: - call void @_Z2f1v() #2, !dbg !17 - ret void, !dbg !19 -} - -attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #1 = { alwaysinline nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #2 = { nounwind } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!10, !11} -!llvm.ident = !{!12} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, emissionKind: LineTablesOnly, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2) -!1 = !DIFile(filename: "gmlt.cpp", directory: "/tmp/dbginfo") -!2 = !{} -!4 = distinct !DISubprogram(name: "f1", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !5, type: !6, variables: !2) -!5 = !DIFile(filename: "gmlt.cpp", directory: "/tmp/dbginfo") -!6 = !DISubroutineType(types: !2) -!7 = distinct !DISubprogram(name: "f2", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 2, file: !1, scope: !5, type: !6, variables: !2) -!8 = distinct !DISubprogram(name: "f3", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 3, file: !1, scope: !5, type: !6, variables: !2) -!9 = distinct !DISubprogram(name: "f4", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 4, file: !1, scope: !5, type: !6, variables: !2) -!10 = !{i32 2, !"Dwarf Version", i32 4} -!11 = !{i32 2, !"Debug Info Version", i32 3} -!12 = !{!"clang version 3.6.0 "} -!13 = !DILocation(line: 1, column: 12, scope: !4) -!14 = !DILocation(line: 2, column: 53, scope: !7) -!15 = !DILocation(line: 3, column: 44, scope: !8) -!16 = !DILocation(line: 3, column: 50, scope: !8) -!17 = !DILocation(line: 3, column: 44, scope: !8, inlinedAt: !18) -!18 = !DILocation(line: 4, column: 13, scope: !9) -!19 = !DILocation(line: 4, column: 19, scope: !9) Index: unittests/IR/MetadataTest.cpp =================================================================== --- unittests/IR/MetadataTest.cpp +++ unittests/IR/MetadataTest.cpp @@ -95,7 +95,7 @@ return DICompileUnit::getDistinct(Context, 1, getFile(), "clang", false, "-g", 2, "", DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(), - getTuple(), getTuple(), 0, true); + getTuple(), getTuple(), 0, true, false); } DIType *getBasicType(StringRef Name) { return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); @@ -1406,7 +1406,8 @@ auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true); + RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true, + false); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); @@ -1463,7 +1464,7 @@ auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true); + RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false); auto *GlobalVariables = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getGlobalVariables().get());