diff --git a/llvm/test/tools/llvm-dwarfdump/X86/locstats-for-inlined-vars.yaml b/llvm/test/tools/llvm-dwarfdump/X86/locstats-for-absctract-origin-vars.yaml rename from llvm/test/tools/llvm-dwarfdump/X86/locstats-for-inlined-vars.yaml rename to llvm/test/tools/llvm-dwarfdump/X86/locstats-for-absctract-origin-vars.yaml --- a/llvm/test/tools/llvm-dwarfdump/X86/locstats-for-inlined-vars.yaml +++ b/llvm/test/tools/llvm-dwarfdump/X86/locstats-for-absctract-origin-vars.yaml @@ -117,10 +117,12 @@ ## DW_TAG_variable <--(0x000000f8) ## DW_AT_decl_file (0x01) ## DW_AT_decl_line (1) +## DW_TAG_subprogram +## DW_AT_abstract_origin (0x000000f0) -# CHECK: "version": 7, -# CHECK: "#variables processed by location statistics": 15, -# CHECK: "#variables with 0% of parent scope covered by DW_AT_location": 11, +# CHECK: "version": 8, +# CHECK: "#variables processed by location statistics": 17, +# CHECK: "#variables with 0% of parent scope covered by DW_AT_location": 13, # CHECK: "#variables with 100% of parent scope covered by DW_AT_location": 4, --- !ELF @@ -263,6 +265,12 @@ Attributes: - Attribute: DW_AT_abstract_origin Form: DW_FORM_ref4 + - Code: 17 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_abstract_origin + Form: DW_FORM_ref4 debug_info: - Version: 4 AbbrOffset: 0x00 @@ -409,4 +417,7 @@ - Value: 1 ## DW_AT_decl_line - AbbrCode: 0 ## NULL - AbbrCode: 0 ## NULL + - AbbrCode: 17 ## DW_TAG_subprogram + Values: + - Value: 0xf0 ## DW_AT_abstract_origin - AbbrCode: 0 ## NULL diff --git a/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test b/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test --- a/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test +++ b/llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test @@ -69,7 +69,7 @@ # } # -CHECK: "version": 7, +CHECK: "version": 8, CHECK: "#functions": 3, CHECK: "#functions with location": 3, CHECK: "#inlined functions": 7, diff --git a/llvm/test/tools/llvm-dwarfdump/X86/statistics-v3.test b/llvm/test/tools/llvm-dwarfdump/X86/statistics-v3.test --- a/llvm/test/tools/llvm-dwarfdump/X86/statistics-v3.test +++ b/llvm/test/tools/llvm-dwarfdump/X86/statistics-v3.test @@ -64,7 +64,7 @@ # } # -CHECK: "version": 7, +CHECK: "version": 8, CHECK: "#functions": 3, CHECK: "#functions with location": 3, CHECK: "#inlined functions": 8, diff --git a/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll b/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll --- a/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll +++ b/llvm/test/tools/llvm-dwarfdump/X86/statistics.ll @@ -1,6 +1,6 @@ ; RUN: llc -O0 %s -o - -filetype=obj \ ; RUN: | llvm-dwarfdump -statistics - | FileCheck %s -; CHECK: "version": 7, +; CHECK: "version": 8, ; namespace test { ; extern int a; diff --git a/llvm/test/tools/llvm-dwarfdump/X86/stats-scope-bytes-covered.yaml b/llvm/test/tools/llvm-dwarfdump/X86/stats-scope-bytes-covered.yaml --- a/llvm/test/tools/llvm-dwarfdump/X86/stats-scope-bytes-covered.yaml +++ b/llvm/test/tools/llvm-dwarfdump/X86/stats-scope-bytes-covered.yaml @@ -33,7 +33,7 @@ ## DW_AT_location (0x00000023: ## [0x0000000000000003, 0x0000000000000005): DW_OP_reg2 RCX) -# CHECK: "version": 7, +# CHECK: "version": 8, # CHECK: "sum_all_variables(#bytes in parent scope)": 12, # CHECK: "sum_all_variables(#bytes in any scope covered by DW_AT_location)": 8 # CHECK: "sum_all_variables(#bytes in parent scope covered by DW_AT_location)": 4 diff --git a/llvm/tools/llvm-dwarfdump/Statistics.cpp b/llvm/tools/llvm-dwarfdump/Statistics.cpp --- a/llvm/tools/llvm-dwarfdump/Statistics.cpp +++ b/llvm/tools/llvm-dwarfdump/Statistics.cpp @@ -458,14 +458,20 @@ return; // Handle any kind of lexical scope. + const bool HasAbstractOrigin = Die.find(dwarf::DW_AT_abstract_origin) != None; const bool IsFunction = Tag == dwarf::DW_TAG_subprogram; const bool IsBlock = Tag == dwarf::DW_TAG_lexical_block; const bool IsInlinedFunction = Tag == dwarf::DW_TAG_inlined_subroutine; + // We want to know how many variables (with abstract_origin) don't have + // location info. + const bool IsCandidateForZeroLocCovTracking = + (IsInlinedFunction || (IsFunction && HasAbstractOrigin)); + AbstractOriginVarsTy AbstractOriginVars; // Get the vars of the inlined fn, so the locstats // reports the missing vars (with coverage 0%). - if (IsInlinedFunction) { + if (IsCandidateForZeroLocCovTracking) { auto OffsetFn = Die.find(dwarf::DW_AT_abstract_origin); if (OffsetFn) { uint64_t OffsetOfInlineFnCopy = (*OffsetFn).getRawUValue(); @@ -572,11 +578,11 @@ Child = Child.getSibling(); } - if (!IsInlinedFunction) + if (!IsCandidateForZeroLocCovTracking) return; - // After we have processed all vars of the inlined function, - // we want to know how many variables have no location. + // After we have processed all vars of the inlined function (or function with + // an abstract_origin), we want to know how many variables have no location. for (auto Offset : AbstractOriginVars) { LocStats.NumVarParam++; LocStats.VarParamLocStats[ZeroCoverageBucket]++; @@ -666,6 +672,8 @@ /// Collect zero location coverage for inlined variables which refer to /// a DW_AT_inline copy of subprogram that is out of order in the DWARF. +/// Also cover the variables of a concrete function (represented with +/// the DW_TAG_subprogram) with an abstract_origin attribute. static void collectZeroLocCovForVarsWithAbstractOrigin( DWARFUnit *DwUnit, GlobalStats &GlobalStats, LocationStats &LocStats, AbstractOriginVarsTyMap &GlobalAbstractOriginFnInfo, @@ -742,7 +750,7 @@ /// The version number should be increased every time the algorithm is changed /// (including bug fixes). New metrics may be added without increasing the /// version. - unsigned Version = 7; + unsigned Version = 8; unsigned VarParamTotal = 0; unsigned VarParamUnique = 0; unsigned VarParamWithLoc = 0;