[llvm-pdbdump] Allow sorting / filtering by immediate padding
authorZachary Turner <zturner@google.com>
Tue, 25 Apr 2017 20:22:29 +0000 (20:22 +0000)
committerZachary Turner <zturner@google.com>
Tue, 25 Apr 2017 20:22:29 +0000 (20:22 +0000)
llvm-svn: 301358

llvm/include/llvm/DebugInfo/PDB/UDTLayout.h
llvm/lib/DebugInfo/PDB/UDTLayout.cpp
llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp
llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
llvm/tools/llvm-pdbdump/llvm-pdbdump.h

index 8283113..6bc3660 100644 (file)
@@ -44,6 +44,7 @@ public:
   virtual ~LayoutItemBase() {}
 
   uint32_t deepPaddingSize() const;
+  virtual uint32_t immediatePadding() const { return 0; }
   virtual uint32_t tailPadding() const;
 
   const UDTLayoutBase *getParent() const { return Parent; }
@@ -175,8 +176,10 @@ public:
   ClassLayout(ClassLayout &&Other) = default;
 
   const PDBSymbolTypeUDT &getClass() const { return UDT; }
+  uint32_t immediatePadding() const override;
 
 private:
+  BitVector ImmediateUsedBytes;
   std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage;
   const PDBSymbolTypeUDT &UDT;
 };
index 6c6bb26..aacefae 100644 (file)
@@ -60,7 +60,6 @@ uint32_t LayoutItemBase::tailPadding() const {
   return UsedBytes.size() - (Last + 1);
 }
 
-
 DataMemberLayoutItem::DataMemberLayoutItem(
     const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> Member)
     : LayoutItemBase(&Parent, Member.get(), Member->getName(),
@@ -126,13 +125,25 @@ uint32_t UDTLayoutBase::tailPadding() const {
 
 ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
     : UDTLayoutBase(nullptr, UDT, UDT.getName(), 0, UDT.getLength(), false),
-      UDT(UDT) {}
+      UDT(UDT) {
+  ImmediateUsedBytes.resize(SizeOf, false);
+  for (auto &LI : LayoutItems) {
+    uint32_t Begin = LI->getOffsetInParent();
+    uint32_t End = Begin + LI->getLayoutSize();
+    End = std::min(SizeOf, End);
+    ImmediateUsedBytes.set(Begin, End);
+  }
+}
 
 ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
     : ClassLayout(*UDT) {
   OwnedStorage = std::move(UDT);
 }
 
+uint32_t ClassLayout::immediatePadding() const {
+  return SizeOf - ImmediateUsedBytes.count();
+}
+
 BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
                                  uint32_t OffsetInParent, bool Elide,
                                  std::unique_ptr<PDBSymbolTypeBaseClass> B)
index c6d71e8..90f7772 100644 (file)
@@ -96,5 +96,13 @@ void ClassDefinitionDumper::prettyPrintClassOutro(const ClassLayout &Layout) {
         << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr
         << "% of class size)";
     Printer.NewLine();
+    APFloat Pct2(100.0 * (double)Layout.immediatePadding() /
+                 (double)Layout.getSize());
+    PctStr.clear();
+    Pct2.toString(PctStr, 4);
+    WithColor(Printer, PDB_ColorItem::Padding).get()
+        << "Immediate padding " << Layout.immediatePadding() << " bytes ("
+        << PctStr << "% of class size)";
+    Printer.NewLine();
   }
 }
index 324a26f..cd156f0 100644 (file)
@@ -51,6 +51,17 @@ static bool ComparePaddingPct(const LayoutPtr &S1, const LayoutPtr &S2) {
   return Pct1 < Pct2;
 }
 
