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), + EmulatedTLS(false), EnableIPRA(false), DebugInfoForProfiling(false), FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard), ThreadModel(ThreadModel::POSIX), @@ -225,6 +225,9 @@ /// 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 @@ -299,7 +302,8 @@ ARE_EQUAL(FPDenormalMode) && ARE_EQUAL(ExceptionModel) && ARE_EQUAL(MCOptions) && - ARE_EQUAL(EnableIPRA); + ARE_EQUAL(EnableIPRA) && + ARE_EQUAL(DebugInfoForProfiling); #undef ARE_EQUAL } Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1184,8 +1184,10 @@ TheCU.addRange(RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd())); // Under -gmlt, skip building the subprogram if there are no inlined - // subroutines inside it. - if (TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly && + // 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 && + TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly && LScopes.getAbstractScopesList().empty() && !IsDarwin) { assert(InfoHolder.getScopeVariables().empty()); assert(DbgValues.empty()); Index: lib/CodeGen/AsmPrinter/DwarfUnit.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.h +++ lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -256,7 +256,7 @@ DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false); void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, - bool Minimal = false); + bool SkipSPAttributes = false); /// Find existing DIE or create new DIE for the given type. DIE *getOrCreateTypeDIE(const MDNode *N); Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1178,8 +1178,12 @@ } void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, - bool Minimal) { - if (!Minimal) + bool SkipSPAttributes) { + // If -fdebug-info-for-profiling is enabled, need to emit the subprogram + // and its source location. + bool SkipSPSourceLocation = SkipSPAttributes && + !Asm->TM.Options.DebugInfoForProfiling; + if (!SkipSPSourceLocation) if (applySubprogramDefinitionAttributes(SP, SPDie)) return; @@ -1187,12 +1191,13 @@ if (!SP->getName().empty()) addString(SPDie, dwarf::DW_AT_name, SP->getName()); + if (!SkipSPSourceLocation) + addSourceLine(SPDie, SP); + // Skip the rest of the attributes under -gmlt to save space. - if (Minimal) + if (SkipSPAttributes) return; - addSourceLine(SPDie, SP); - // Add the prototype if we have a prototype and we have a C like // language. uint16_t Language = getLanguage(); Index: lib/Target/TargetMachine.cpp =================================================================== --- lib/Target/TargetMachine.cpp +++ lib/Target/TargetMachine.cpp @@ -35,6 +35,10 @@ 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 // @@ -47,6 +51,8 @@ RequireStructuredCFG(false), Options(Options) { if (EnableIPRA.getNumOccurrences()) this->Options.EnableIPRA = EnableIPRA; + if (DebugInfoForProfiling.getNumOccurrences()) + this->Options.DebugInfoForProfiling = DebugInfoForProfiling; } TargetMachine::~TargetMachine() { Index: test/DebugInfo/Generic/gmlt.test =================================================================== --- test/DebugInfo/Generic/gmlt.test +++ test/DebugInfo/Generic/gmlt.test @@ -1,5 +1,6 @@ ; 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/Inputs/gmlt.ll =================================================================== --- test/DebugInfo/Inputs/gmlt.ll +++ test/DebugInfo/Inputs/gmlt.ll @@ -76,6 +76,12 @@ ; 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: