From 14911bb49761879d9f8acb3fae02e21cd42a58b7 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 8 Feb 2019 00:51:33 +0000 Subject: [PATCH] lvm-dwarfdump: Stop counting out-of-line subprogram in the "inlined functions" statistic. DW_TAG_subprogram DIEs should not be counted in the inlined function statistic. This also addresses the source variables count, as that uses the inlined function count in its calculations. Differential revision: https://reviews.llvm.org/D57849 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353491 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/tools/llvm-dwarfdump/X86/statistics.ll | 2 +- .../X86/stats-inlining-multi-cu.ll | 2 +- .../X86/stats-inlining-single-cu.ll | 2 +- tools/llvm-dwarfdump/Statistics.cpp | 45 ++++++++++++------- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/test/tools/llvm-dwarfdump/X86/statistics.ll b/test/tools/llvm-dwarfdump/X86/statistics.ll index 0ddae7e39ac..73c56dabf87 100644 --- a/test/tools/llvm-dwarfdump/X86/statistics.ll +++ b/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":1 +; CHECK: "version":2 ; int GlobalConst = 42; ; int Global; diff --git a/test/tools/llvm-dwarfdump/X86/stats-inlining-multi-cu.ll b/test/tools/llvm-dwarfdump/X86/stats-inlining-multi-cu.ll index f8656e6a7b7..e6e193c2004 100644 --- a/test/tools/llvm-dwarfdump/X86/stats-inlining-multi-cu.ll +++ b/test/tools/llvm-dwarfdump/X86/stats-inlining-multi-cu.ll @@ -4,7 +4,7 @@ ; Test that abstract origins in multiple CUs are uniqued. ; CHECK: "source functions":4, -; CHECK-SAME: "inlined functions":5, +; CHECK-SAME: "inlined functions":2, ; CHECK-SAME: "unique source variables":4 ; CHECK-SAME: "source variables":6 ; CHECK-SAME: "variables with location":6 diff --git a/test/tools/llvm-dwarfdump/X86/stats-inlining-single-cu.ll b/test/tools/llvm-dwarfdump/X86/stats-inlining-single-cu.ll index 14ef7096132..5a4c3541a5c 100644 --- a/test/tools/llvm-dwarfdump/X86/stats-inlining-single-cu.ll +++ b/test/tools/llvm-dwarfdump/X86/stats-inlining-single-cu.ll @@ -5,7 +5,7 @@ ; The results for both tests should be identical. ; CHECK: "source functions":4, -; CHECK-SAME: "inlined functions":5, +; CHECK-SAME: "inlined functions":2, ; CHECK-SAME: "unique source variables":4 ; CHECK-SAME: "source variables":6 ; CHECK-SAME: "variables with location":6 diff --git a/tools/llvm-dwarfdump/Statistics.cpp b/tools/llvm-dwarfdump/Statistics.cpp index 5fe7e8b4615..a01a5017c59 100644 --- a/tools/llvm-dwarfdump/Statistics.cpp +++ b/tools/llvm-dwarfdump/Statistics.cpp @@ -23,6 +23,9 @@ struct PerFunctionStats { StringSet<> VarsInFunction; /// Compile units also cover a PC range, but have this flag set to false. bool IsFunction = false; + /// Verify function definition has PC addresses (for detecting when + /// a function has been inlined everywhere). + bool HasPCAddresses = false; }; /// Holds accumulated global statistics about DIEs. @@ -136,8 +139,10 @@ static void collectStatsForDie(DWARFDie Die, std::string FnPrefix, GlobalStats.ScopeBytesFromFirstDefinition += BytesInScope; assert(GlobalStats.ScopeBytesCovered <= GlobalStats.ScopeBytesFromFirstDefinition); - } else { + } else if (Die.getTag() == dwarf::DW_TAG_member) { FnStats.ConstantMembers++; + } else { + FnStats.TotalVarWithLoc += (unsigned)HasLoc; } } @@ -164,6 +169,19 @@ static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix, if (Die.find(dwarf::DW_AT_declaration)) return; + // PC Ranges. + auto RangesOrError = Die.getAddressRanges(); + if (!RangesOrError) { + llvm::consumeError(RangesOrError.takeError()); + return; + } + + auto Ranges = RangesOrError.get(); + uint64_t BytesInThisScope = 0; + for (auto Range : Ranges) + BytesInThisScope += Range.HighPC - Range.LowPC; + ScopeLowPC = getLowPC(Die); + // Count the function. if (!IsBlock) { StringRef Name = Die.getName(DINameKind::LinkageName); @@ -175,23 +193,13 @@ static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix, return; // We've seen an (inlined) instance of this function. auto &FnStats = FnStatMap[Name]; - FnStats.NumFnInlined++; + if (IsInlinedFunction) + FnStats.NumFnInlined++; FnStats.IsFunction = true; + if (BytesInThisScope && !IsInlinedFunction) + FnStats.HasPCAddresses = true; } - // PC Ranges. - auto RangesOrError = Die.getAddressRanges(); - if (!RangesOrError) { - llvm::consumeError(RangesOrError.takeError()); - return; - } - - auto Ranges = RangesOrError.get(); - uint64_t BytesInThisScope = 0; - for (auto Range : Ranges) - BytesInThisScope += Range.HighPC - Range.LowPC; - ScopeLowPC = getLowPC(Die); - if (BytesInThisScope) { BytesInScope = BytesInThisScope; if (IsFunction) @@ -258,7 +266,7 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx, /// 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 = 1; + unsigned Version = 2; unsigned VarTotal = 0; unsigned VarUnique = 0; unsigned VarWithLoc = 0; @@ -267,9 +275,12 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx, for (auto &Entry : Statistics) { PerFunctionStats &Stats = Entry.getValue(); unsigned TotalVars = Stats.VarsInFunction.size() * Stats.NumFnInlined; + // Count variables in concrete out-of-line functions and in global scope. + if (Stats.HasPCAddresses || !Stats.IsFunction) + TotalVars += Stats.VarsInFunction.size(); unsigned Constants = Stats.ConstantMembers; VarWithLoc += Stats.TotalVarWithLoc + Constants; - VarTotal += TotalVars + Constants; + VarTotal += TotalVars; VarUnique += Stats.VarsInFunction.size(); LLVM_DEBUG(for (auto &V : Stats.VarsInFunction) llvm::dbgs() << Entry.getKey() << ": " << V.getKey() << "\n"); -- 2.50.1