+static bool ComparePaddingImmediate(const LayoutPtr &S1, const LayoutPtr &S2) {
+  return S1->immediatePadding() < S2->immediatePadding();
+}
+
+static bool ComparePaddingPctImmediate(const LayoutPtr &S1,
+                                       const LayoutPtr &S2) {
+  double Pct1 = (double)S1->immediatePadding() / (double)S1->getSize();
+  double Pct2 = (double)S2->immediatePadding() / (double)S2->getSize();
+  return Pct1 < Pct2;
+}
+
 static CompareFunc getComparisonFunc(opts::pretty::ClassSortMode Mode) {
   switch (Mode) {
   case opts::pretty::ClassSortMode::Name:
@@ -61,6 +72,10 @@ static CompareFunc getComparisonFunc(opts::pretty::ClassSortMode Mode) {
     return ComparePadding;
   case opts::pretty::ClassSortMode::PaddingPct:
     return ComparePaddingPct;
+  case opts::pretty::ClassSortMode::PaddingImmediate:
+    return ComparePaddingImmediate;
+  case opts::pretty::ClassSortMode::PaddingPctImmediate:
+    return ComparePaddingPctImmediate;
   default:
     return nullptr;
   }
@@ -104,6 +119,10 @@ filterAndSortClassDefs(LinePrinter &Printer, Enumerator &E,
       ++Discarded;
       continue;
     }
+    if (Layout->immediatePadding() < opts::pretty::ImmediatePaddingThreshold) {
+      ++Discarded;
+      continue;
+    }
 
     Filtered.push_back(std::move(Layout));
   }
index e498c01..7337b1d 100644 (file)
@@ -132,7 +132,12 @@ cl::opt<ClassSortMode> ClassOrder(
         clEnumValN(ClassSortMode::Padding, "padding",
                    "Sort classes by amount of padding"),
         clEnumValN(ClassSortMode::PaddingPct, "padding-pct",
-                   "Sort classes by percentage of space consumed by padding")),
+                   "Sort classes by percentage of space consumed by padding"),
+        clEnumValN(ClassSortMode::PaddingImmediate, "padding-imm",
+                   "Sort classes by amount of immediate padding"),
+        clEnumValN(ClassSortMode::PaddingPctImmediate, "padding-pct-imm",
+                   "Sort classes by percentage of space consumed by immediate "
+                   "padding")),
     cl::cat(TypeCategory), cl::sub(PrettySubcommand));
 
 cl::opt<ClassDefinitionFormat> ClassFormat(
@@ -197,6 +202,12 @@ cl::opt<uint32_t> PaddingThreshold(
     "min-class-padding", cl::desc("Displays only those classes which have at "
                                   "least the specified amount of padding."),
     cl::init(0), cl::cat(FilterCategory), cl::sub(PrettySubcommand));
+cl::opt<uint32_t> ImmediatePaddingThreshold(
+    "min-class-padding-imm",
+    cl::desc("Displays only those classes which have at least the specified "
+             "amount of immediate padding, ignoring padding internal to bases "
+             "and aggregates."),
+    cl::init(0), cl::cat(FilterCategory), cl::sub(PrettySubcommand));
 
 cl::opt<bool> ExcludeCompilerGenerated(
     "no-compiler-generated",
index d1af06f..f080d6d 100644 (file)
@@ -19,7 +19,15 @@ namespace opts {
 namespace pretty {
 
 enum class ClassDefinitionFormat { None, Layout, All };
-enum class ClassSortMode { None, Name, Size, Padding, PaddingPct };
+enum class ClassSortMode {
+  None,
+  Name,
+  Size,
+  Padding,
+  PaddingPct,
+  PaddingImmediate,
+  PaddingPctImmediate
+};
 
 extern llvm::cl::opt<bool> Compilands;
 extern llvm::cl::opt<bool> Symbols;
@@ -40,6 +48,7 @@ extern llvm::cl::list<std::string> IncludeCompilands;
 extern llvm::cl::opt<ClassSortMode> ClassOrder;
 extern llvm::cl::opt<uint32_t> SizeThreshold;
 extern llvm::cl::opt<uint32_t> PaddingThreshold;
+extern llvm::cl::opt<uint32_t> ImmediatePaddingThreshold;
 extern llvm::cl::opt<ClassDefinitionFormat> ClassFormat;
 extern llvm::cl::opt<uint32_t> ClassRecursionDepth;
 }