[llvm] r309983 - [llvm-pdbutil] Allow diff to force module equivalencies.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 3 13:30:10 PDT 2017


Author: zturner
Date: Thu Aug  3 13:30:09 2017
New Revision: 309983

URL: http://llvm.org/viewvc/llvm-project?rev=309983&view=rev
Log:
[llvm-pdbutil] Allow diff to force module equivalencies.

Sometimes the normal module equivalence detection algorithm doesn't
quite work.  For example, you might build the same program with
MSVC and clang-cl, outputting to different object files, exes, and
PDBs, then compare them.  If the object files have different names
though, then they won't be treated as equivalent.  This way we
can force specific module indices to be treated as equivalent.

Modified:
    llvm/trunk/tools/llvm-pdbutil/Diff.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h

Modified: llvm/trunk/tools/llvm-pdbutil/Diff.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/Diff.cpp?rev=309983&r1=309982&r2=309983&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/Diff.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/Diff.cpp Thu Aug  3 13:30:09 2017
@@ -425,20 +425,66 @@ Error DiffStyle::diffInfoStream() {
   return Error::success();
 }
 
-static std::vector<std::pair<uint32_t, DbiModuleDescriptor>>
+typedef std::pair<uint32_t, DbiModuleDescriptor> IndexedModuleDescriptor;
+typedef std::vector<IndexedModuleDescriptor> IndexedModuleDescriptorList;
+
+static IndexedModuleDescriptorList
 getModuleDescriptors(const DbiModuleList &ML) {
-  std::vector<std::pair<uint32_t, DbiModuleDescriptor>> List;
+  IndexedModuleDescriptorList List;
   List.reserve(ML.getModuleCount());
   for (uint32_t I = 0; I < ML.getModuleCount(); ++I)
     List.emplace_back(I, ML.getModuleDescriptor(I));
   return List;
 }
 
