[llvm] r346531 - Add total function byte size and inline function byte size to "llvm-dwarfdump --statistics"

Greg Clayton via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 9 10:10:02 PST 2018


Author: gclayton
Date: Fri Nov  9 10:10:02 2018
New Revision: 346531

URL: http://llvm.org/viewvc/llvm-project?rev=346531&view=rev
Log:
Add total function byte size and inline function byte size to "llvm-dwarfdump --statistics"

Differential Revision: https://reviews.llvm.org/D54217


Modified:
    llvm/trunk/test/tools/llvm-dwarfdump/X86/statistics.ll
    llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp

Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/statistics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/statistics.ll?rev=346531&r1=346530&r2=346531&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/statistics.ll (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/statistics.ll Fri Nov  9 10:10:02 2018
@@ -27,6 +27,9 @@
 ; CHECK-NOT: "scope bytes covered":0
 ; CHECK-NOT "scope bytes covered":[[BYTES]]
 ; CHECK: "scope bytes covered":
+; CHECK: "total function size":[[FUNCSIZE:[0-9]+]]
+; CHECK: "total inlined function size":[[INLINESIZE:[0-9]+]]
+
 
 ; ModuleID = '/tmp/quality.cpp'
 source_filename = "/tmp/quality.cpp"

Modified: llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp?rev=346531&r1=346530&r2=346531&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp (original)
+++ llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp Fri Nov  9 10:10:02 2018
@@ -25,7 +25,7 @@ struct PerFunctionStats {
   bool IsFunction = false;
 };
 
-/// Holds accumulated global statistics about local variables.
+/// Holds accumulated global statistics about DIEs.
 struct GlobalStats {
   /// Total number of PC range bytes covered by DW_AT_locations.
   unsigned ScopeBytesCovered = 0;
@@ -34,6 +34,13 @@ struct GlobalStats {
   unsigned ScopeBytesFromFirstDefinition = 0;
   /// Total number of call site entries (DW_TAG_call_site).
   unsigned CallSiteEntries = 0;
+  /// Total byte size of concrete functions. This byte size includes
+  /// inline functions contained in the concrete functions.
+  uint64_t FunctionSize = 0;
+  /// Total byte size of inlined functions. This is the total number of bytes
+  /// for the top inline functions within concrete functions. This can help
+  /// tune the inline settings when compiling to match user expectations.
+  uint64_t InlineFunctionSize = 0;
 };
 
 /// Extract the low pc from a Die.
@@ -53,6 +60,7 @@ static uint64_t getLowPC(DWARFDie Die) {
 static void collectStatsForDie(DWARFDie Die, std::string FnPrefix,
                                std::string VarPrefix, uint64_t ScopeLowPC,
                                uint64_t BytesInScope,
+                               uint32_t InlineDepth,
                                StringMap<PerFunctionStats> &FnStatMap,
                                GlobalStats &GlobalStats) {
   bool HasLoc = false;
@@ -137,24 +145,27 @@ static void collectStatsForDie(DWARFDie
 static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix,
                                   std::string VarPrefix, uint64_t ScopeLowPC,
                                   uint64_t BytesInScope,
+                                  uint32_t InlineDepth,
                                   StringMap<PerFunctionStats> &FnStatMap,
                                   GlobalStats &GlobalStats) {
   // Handle any kind of lexical scope.
-  if (Die.getTag() == dwarf::DW_TAG_subprogram ||
-      Die.getTag() == dwarf::DW_TAG_inlined_subroutine ||
-      Die.getTag() == dwarf::DW_TAG_lexical_block) {
+  const dwarf::Tag Tag = Die.getTag();
+  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;
+  if (IsFunction || IsInlinedFunction || IsBlock) {
 
     // Reset VarPrefix when entering a new function.
     if (Die.getTag() == dwarf::DW_TAG_subprogram ||
         Die.getTag() == dwarf::DW_TAG_inlined_subroutine)
       VarPrefix = "v";
-  
+
     // Ignore forward declarations.
     if (Die.find(dwarf::DW_AT_declaration))
       return;
 
     // Count the function.
-    if (Die.getTag() != dwarf::DW_TAG_lexical_block) {
+    if (!IsBlock) {
       StringRef Name = Die.getName(DINameKind::LinkageName);
       if (Name.empty())
         Name = Die.getName(DINameKind::ShortName);
@@ -174,21 +185,32 @@ static void collectStatsRecursive(DWARFD
       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)
+    if (BytesInThisScope) {
       BytesInScope = BytesInThisScope;
+      if (IsFunction)
+        GlobalStats.FunctionSize += BytesInThisScope;
+      else if (IsInlinedFunction && InlineDepth == 0)
+        GlobalStats.InlineFunctionSize += BytesInThisScope;
+    }
   } else {
     // Not a scope, visit the Die itself. It could be a variable.
     collectStatsForDie(Die, FnPrefix, VarPrefix, ScopeLowPC, BytesInScope,
-                       FnStatMap, GlobalStats);
+                       InlineDepth, FnStatMap, GlobalStats);
   }
 
+  // Set InlineDepth correctly for child recursion
+  if (IsFunction)
+    InlineDepth = 0;
+  else if (IsInlinedFunction)
+    ++InlineDepth;
+
   // Traverse children.
   unsigned LexicalBlockIndex = 0;
   DWARFDie Child = Die.getFirstChild();
@@ -198,7 +220,7 @@ static void collectStatsRecursive(DWARFD
       ChildVarPrefix += toHex(LexicalBlockIndex++) + '.';
 
     collectStatsRecursive(Child, FnPrefix, ChildVarPrefix, ScopeLowPC,
-                          BytesInScope, FnStatMap, GlobalStats);
+                          BytesInScope, InlineDepth, FnStatMap, GlobalStats);
     Child = Child.getSibling();
   }
 }
@@ -231,7 +253,7 @@ bool collectStatsForObjectFile(ObjectFil
   StringMap<PerFunctionStats> Statistics;
   for (const auto &CU : static_cast<DWARFContext *>(&DICtx)->compile_units())
     if (DWARFDie CUDie = CU->getUnitDIE(false))
-      collectStatsRecursive(CUDie, "/", "g", 0, 0, Statistics, GlobalStats);
+      collectStatsRecursive(CUDie, "/", "g", 0, 0, 0, Statistics, GlobalStats);
 
   /// The version number should be increased every time the algorithm is changed
   /// (including bug fixes). New metrics may be added without increasing the
@@ -271,6 +293,8 @@ bool collectStatsForObjectFile(ObjectFil
   printDatum(OS, "scope bytes total",
              GlobalStats.ScopeBytesFromFirstDefinition);
   printDatum(OS, "scope bytes covered", GlobalStats.ScopeBytesCovered);
+  printDatum(OS, "total function size", GlobalStats.FunctionSize);
+  printDatum(OS, "total inlined function size", GlobalStats.InlineFunctionSize);
   OS << "}\n";
   LLVM_DEBUG(
       llvm::dbgs() << "Total Availability: "




More information about the llvm-commits mailing list