diff --git a/llvm/tools/llvm-dwarfdump/Statistics.cpp b/llvm/tools/llvm-dwarfdump/Statistics.cpp
new file mode 100644
index 0000000..9a7454a
--- /dev/null
+++ b/llvm/tools/llvm-dwarfdump/Statistics.cpp
@@ -0,0 +1,239 @@
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
+#include "llvm/Object/ObjectFile.h"
+
+#define DEBUG_TYPE "dwarfdump"
+using namespace llvm;
+using namespace object;
+
+/// Holds statistics for one function (or other entity that has a PC range and
+/// contains variables, such as a compile unit).
+struct PerFunctionStats {
+  /// Number of inlined instances of this function.
+  unsigned NumFnInlined = 0;
+  /// Number of variables with location across all inlined instances.
+  unsigned TotalVarWithLoc = 0;
+  /// Number of constants with location across all inlined instances.
+  unsigned ConstantMembers = 0;
+  /// List of all Variables in this function.
+  SmallDenseSet<uint32_t, 4> VarsInFunction;
+  /// Compile units also cover a PC range, but have this flag set to false.
+  bool IsFunction = false;
+};
+
+/// Holds accumulated global statistics about local variables.
+struct GlobalStats {
+  /// Total number of PC range bytes covered by DW_AT_locations.
+  unsigned ScopeBytesCovered = 0;
+  /// Total number of PC range bytes in each variable's enclosing scope,
+  /// starting from the first definition of the variable.
+  unsigned ScopeBytesFromFirstDefinition = 0;
+};
+
+/// Extract the low pc from a Die.
+static uint64_t getLowPC(DWARFDie Die) {
+  if (Die.getAddressRanges().size())
+    return Die.getAddressRanges()[0].LowPC;
+  return dwarf::toAddress(Die.find(dwarf::DW_AT_low_pc), 0);
+}
+
+/// Collect debug info quality metrics for one DIE.
+static void collectStatsForDie(DWARFDie Die, std::string Prefix,
+                               uint64_t ScopeLowPC, uint64_t BytesInScope,
+                               StringMap<PerFunctionStats> &FnStatMap,
+                               GlobalStats &GlobalStats) {
+  bool HasLoc = false;
+  uint64_t BytesCovered = 0;
+  uint64_t OffsetToFirstDefinition = 0;
+  if (Die.find(dwarf::DW_AT_const_value)) {
+    // This catches constant members *and* variables.
+    HasLoc = true;
+    BytesCovered = BytesInScope;
+  } else if (Die.getTag() == dwarf::DW_TAG_variable ||
+             Die.getTag() == dwarf::DW_TAG_formal_parameter) {
+    // Handle variables and function arguments.
+    auto FormValue = Die.find(dwarf::DW_AT_location);
+    HasLoc = FormValue.hasValue();
+    if (HasLoc) {
+      // Get PC coverage.
+      if (auto DebugLocOffset = FormValue->getAsSectionOffset()) {
+        auto *DebugLoc = Die.getDwarfUnit()->getContext().getDebugLoc();
+        if (auto List = DebugLoc->getLocationListAtOffset(*DebugLocOffset)) {
+          for (auto Entry : List->Entries)
+            BytesCovered += Entry.End - Entry.Begin;
+          if (List->Entries.size()) {
+            uint64_t FirstDef = List->Entries[0].Begin;
+            uint64_t UnitOfs = getLowPC(Die.getDwarfUnit()->getUnitDIE());
+            // Ranges sometimes start before the lexical scope.
+            if (UnitOfs + FirstDef >= ScopeLowPC)
+              OffsetToFirstDefinition = UnitOfs + FirstDef - ScopeLowPC;
+            // Or even after it. Count that as a failure.
+            if (OffsetToFirstDefinition > BytesInScope)
+              OffsetToFirstDefinition = 0;
+          }
+        }
+        assert(BytesInScope);
+      } else {
+        // Assume the entire range is covered by a single location.
+        BytesCovered = BytesInScope;
+      }
+    }
+  } else {
+    // Not a variable or constant member.
+    return;
+  }
+
+  // Collect PC range coverage data.
+  auto &FnStats = FnStatMap[Prefix];
+  if (DWARFDie D =
+          Die.getAttributeValueAsReferencedDie(dwarf::DW_AT_abstract_origin))
+    Die = D;
+  // This is a unique ID for the variable inside the current object file.
+  unsigned CanonicalDieOffset = Die.getOffset();
+  FnStats.VarsInFunction.insert(CanonicalDieOffset);
+  if (BytesInScope) {
+    FnStats.TotalVarWithLoc += (unsigned)HasLoc;
+    // Adjust for the fact the variables often start their lifetime in the
+    // middle of the scope.
+    BytesInScope -= OffsetToFirstDefinition;
+    // Turns out we have a lot of ranges that extend past the lexical scope.
+    GlobalStats.ScopeBytesCovered += std::min(BytesInScope, BytesCovered);
+    GlobalStats.ScopeBytesFromFirstDefinition += BytesInScope;
+    assert(GlobalStats.ScopeBytesCovered <=
+           GlobalStats.ScopeBytesFromFirstDefinition);
+  } else {
+    FnStats.ConstantMembers++;
+  }
+}
+
+/// Recursively collect debug info quality metrics.
+static void collectStatsRecursive(DWARFDie Die, std::string Prefix,
+                                  uint64_t ScopeLowPC, uint64_t BytesInScope,
+                                  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) {
+    // Ignore forward declarations.
+    if (Die.find(dwarf::DW_AT_declaration))
+      return;
+
+    // Count the function.
+    if (Die.getTag() != dwarf::DW_TAG_lexical_block) {
+      StringRef Name = Die.getName(DINameKind::LinkageName);
+      if (Name.empty())
+        Name = Die.getName(DINameKind::ShortName);
+      Prefix = Name;
+      // Skip over abstract origins.
+      if (Die.find(dwarf::DW_AT_inline))
+        return;
+      // We've seen an (inlined) instance of this function.
+      auto &FnStats = FnStatMap[Name];
+      FnStats.NumFnInlined++;
+      FnStats.IsFunction = true;
+    }
+
+    // PC Ranges.
+    auto Ranges = Die.getAddressRanges();
+    uint64_t BytesInThisScope = 0;
+    for (auto Range : Ranges)
+      BytesInThisScope += Range.HighPC - Range.LowPC;
+    ScopeLowPC = getLowPC(Die);
+
+    if (BytesInThisScope)
+      BytesInScope = BytesInThisScope;
+  } else {
+    // Not a scope, visit the Die itself. It could be a variable.
+    collectStatsForDie(Die, Prefix, ScopeLowPC, BytesInScope, FnStatMap,
+                       GlobalStats);
+  }
+
+  // Traverse children.
+  DWARFDie Child = Die.getFirstChild();
+  while (Child) {
+    collectStatsRecursive(Child, Prefix, ScopeLowPC, BytesInScope, FnStatMap,
+                          GlobalStats);
+    Child = Child.getSibling();
+  }
+}
+
+/// Print machine-readable output.
+/// The machine-readable format is single-line JSON output.
+/// \{
+static void printDatum(raw_ostream &OS, const char *Key, StringRef Value) {
+  OS << ",\"" << Key << "\":\"" << Value << '"';
+  DEBUG(llvm::dbgs() << Key << ": " << Value << '\n');
+}
+static void printDatum(raw_ostream &OS, const char *Key, uint64_t Value) {
+  OS << ",\"" << Key << "\":" << Value;
+  DEBUG(llvm::dbgs() << Key << ": " << Value << '\n');
+}
+/// \}
+
+/// Collect debug info quality metrics for an entire DIContext.
+///
+/// Do the impossible and reduce the quality of the debug info down to a few
+/// numbers. The idea is to condense the data into numbers that can be tracked
+/// over time to identify trends in newer compiler versions and gauge the effect
+/// of particular optimizations. The raw numbers themselves are not particularly
+/// useful, only the delta between compiling the same program with different
+/// compilers is.
+bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
+                               Twine Filename, raw_ostream &OS) {
+  StringRef FormatName = Obj.getFileFormatName();
+  GlobalStats GlobalStats;
+  StringMap<PerFunctionStats> Statistics;
+  for (const auto &CU : static_cast<DWARFContext *>(&DICtx)->compile_units())
+    if (DWARFDie CUDie = CU->getUnitDIE(false))
+      collectStatsRecursive(CUDie, "/", 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
+  /// version.
+  unsigned Version = 1;
+  unsigned VarTotal = 0;
+  unsigned VarUnique = 0;
+  unsigned VarWithLoc = 0;
+  unsigned NumFunctions = 0;
+  unsigned NumInlinedFunctions = 0;
+  for (auto &Entry : Statistics) {
+    PerFunctionStats &Stats = Entry.getValue();
+    unsigned TotalVars = Stats.VarsInFunction.size() * Stats.NumFnInlined;
+    unsigned Constants = Stats.ConstantMembers;
+    VarWithLoc += Stats.TotalVarWithLoc + Constants;
+    VarTotal += TotalVars + Constants;
+    VarUnique += Stats.VarsInFunction.size();
+    DEBUG(for (auto V : Stats.VarsInFunction)
+            llvm::dbgs() << Entry.getKey() << ": " << V << "\n");
+    NumFunctions += Stats.IsFunction;
+    NumInlinedFunctions += Stats.IsFunction * Stats.NumFnInlined;
+  }
+
+  // Print summary.
+  OS.SetBufferSize(1024);
+  OS << "{\"version\":\"" << Version << '"';
+  DEBUG(llvm::dbgs() << "Variable location quality metrics\n";
+        llvm::dbgs() << "---------------------------------\n");
+  printDatum(OS, "file", Filename.str());
+  printDatum(OS, "format", FormatName);
+  printDatum(OS, "source functions", NumFunctions);
+  printDatum(OS, "inlined functions", NumInlinedFunctions);
+  printDatum(OS, "unique source variables", VarUnique);
+  printDatum(OS, "source variables", VarTotal);
+  printDatum(OS, "variables with location", VarWithLoc);
+  printDatum(OS, "scope bytes total",
+             GlobalStats.ScopeBytesFromFirstDefinition);
+  printDatum(OS, "scope bytes covered", GlobalStats.ScopeBytesCovered);
+  OS << "}\n";
+  DEBUG(
+      llvm::dbgs() << "Total Availability: "
+                   << (int)std::round((VarWithLoc * 100.0) / VarTotal) << "%\n";
+      llvm::dbgs() << "PC Ranges covered: "
+                   << (int)std::round((GlobalStats.ScopeBytesCovered * 100.0) /
+                                      GlobalStats.ScopeBytesFromFirstDefinition)
+                   << "%\n");
+  return true;
+}