-static void
-diffOneModule(DiffPrinter &D,
-              const std::pair<uint32_t, DbiModuleDescriptor> Item,
-              std::vector<std::pair<uint32_t, DbiModuleDescriptor>> &Other,
-              bool ItemIsRight) {
+static IndexedModuleDescriptorList::iterator
+findOverrideEquivalentModule(uint32_t Modi,
+                             IndexedModuleDescriptorList &OtherList) {
+  auto &EqMap = opts::diff::Equivalences;
+
+  auto Iter = EqMap.find(Modi);
+  if (Iter == EqMap.end())
+    return OtherList.end();
+
+  uint32_t EqValue = Iter->second;
+
+  return llvm::find_if(OtherList,
+                       [EqValue](const IndexedModuleDescriptor &Desc) {
+                         return Desc.first == EqValue;
+                       });
+}
+
+static IndexedModuleDescriptorList::iterator
+findEquivalentModule(const IndexedModuleDescriptor &Item,
+                     IndexedModuleDescriptorList &OtherList, bool ItemIsRight) {
+
+  if (!ItemIsRight) {
+    uint32_t Modi = Item.first;
+    auto OverrideIter = findOverrideEquivalentModule(Modi, OtherList);
+    if (OverrideIter != OtherList.end())
+      return OverrideIter;
+  }
+
+  BinaryPathProvider PathProvider(28);
+
+  auto Iter = OtherList.begin();
+  auto End = OtherList.end();
+  for (; Iter != End; ++Iter) {
+    const IndexedModuleDescriptor *Left = &Item;
+    const IndexedModuleDescriptor *Right = &*Iter;
+    if (ItemIsRight)
+      std::swap(Left, Right);
+    DiffResult Result = PathProvider.compare(Left->second.getModuleName(),
+                                             Right->second.getModuleName());
+    if (Result == DiffResult::EQUIVALENT || Result == DiffResult::IDENTICAL)
+      return Iter;
+  }
+  return OtherList.end();
+}
+
+static void diffOneModule(DiffPrinter &D, const IndexedModuleDescriptor &Item,
+                          IndexedModuleDescriptorList &Other,
+                          bool ItemIsRight) {
   StreamPurposeProvider HeaderProvider(70);
   std::pair<StreamPurpose, std::string> Header;
   Header.first = StreamPurpose::ModuleStream;
@@ -447,23 +493,14 @@ diffOneModule(DiffPrinter &D,
 
   const auto *L = &Item;
 
-  BinaryPathProvider PathProvider(28);
-  auto Iter = llvm::find_if(
-      Other, [&PathProvider, ItemIsRight,
-              L](const std::pair<uint32_t, DbiModuleDescriptor> &Other) {
-        const auto *Left = L;
-        const auto *Right = &Other;
-        if (ItemIsRight)
-          std::swap(Left, Right);
-        DiffResult Result = PathProvider.compare(Left->second.getModuleName(),
-                                                 Right->second.getModuleName());
-        return Result == DiffResult::EQUIVALENT ||
-               Result == DiffResult::IDENTICAL;
-      });
+  auto Iter = findEquivalentModule(Item, Other, ItemIsRight);
   if (Iter == Other.end()) {
     // We didn't find this module at all on the other side.  Just print one row
     // and continue.
-    D.print<ModiProvider>("- Modi", Item.first, None);
+    if (ItemIsRight)
+      D.print<ModiProvider>("- Modi", None, Item.first);
+    else
+      D.print<ModiProvider>("- Modi", Item.first, None);
     return;
   }
 
@@ -472,6 +509,7 @@ diffOneModule(DiffPrinter &D,
   if (ItemIsRight)
     std::swap(L, R);
 
+  BinaryPathProvider PathProvider(28);
   D.print<ModiProvider>("- Modi", L->first, R->first);
   D.print<BinaryPathProvider>("- Obj File Name", L->second.getObjFileName(),
                               R->second.getObjFileName(), PathProvider);

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=309983&r1=309982&r2=309983&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Thu Aug  3 13:30:09 2017
@@ -293,6 +293,13 @@ cl::opt<bool>
                       cl::desc("Print a column with the result status"),
                       cl::Optional, cl::sub(DiffSubcommand));
 
+cl::list<std::string>
+    RawModiEquivalences("modi-equivalence", cl::ZeroOrMore,
+                        cl::value_desc("left,right"),
+                        cl::desc("Modules with the specified indices will be "
+                                 "treated as referring to the same module"),
+                        cl::sub(DiffSubcommand));
+
 cl::opt<std::string> LeftRoot(
     "left-bin-root", cl::Optional,
     cl::desc("Treats the specified path as the root of the tree containing "
@@ -310,6 +317,8 @@ cl::opt<std::string> Left(cl::Positional
                           cl::sub(DiffSubcommand));
 cl::opt<std::string> Right(cl::Positional, cl::desc("<right>"),
                            cl::sub(DiffSubcommand));
+
+llvm::DenseMap<uint32_t, uint32_t> Equivalences;
 }
 
 cl::OptionCategory FileOptions("Module & File Options");
@@ -1175,6 +1184,19 @@ int main(int argc_, const char *argv_[])
     std::for_each(opts::bytes::InputFilenames.begin(),
                   opts::bytes::InputFilenames.end(), dumpBytes);
   } else if (opts::DiffSubcommand) {
+    for (StringRef S : opts::diff::RawModiEquivalences) {
+      StringRef Left;
+      StringRef Right;
+      std::tie(Left, Right) = S.split(',');
+      uint32_t X, Y;
+      if (!to_integer(Left, X) || !to_integer(Right, Y)) {
+        errs() << formatv("invalid value {0} specified for modi equivalence\n",
+                          S);
+        exit(1);
+      }
+      opts::diff::Equivalences[X] = Y;
+    }
+
     diff(opts::diff::Left, opts::diff::Right);
   } else if (opts::MergeSubcommand) {
     if (opts::merge::InputFilenames.size() < 2) {

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h?rev=309983&r1=309982&r2=309983&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Thu Aug  3 13:30:09 2017
@@ -10,6 +10,7 @@
 #ifndef LLVM_TOOLS_LLVMPDBDUMP_LLVMPDBDUMP_H
 #define LLVM_TOOLS_LLVMPDBDUMP_LLVMPDBDUMP_H
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
@@ -177,6 +178,7 @@ extern llvm::cl::opt<bool> DumpModuleSym
 namespace diff {
 extern llvm::cl::opt<bool> PrintValueColumns;
 extern llvm::cl::opt<bool> PrintResultColumn;
+extern llvm::DenseMap<uint32_t, uint32_t> Equivalences;
 extern llvm::cl::opt<std::string> LeftRoot;
 extern llvm::cl::opt<std::string> RightRoot;
 } // namespace diff




More information about the llvm-commits mailing list