[clang-tools-extra] Add flags to dump IR to a file before and after LLVM passes (PR #65179)

Nuri Amari via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 6 06:12:20 PDT 2023


https://github.com/NuriAmari updated https://github.com/llvm/llvm-project/pull/65179:

>From 5d395c85b84e5a554df4b092014d38123e666c6c Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Tue, 29 Aug 2023 10:10:57 -0700
Subject: [PATCH 1/4] Add flags to dump IR to a file before and after LLVM
 passes

Summary:

LLVM offers -print-after and -print-before flags that allow you
to print IR to stderr before and after any pass you want. This can
be useful for debugging LLVM optimization issue, but is far too
noisy for large builds.

This patch adds analogous options -dump-after and -dump-before that
dump the IR to appropriately named files. In addition, it also
introduces flags -dump-after-all, -dump-before-all and -ir-dump-directory
to control where the files are written to.

Test Plan:

Included LIT tests:
```
ninja check-llvm
```
---
 llvm/include/llvm/IR/PrintPasses.h            |  21 +++
 .../llvm/Passes/StandardInstrumentations.h    |  57 ++++++
 llvm/lib/IR/PrintPasses.cpp                   |  54 ++++++
 llvm/lib/Passes/PassBuilder.cpp               |   3 +-
 llvm/lib/Passes/StandardInstrumentations.cpp  | 178 ++++++++++++++++++
 .../Other/dump-before-after-file-contents     |  76 ++++++++
 llvm/test/Other/dump-before-after-filenames   |  71 +++++++
 .../Other/dump-before-after-multiple-modules  |  36 ++++
 llvm/test/Other/lit.local.cfg                 |   1 +
 9 files changed, 496 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Other/dump-before-after-file-contents
 create mode 100644 llvm/test/Other/dump-before-after-filenames
 create mode 100644 llvm/test/Other/dump-before-after-multiple-modules
 create mode 100644 llvm/test/Other/lit.local.cfg

diff --git a/llvm/include/llvm/IR/PrintPasses.h b/llvm/include/llvm/IR/PrintPasses.h
index 95b97e76c867cb..b2a9017521c6a9 100644
--- a/llvm/include/llvm/IR/PrintPasses.h
+++ b/llvm/include/llvm/IR/PrintPasses.h
@@ -48,6 +48,27 @@ bool shouldPrintAfterAll();
 std::vector<std::string> printBeforePasses();
 std::vector<std::string> printAfterPasses();
 
+// Returns true if dumping IR to a file before/after some pass is enabled
+// wether all passes or a specific pass.
+bool shouldDumpBeforeSomePass();
+bool shouldDumpAfterSomePass();
+
+// Returns true if we should dump IR to a file before/after a specific pass. The
+// argument should be the pass ID, e.g. "instcombine"
+bool shouldDumpBeforePass(StringRef PassID);
+bool shouldDumpAfterPass(StringRef PassID);
+
+// Returns true if we should dump IR to a file before/after all passes.
+bool shouldDumpBeforeAll();
+bool shouldDumpAfterAll();
+
+// The list of passes to dump IR to a file before/after, if we only want
+// to print before/after specific passes.
+std::vector<std::string> dumpBeforePasses();
+std::vector<std::string> dumpAfterPasses();
+
+StringRef irInstrumentationDumpDirectory();
+
 // Returns true if we should always print the entire module.
 bool forcePrintModuleIR();
 
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index 331130c6b22d99..4068a68aa956fd 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -69,6 +69,62 @@ class PrintIRInstrumentation {
   unsigned CurrentPassNumber = 0;
 };
 
+class DumpIRInstrumentation {
+public:
+  void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+  void dumpBeforePass(StringRef PassID, Any IR);
+  void dumpAfterPass(StringRef PassID, Any IR);
+
+  bool shouldDumpBeforePass(StringRef PassID);
+  bool shouldDumpAfterPass(StringRef PassID);
+
+  PassInstrumentationCallbacks *PIC;
+
+  // The module currently being processed in the pipeline.
+  Module const *CurrentModule = nullptr;
+
+  void pushPass(StringRef PassID, Any IR);
+  void popPass(StringRef PassID);
+
+  SmallString<16> InstrumentationDumpDirectory;
+  StringRef fetchInstrumentationDumpDirectory();
+
+  SmallString<16> fetchCurrentInstrumentationDumpFile(StringRef Suffix);
+
+  // A table to store how many times a given pass has run at the current "nested
+  // level"
+  using PassRunsFrequencyTableT = DenseMap<StringRef, unsigned>;
+  // A stack each frame of which (aside from the very first) represents a pass
+  // being run on some unit of IR. The larger, the stack grows, the smaller the
+  // unit of IR. For example, we would first push a module pass, then for each
+  // function pass in that module pass, we would push a frame and so on. This
+  // information is used to craft the output path for this logging.
+  //
+  // Each frame contains a map to track how many times a given subpass runs. For
+  // example, to keep track of how many times a function pass Foo runs within a
+  // module pass Bar. The first frame of the stack represents the module being
+  // processed rather than any particular pass. This is to create a frequency
+  // table to track module level pass run counts without having to special case
+  // that logic.
+  //
+  // When a change in the module being processed is detected, this first frame
+  // is updated accordingly.
+
+  struct PipelineStateStackFrame {
+    StringRef PassID;
+    PassRunsFrequencyTableT FreqTable;
+    unsigned int PassCount;
+
+    PipelineStateStackFrame(StringRef PassID) : PassID{PassID}, PassCount{0} {}
+  };
+
+  using PipelineStateStackT = SmallVector<PipelineStateStackFrame>;
+
+  PipelineStateStackT PipelineStateStack;
+};
+
 class OptNoneInstrumentation {
 public:
   OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
@@ -555,6 +611,7 @@ class PrintCrashIRInstrumentation {
 /// instrumentations and manages their state (if any).
 class StandardInstrumentations {
   PrintIRInstrumentation PrintIR;
+  DumpIRInstrumentation DumpIR;
   PrintPassInstrumentation PrintPass;
   TimePassesHandler TimePasses;
   TimeProfilingPassesHandler TimeProfilingPasses;
diff --git a/llvm/lib/IR/PrintPasses.cpp b/llvm/lib/IR/PrintPasses.cpp
index e2ef20bb81ba7d..bec315cb90e7d6 100644
--- a/llvm/lib/IR/PrintPasses.cpp
+++ b/llvm/lib/IR/PrintPasses.cpp
@@ -33,6 +33,31 @@ static cl::opt<bool> PrintAfterAll("print-after-all",
                                    llvm::cl::desc("Print IR after each pass"),
                                    cl::init(false), cl::Hidden);
 
+static cl::list<std::string>
+    DumpBefore("dump-before",
+               llvm::cl::desc("Dump IR to a file before specified passes"),
+               cl::CommaSeparated, cl::Hidden);
+
+static cl::list<std::string>
+    DumpAfter("dump-after",
+              llvm::cl::desc("Dump IR to a file after specified passes"),
+              cl::CommaSeparated, cl::Hidden);
+
+static cl::opt<bool>
+    DumpBeforeAll("dump-before-all",
+                  llvm::cl::desc("Dump IR to a file before each pass"),
+                  cl::init(false), cl::Hidden);
+static cl::opt<bool>
+    DumpAfterAll("dump-after-all",
+                 llvm::cl::desc("Dump IR to a file after each pass"),
+                 cl::init(false), cl::Hidden);
+
+static cl::opt<std::string> DumpDirectory(
+    "ir-dump-directory",
+    llvm::cl::desc("A directory to dump IR log files into before and after "
+                   "passes as specified using -dump-before / -dump-after"),
+    cl::init(""), cl::Hidden, cl::value_desc("filename"));
+
 // Print out the IR after passes, similar to -print-after-all except that it
 // only prints the IR after passes that change the IR. Those passes that do not
 // make changes to the IR are reported as not making any changes. In addition,
@@ -139,6 +164,35 @@ std::vector<std::string> llvm::printAfterPasses() {
   return std::vector<std::string>(PrintAfter);
 }
 
+bool llvm::shouldDumpBeforeSomePass() {
+  return DumpBeforeAll || !DumpBefore.empty();
+}
+
+bool llvm::shouldDumpAfterSomePass() {
+  return DumpAfterAll || !DumpAfter.empty();
+}
+
+bool llvm::shouldDumpBeforeAll() { return DumpBeforeAll; }
+
+bool llvm::shouldDumpAfterAll() { return DumpAfterAll; }
+
+bool llvm::shouldDumpBeforePass(StringRef PassID) {
+  return DumpBeforeAll || llvm::is_contained(DumpBefore, PassID);
+}
+
+bool llvm::shouldDumpAfterPass(StringRef PassID) {
+  return DumpAfterAll || llvm::is_contained(DumpAfter, PassID);
+}
+std::vector<std::string> llvm::dumpBeforePasses() {
+  return std::vector<std::string>(DumpBefore);
+}
+
+std::vector<std::string> llvm::dumpAfterPasses() {
+  return std::vector<std::string>(DumpAfter);
+}
+
+StringRef llvm::irInstrumentationDumpDirectory() { return DumpDirectory; }
+
 bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
 
 bool llvm::isPassInPrintList(StringRef PassName) {
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 1fdeb13706ca6a..c402399779683c 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -386,7 +386,8 @@ AnalysisKey NoOpLoopAnalysis::Key;
 /// We currently only use this for --print-before/after.
 bool shouldPopulateClassToPassNames() {
   return PrintPipelinePasses || !printBeforePasses().empty() ||
-         !printAfterPasses().empty() || !isFilterPassesEmpty();
+         !printAfterPasses().empty() || !isFilterPassesEmpty() ||
+         !dumpAfterPasses().empty() || !dumpBeforePasses().empty();
 }
 
 // A pass for testing -print-on-crash.
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index ce14489ba43474..48e85b97dbbb28 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -33,6 +33,7 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/GraphWriter.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/Signals.h"
@@ -830,6 +831,182 @@ void PrintIRInstrumentation::registerCallbacks(
   }
 }
 
+void DumpIRInstrumentation::registerCallbacks(
+    PassInstrumentationCallbacks &PIC) {
+
+  if (!(shouldDumpBeforeSomePass() || shouldDumpAfterSomePass()))
+    return;
+
+  this->PIC = &PIC;
+
+  PIC.registerBeforeNonSkippedPassCallback(
+      [this](StringRef P, Any IR) { this->pushPass(P, IR); });
+
+  if (shouldDumpBeforeSomePass())
+    PIC.registerBeforeNonSkippedPassCallback(
+        [this](StringRef P, Any IR) { this->dumpBeforePass(P, IR); });
+
+  if (shouldDumpAfterSomePass()) {
+    PIC.registerAfterPassCallback(
+        [this](StringRef P, Any IR, const PreservedAnalyses &) {
+          this->dumpAfterPass(P, IR);
+        });
+  }
+
+  // It is important the the "popPass" callback fires after the dumpAfterPass
+  // callback
+  PIC.registerAfterPassCallback(
+      [this](StringRef P, Any IR, const PreservedAnalyses &) {
+        this->popPass(P);
+      });
+}
+
+void DumpIRInstrumentation::dumpBeforePass(StringRef PassID, Any IR) {
+  if (isIgnored(PassID))
+    return;
+
+  if (!shouldDumpBeforePass(PassID)) {
+    return;
+  }
+
+  SmallString<16> OutputPath =
+      fetchCurrentInstrumentationDumpFile("-before.ll");
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(OutputPath, EC, llvm::sys::fs::CD_CreateAlways);
+  if (EC)
+    report_fatal_error(Twine("Failed to open ") + OutputPath +
+                       " to support dump-before: " + EC.message());
+
+  OS << "*** IR Dump Before " << PassID << " on " << getIRName(IR) << " ***\n";
+  unwrapAndPrint(OS, IR);
+}
+
+void DumpIRInstrumentation::dumpAfterPass(StringRef PassID, Any IR) {
+  if (isIgnored(PassID))
+    return;
+
+  if (!shouldDumpAfterPass(PassID))
+    return;
+
+  SmallString<16> OutputPath = fetchCurrentInstrumentationDumpFile("-after.ll");
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(OutputPath, EC, llvm::sys::fs::CD_CreateAlways);
+  if (EC)
+    report_fatal_error(Twine("Failed to open ") + OutputPath +
+                       " to support -dump-after: " + EC.message());
+
+  OS << "*** IR Dump After " << PassID << " on " << getIRName(IR) << " ***\n";
+  unwrapAndPrint(OS, IR);
+}
+
+bool DumpIRInstrumentation::shouldDumpBeforePass(StringRef PassID) {
+  if (shouldDumpBeforeAll())
+    return true;
+
+  StringRef PassName = PIC->getPassNameForClassName(PassID);
+  return is_contained(dumpBeforePasses(), PassName);
+}
+
+bool DumpIRInstrumentation::shouldDumpAfterPass(StringRef PassID) {
+  if (shouldDumpAfterAll())
+    return true;
+
+  StringRef PassName = PIC->getPassNameForClassName(PassID);
+  return is_contained(dumpAfterPasses(), PassName);
+}
+
+void DumpIRInstrumentation::pushPass(StringRef PassID, Any IR) {
+  const Module *M = unwrapModule(IR);
+  if (CurrentModule != M) {
+    // If currentModule is nullptr, or is not equal to M, we are starting to
+    // process a new module.
+
+    // The first frame of the stack should maintain a frequency table
+    // for module level passes.
+    PipelineStateStack.clear();
+    PipelineStateStack.push_back(PipelineStateStackFrame(M->getName()));
+
+    CurrentModule = M;
+  }
+
+  PassRunsFrequencyTableT &FreqTable = PipelineStateStack.back().FreqTable;
+  if (FreqTable.find(PassID) == FreqTable.end())
+    FreqTable[PassID] = 0;
+
+  PipelineStateStack.push_back(PipelineStateStackFrame(PassID));
+}
+
+void DumpIRInstrumentation::popPass(StringRef PassID) {
+  PipelineStateStack.pop_back();
+  assert(!PipelineStateStack.empty());
+
+  PassRunsFrequencyTableT &FreqTable = PipelineStateStack.back().FreqTable;
+  assert(FreqTable.find(PassID) != FreqTable.end());
+  FreqTable[PassID]++;
+  PipelineStateStack.back().PassCount++;
+}
+
+StringRef DumpIRInstrumentation::fetchInstrumentationDumpDirectory() {
+  if (!InstrumentationDumpDirectory.empty())
+    return InstrumentationDumpDirectory;
+
+  if (!irInstrumentationDumpDirectory().empty())
+    return irInstrumentationDumpDirectory();
+
+  std::error_code EC =
+      sys::fs::createUniqueDirectory("dumped-ir", InstrumentationDumpDirectory);
+  if (EC)
+    report_fatal_error(
+        Twine("Failed to create unique directory for IR dumping: ") +
+        EC.message());
+
+  return InstrumentationDumpDirectory;
+}
+
+SmallString<16>
+DumpIRInstrumentation::fetchCurrentInstrumentationDumpFile(StringRef Suffix) {
+  SmallString<16> OutputPath;
+  sys::path::append(OutputPath, fetchInstrumentationDumpDirectory());
+  assert(CurrentModule);
+  sys::path::append(OutputPath, CurrentModule->getName());
+  auto *StateStackIt = PipelineStateStack.begin();
+  // Skip over the first frame in the stack which represents the module being
+  // processed
+  for (++StateStackIt; StateStackIt != PipelineStateStack.end();
+       ++StateStackIt) {
+    SmallString<8> PathComponentName;
+    // Check the previous frame's pass count to see how many passes of
+    // any kind have run on this "nesting level".
+    unsigned int PassCount = (StateStackIt - 1)->PassCount;
+    PathComponentName += std::to_string(PassCount);
+    PathComponentName += ".";
+    // Check the previous frame's frequency table to see how many times
+    // this pass has run at this "nesting level".
+    PassRunsFrequencyTableT &FreqTable = (StateStackIt - 1)->FreqTable;
+    StringRef FramePassID = StateStackIt->PassID;
+    PathComponentName += FramePassID;
+    PathComponentName += ".";
+    assert(FreqTable.find(FramePassID) != FreqTable.end() &&
+           "DumpIRInstrumentation pass frequency table missing entry");
+    // Make sure the uint is converted to a character and not interpretted as
+    // one
+    PathComponentName += std::to_string(FreqTable[FramePassID]);
+    sys::path::append(OutputPath, PathComponentName);
+  }
+  OutputPath += Suffix;
+
+  // Make sure the directory we wish to write our log file into exists.
+  StringRef ParentDirectory = sys::path::parent_path(OutputPath);
+  if (!ParentDirectory.empty()) {
+    if (auto EC = llvm::sys::fs::create_directories(ParentDirectory)) {
+      report_fatal_error(Twine("Failed to create directory '") +
+                         ParentDirectory + "' :" + EC.message());
+    }
+  }
+
+  return OutputPath;
+}
+
 void OptNoneInstrumentation::registerCallbacks(
     PassInstrumentationCallbacks &PIC) {
   PIC.registerShouldRunOptionalPassCallback(
@@ -2288,6 +2465,7 @@ void PrintCrashIRInstrumentation::registerCallbacks(
 void StandardInstrumentations::registerCallbacks(
     PassInstrumentationCallbacks &PIC, ModuleAnalysisManager *MAM) {
   PrintIR.registerCallbacks(PIC);
+  DumpIR.registerCallbacks(PIC);
   PrintPass.registerCallbacks(PIC);
   TimePasses.registerCallbacks(PIC);
   OptNone.registerCallbacks(PIC);
diff --git a/llvm/test/Other/dump-before-after-file-contents b/llvm/test/Other/dump-before-after-file-contents
new file mode 100644
index 00000000000000..6181ab90371e71
--- /dev/null
+++ b/llvm/test/Other/dump-before-after-file-contents
@@ -0,0 +1,76 @@
+; This first run is intended to test that the -dump* write an appropriate amount of IR to the file for different types of passes
+
+; RUN: opt %s -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module,no-op-function,no-op-loop -dump-before=no-op-module,no-op-function,no-op-loop
+
+; RUN: cat '%t/logs/%s/0.NoOpModulePass.0-before.ll' | FileCheck %s --check-prefix=MODULE-PASS --check-prefix=MODULE-PASS-BEFORE -DSOURCE_FILE_NAME=%s
+; RUN: cat '%t/logs/%s/0.NoOpModulePass.0-after.ll' | FileCheck %s --check-prefix=MODULE-PASS --check-prefix=MODULE-PASS-AFTER -DSOURCE_FILE_NAME=%s
+
+; MODULE-PASS-BEFORE: *** IR Dump Before NoOpModulePass on [module] ***
+; MODULE-PASS-AFTER: *** IR Dump After NoOpModulePass on [module] ***
+; MODULE-PASS: ; ModuleID = '[[SOURCE_FILE_NAME]]'
+; MODULE-PASS: source_filename = "[[SOURCE_FILE_NAME]]"
+; MODULE-PASS: define void @foo() {
+; MODULE-PASS:   ret void
+; MODULE-PASS: }
+; MODULE-PASS: define void @bar() {
+; MODULE-PASS: entry:
+; MODULE-PASS:   br label %loop
+; MODULE-PASS: loop:
+; MODULE-PASS:   br label %loop
+; MODULE-PASS: }
+
+; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-FOO --check-prefix=FUNCTION-PASS-FOO-BEFORE
+; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-FOO --check-prefix=FUNCTION-PASS-FOO-AFTER
+
+; FUNCTION-PASS-FOO-BEFORE: *** IR Dump Before NoOpFunctionPass on foo ***
+; FUNCTION-PASS-FOO-AFTER: *** IR Dump After NoOpFunctionPass on foo ***
+; FUNCTION-PASS-FOO: define void @foo() {
+; FUNCTION-PASS-FOO:   ret void
+; FUNCTION-PASS-FOO: }
+
+; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-before.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-BAR --check-prefix=FUNCTION-PASS-BAR-BEFORE
+; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-after.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-BAR --check-prefix=FUNCTION-PASS-BAR-AFTER
+
+; FUNCTION-PASS-BAR-BEFORE: *** IR Dump Before NoOpFunctionPass on bar ***
+; FUNCTION-PASS-BAR-AFTER:  *** IR Dump After NoOpFunctionPass on bar ***
+; FUNCTION-PASS-BAR: define void @bar() {
+; FUNCTION-PASS-BAR: entry:
+; FUNCTION-PASS-BAR:     br label %loop
+; FUNCTION-PASS-BAR: loop:
+; FUNCTION-PASS-BAR:     br label %loop
+; FUNCTION-PASS-BAR: }
+
+; RUN: cat '%t/logs/%s/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll' | FileCheck %s --check-prefix=LOOP-PASS --check-prefix=LOOP-PASS-BEFORE
+; RUN: cat '%t/logs/%s/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll' | FileCheck %s --check-prefix=LOOP-PASS --check-prefix=LOOP-PASS-AFTER
+
+; LOOP-PASS-BEFORE: *** IR Dump Before NoOpLoopPass on loop ***
+; LOOP-PASS-AFTER:  *** IR Dump After NoOpLoopPass on loop ***
+; LOOP-PASS: entry:
+; LOOP-PASS:   br label %loop
+; LOOP-PASS: ; Loop:
+; LOOP-PASS: loop:
+; LOOP-PASS:   br label %loop
+
+; This test verifies that dumping before and after really does dump before and after
+
+; RUN: rm -rf %t/logs
+; RUN: opt -S %s -passes=globaldce -ir-dump-directory %t/logs -dump-before=globaldce -dump-after=globaldce > %t/output.ll
+; Just compare the last few lines of all files to remove comments and header inserted by the logging
+; RUN: tail -n 11 %s > %t/normalized-input.ll
+; RUN: tail -n 11 %t/output.ll > %t/normalized-output.ll
+; RUN: tail -n 11 '%t/logs/%s/0.GlobalDCEPass.0-before.ll' > %t/normalized-before.ll
+; RUN: tail -n 11 '%t/logs/%s/0.GlobalDCEPass.0-after.ll' > %t/normalized-after.ll
+; RUN: diff %t/normalized-input.ll %t/normalized-before.ll
+; RUN: diff %t/normalized-output.ll %t/normalized-after.ll
+
+define void @foo() {
+  ret void
+}
+
+define void @bar() {
+entry:
+  br label %loop
+
+loop:                                             ; preds = %loop, %entry
+  br label %loop
+}
diff --git a/llvm/test/Other/dump-before-after-filenames b/llvm/test/Other/dump-before-after-filenames
new file mode 100644
index 00000000000000..0236baba733751
--- /dev/null
+++ b/llvm/test/Other/dump-before-after-filenames
@@ -0,0 +1,71 @@
+; RUN: mkdir -p %t/logs
+; RUN: rm -rf %t/logs
+
+; Basic dump before and after a single module pass
+; RUN: opt %s -disable-output -passes='no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module -dump-before=no-op-module
+; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=SINGLE-RUN -DSOURCE_FILE_NAME=%s
+; SINGLE-RUN-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
+; SINGLE-RUN-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
+; RUN: rm -rf %t/logs
+
+; Dump before and after multiple runs of the same module pass
+; RUN: opt %s -disable-output -passes='no-op-module,no-op-module,no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module -dump-before=no-op-module
+; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=MULTIPLE-RUNS -DSOURCE_FILE_NAME=%s
+; MULTIPLE-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
+; MULTIPLE-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
+; MULTIPLE-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.NoOpModulePass.1-before.ll
+; MULTIPLE-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.NoOpModulePass.1-after.ll
+; MULTIPLE-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.NoOpModulePass.2-before.ll
+; MULTIPLE-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.NoOpModulePass.2-after.ll
+; RUN: rm -rf %t/logs
+
+; Dump before and after multiple passes, some nested
+; RUN: opt %s -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module,no-op-function,no-op-loop -dump-before=no-op-module,no-op-function,no-op-loop
+; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=MULTIPLE-NESTED-RUNS -DSOURCE_FILE_NAME=%s
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-after.ll
+; RUN: rm -rf %t/logs
+
+; Dump before and after all passes, some nested
+; RUN: opt %s -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after-all -dump-before-all
+; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=MULTIPLE-NESTED-RUNS-DUMP-ALL -DSOURCE_FILE_NAME=%s
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.l
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/4.VerifierPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/4.VerifierPass.0-after.ll
+; RUN: rm -rf %t/logs
+
+define void @foo() {
+    ret void
+}
+
+define void @bar() {
+entry:
+    br label %loop
+loop:
+    br label %loop
+}
diff --git a/llvm/test/Other/dump-before-after-multiple-modules b/llvm/test/Other/dump-before-after-multiple-modules
new file mode 100644
index 00000000000000..72aeddecf952ae
--- /dev/null
+++ b/llvm/test/Other/dump-before-after-multiple-modules
@@ -0,0 +1,36 @@
+; RUN: mkdir -p %t/logs
+; RUN: rm -rf %t/logs
+
+; RUN: split-file %s %t
+; RUN: opt %t/module-foo -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module,no-op-function,no-op-loop -dump-before=no-op-module,no-op-function,no-op-loop
+; RUN: opt %t/module-bar -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module,no-op-function,no-op-loop -dump-before=no-op-module,no-op-function,no-op-loop
+; RUN: find %t/logs -type f -print | FileCheck %s
+; CHECK-DAG: module-foo/0.NoOpModulePass.0-before.ll
+; CHECK-DAG: module-foo/0.NoOpModulePass.0-after.ll
+; CHECK-DAG: module-foo/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
+; CHECK-DAG: module-foo/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
+; CHECK-DAG: module-foo/3.NoOpModulePass.1-before.ll
+; CHECK-DAG: module-foo/3.NoOpModulePass.1-after.ll
+; CHECK-DAG: module-bar/0.NoOpModulePass.0-before.ll
+; CHECK-DAG: module-bar/0.NoOpModulePass.0-after.ll
+; CHECK-DAG: module-bar/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
+; CHECK-DAG: module-bar/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
+; CHECK-DAG: module-bar/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll
+; CHECK-DAG: module-bar/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
+; CHECK-DAG: module-bar/3.NoOpModulePass.1-before.ll
+; CHECK-DAG: module-bar/3.NoOpModulePass.1-after.ll
+
+;--- module-foo
+
+define void @foo() {
+    ret void
+}
+
+;--- module-bar
+
+define void @bar() {
+entry:
+    br label %loop
+loop:
+    br label %loop
+}
diff --git a/llvm/test/Other/lit.local.cfg b/llvm/test/Other/lit.local.cfg
new file mode 100644
index 00000000000000..ae84c64a29c5ce
--- /dev/null
+++ b/llvm/test/Other/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['', '.ll']

>From ec1052b5473d76c5e4cad9b338b607f95ec2accd Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Sat, 2 Sep 2023 16:15:15 -0700
Subject: [PATCH 2/4] Fix tests to account for platform dependent output paths

The name of a particular pass is determined automatically
using the name of the type that implements in. This in turn
is determined using __PRETTY_FUNCTION__ which is not defined
in the standard and implementation specific.

This means the output paths differ slightly depending on the
platform.

To adjust tests for this:

- Add regexes that relax the requirements on output paths.
- Use find to find output paths without specifying
- Remove a test that was intended to test multiple modules being
  processing by a single pipeline, but was not really testing that

PR Feedback is also addressed.
---
 .../llvm/Passes/StandardInstrumentations.h    |  6 +-
 llvm/lib/Passes/StandardInstrumentations.cpp  | 12 ++--
 .../Other/dump-before-after-file-contents     | 56 +++++++------------
 llvm/test/Other/dump-before-after-filenames   | 40 ++++++-------
 .../Other/dump-before-after-multiple-modules  | 36 ------------
 5 files changed, 49 insertions(+), 101 deletions(-)
 delete mode 100644 llvm/test/Other/dump-before-after-multiple-modules

diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index 4068a68aa956fd..3d99772e87e991 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -77,8 +77,8 @@ class DumpIRInstrumentation {
   void dumpBeforePass(StringRef PassID, Any IR);
   void dumpAfterPass(StringRef PassID, Any IR);
 
-  bool shouldDumpBeforePass(StringRef PassID);
-  bool shouldDumpAfterPass(StringRef PassID);
+  bool shouldDumpBeforePass(StringRef PassID) const;
+  bool shouldDumpAfterPass(StringRef PassID) const;
 
   PassInstrumentationCallbacks *PIC;
 
@@ -95,7 +95,7 @@ class DumpIRInstrumentation {
 
   // A table to store how many times a given pass has run at the current "nested
   // level"
-  using PassRunsFrequencyTableT = DenseMap<StringRef, unsigned>;
+  using PassRunsFrequencyTableT = StringMap<unsigned>;
   // A stack each frame of which (aside from the very first) represents a pass
   // being run on some unit of IR. The larger, the stack grows, the smaller the
   // unit of IR. For example, we would first push a module pass, then for each
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 48e85b97dbbb28..d32071e26f867c 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -899,7 +899,7 @@ void DumpIRInstrumentation::dumpAfterPass(StringRef PassID, Any IR) {
   unwrapAndPrint(OS, IR);
 }
 
-bool DumpIRInstrumentation::shouldDumpBeforePass(StringRef PassID) {
+bool DumpIRInstrumentation::shouldDumpBeforePass(StringRef PassID) const {
   if (shouldDumpBeforeAll())
     return true;
 
@@ -907,7 +907,7 @@ bool DumpIRInstrumentation::shouldDumpBeforePass(StringRef PassID) {
   return is_contained(dumpBeforePasses(), PassName);
 }
 
-bool DumpIRInstrumentation::shouldDumpAfterPass(StringRef PassID) {
+bool DumpIRInstrumentation::shouldDumpAfterPass(StringRef PassID) const {
   if (shouldDumpAfterAll())
     return true;
 
@@ -930,7 +930,7 @@ void DumpIRInstrumentation::pushPass(StringRef PassID, Any IR) {
   }
 
   PassRunsFrequencyTableT &FreqTable = PipelineStateStack.back().FreqTable;
-  if (FreqTable.find(PassID) == FreqTable.end())
+  if (!FreqTable.count(PassID))
     FreqTable[PassID] = 0;
 
   PipelineStateStack.push_back(PipelineStateStackFrame(PassID));
@@ -997,12 +997,10 @@ DumpIRInstrumentation::fetchCurrentInstrumentationDumpFile(StringRef Suffix) {
 
   // Make sure the directory we wish to write our log file into exists.
   StringRef ParentDirectory = sys::path::parent_path(OutputPath);
-  if (!ParentDirectory.empty()) {
-    if (auto EC = llvm::sys::fs::create_directories(ParentDirectory)) {
+  if (!ParentDirectory.empty())
+    if (auto EC = llvm::sys::fs::create_directories(ParentDirectory))
       report_fatal_error(Twine("Failed to create directory '") +
                          ParentDirectory + "' :" + EC.message());
-    }
-  }
 
   return OutputPath;
 }
diff --git a/llvm/test/Other/dump-before-after-file-contents b/llvm/test/Other/dump-before-after-file-contents
index 6181ab90371e71..877a4611c68191 100644
--- a/llvm/test/Other/dump-before-after-file-contents
+++ b/llvm/test/Other/dump-before-after-file-contents
@@ -1,17 +1,16 @@
 ; This first run is intended to test that the -dump* write an appropriate amount of IR to the file for different types of passes
 
+; RUN: mkdir -p %t/logs
+; RUN: rm -rf %t/logs
 ; RUN: opt %s -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module,no-op-function,no-op-loop -dump-before=no-op-module,no-op-function,no-op-loop
 
-; RUN: cat '%t/logs/%s/0.NoOpModulePass.0-before.ll' | FileCheck %s --check-prefix=MODULE-PASS --check-prefix=MODULE-PASS-BEFORE -DSOURCE_FILE_NAME=%s
-; RUN: cat '%t/logs/%s/0.NoOpModulePass.0-after.ll' | FileCheck %s --check-prefix=MODULE-PASS --check-prefix=MODULE-PASS-AFTER -DSOURCE_FILE_NAME=%s
-
+; RUN: cat "$(find '%t/logs' -name '0.NoOpModulePass.0-before.ll')" | FileCheck %s --check-prefix=MODULE-PASS --check-prefix=MODULE-PASS-BEFORE -DSOURCE_FILE_NAME=%s
+; RUN: cat "$(find '%t/logs' -name '0.NoOpModulePass.0-after.ll')" | FileCheck %s --check-prefix=MODULE-PASS --check-prefix=MODULE-PASS-AFTER -DSOURCE_FILE_NAME=%s
+;
 ; MODULE-PASS-BEFORE: *** IR Dump Before NoOpModulePass on [module] ***
 ; MODULE-PASS-AFTER: *** IR Dump After NoOpModulePass on [module] ***
 ; MODULE-PASS: ; ModuleID = '[[SOURCE_FILE_NAME]]'
 ; MODULE-PASS: source_filename = "[[SOURCE_FILE_NAME]]"
-; MODULE-PASS: define void @foo() {
-; MODULE-PASS:   ret void
-; MODULE-PASS: }
 ; MODULE-PASS: define void @bar() {
 ; MODULE-PASS: entry:
 ; MODULE-PASS:   br label %loop
@@ -19,29 +18,20 @@
 ; MODULE-PASS:   br label %loop
 ; MODULE-PASS: }
 
-; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-FOO --check-prefix=FUNCTION-PASS-FOO-BEFORE
-; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-FOO --check-prefix=FUNCTION-PASS-FOO-AFTER
-
-; FUNCTION-PASS-FOO-BEFORE: *** IR Dump Before NoOpFunctionPass on foo ***
-; FUNCTION-PASS-FOO-AFTER: *** IR Dump After NoOpFunctionPass on foo ***
-; FUNCTION-PASS-FOO: define void @foo() {
-; FUNCTION-PASS-FOO:   ret void
-; FUNCTION-PASS-FOO: }
+; RUN: cat "$(find '%t/logs' -name '0.NoOpFunctionPass.0-before.ll')" | FileCheck %s --check-prefix=FUNCTION-PASS --check-prefix=FUNCTION-PASS-BEFORE
+; RUN: cat "$(find '%t/logs' -name '0.NoOpFunctionPass.0-after.ll')" | FileCheck %s --check-prefix=FUNCTION-PASS --check-prefix=FUNCTION-PASS-AFTER
 
-; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-before.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-BAR --check-prefix=FUNCTION-PASS-BAR-BEFORE
-; RUN: cat '%t/logs/%s/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-after.ll' | FileCheck %s --check-prefix=FUNCTION-PASS-BAR --check-prefix=FUNCTION-PASS-BAR-AFTER
+; FUNCTION-PASS-BEFORE: *** IR Dump Before NoOpFunctionPass on bar ***
+; FUNCTION-PASS-AFTER:  *** IR Dump After NoOpFunctionPass on bar ***
+; FUNCTION-PASS: define void @bar() {
+; FUNCTION-PASS: entry:
+; FUNCTION-PASS:     br label %loop
+; FUNCTION-PASS: loop:
+; FUNCTION-PASS:     br label %loop
+; FUNCTION-PASS: }
 
-; FUNCTION-PASS-BAR-BEFORE: *** IR Dump Before NoOpFunctionPass on bar ***
-; FUNCTION-PASS-BAR-AFTER:  *** IR Dump After NoOpFunctionPass on bar ***
-; FUNCTION-PASS-BAR: define void @bar() {
-; FUNCTION-PASS-BAR: entry:
-; FUNCTION-PASS-BAR:     br label %loop
-; FUNCTION-PASS-BAR: loop:
-; FUNCTION-PASS-BAR:     br label %loop
-; FUNCTION-PASS-BAR: }
-
-; RUN: cat '%t/logs/%s/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll' | FileCheck %s --check-prefix=LOOP-PASS --check-prefix=LOOP-PASS-BEFORE
-; RUN: cat '%t/logs/%s/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll' | FileCheck %s --check-prefix=LOOP-PASS --check-prefix=LOOP-PASS-AFTER
+; RUN: cat "$(find '%t/logs' -name '0.NoOpLoopPass.0-before.ll')" | FileCheck %s --check-prefix=LOOP-PASS --check-prefix=LOOP-PASS-BEFORE
+; RUN: cat "$(find '%t/logs' -name '0.NoOpLoopPass.0-after.ll')" | FileCheck %s --check-prefix=LOOP-PASS --check-prefix=LOOP-PASS-AFTER
 
 ; LOOP-PASS-BEFORE: *** IR Dump Before NoOpLoopPass on loop ***
 ; LOOP-PASS-AFTER:  *** IR Dump After NoOpLoopPass on loop ***
@@ -56,17 +46,13 @@
 ; RUN: rm -rf %t/logs
 ; RUN: opt -S %s -passes=globaldce -ir-dump-directory %t/logs -dump-before=globaldce -dump-after=globaldce > %t/output.ll
 ; Just compare the last few lines of all files to remove comments and header inserted by the logging
-; RUN: tail -n 11 %s > %t/normalized-input.ll
-; RUN: tail -n 11 %t/output.ll > %t/normalized-output.ll
-; RUN: tail -n 11 '%t/logs/%s/0.GlobalDCEPass.0-before.ll' > %t/normalized-before.ll
-; RUN: tail -n 11 '%t/logs/%s/0.GlobalDCEPass.0-after.ll' > %t/normalized-after.ll
+; RUN: tail -n 7 %s > %t/normalized-input.ll
+; RUN: tail -n 7 %t/output.ll > %t/normalized-output.ll
+; RUN: tail -n 7 '%t/logs/%s/0.GlobalDCEPass.0-before.ll' > %t/normalized-before.ll
+; RUN: tail -n 7 '%t/logs/%s/0.GlobalDCEPass.0-after.ll' > %t/normalized-after.ll
 ; RUN: diff %t/normalized-input.ll %t/normalized-before.ll
 ; RUN: diff %t/normalized-output.ll %t/normalized-after.ll
 
-define void @foo() {
-  ret void
-}
-
 define void @bar() {
 entry:
   br label %loop
diff --git a/llvm/test/Other/dump-before-after-filenames b/llvm/test/Other/dump-before-after-filenames
index 0236baba733751..8173e6affcb089 100644
--- a/llvm/test/Other/dump-before-after-filenames
+++ b/llvm/test/Other/dump-before-after-filenames
@@ -24,12 +24,12 @@
 ; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=MULTIPLE-NESTED-RUNS -DSOURCE_FILE_NAME=%s
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-before.ll
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-after.ll
 ; RUN: rm -rf %t/logs
@@ -39,20 +39,20 @@
 ; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=MULTIPLE-NESTED-RUNS-DUMP-ALL -DSOURCE_FILE_NAME=%s
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<llvm::Function>.1/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/0.LoopSimplifyPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<llvm::Function>.0/1.LCSSAPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.l
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<llvm::Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-before.l
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-before.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-after.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/4.VerifierPass.0-before.ll
diff --git a/llvm/test/Other/dump-before-after-multiple-modules b/llvm/test/Other/dump-before-after-multiple-modules
deleted file mode 100644
index 72aeddecf952ae..00000000000000
--- a/llvm/test/Other/dump-before-after-multiple-modules
+++ /dev/null
@@ -1,36 +0,0 @@
-; RUN: mkdir -p %t/logs
-; RUN: rm -rf %t/logs
-
-; RUN: split-file %s %t
-; RUN: opt %t/module-foo -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module,no-op-function,no-op-loop -dump-before=no-op-module,no-op-function,no-op-loop
-; RUN: opt %t/module-bar -disable-output -passes='no-op-module,function(no-op-function),function(loop(no-op-loop)),no-op-module' -ir-dump-directory %t/logs -dump-after=no-op-module,no-op-function,no-op-loop -dump-before=no-op-module,no-op-function,no-op-loop
-; RUN: find %t/logs -type f -print | FileCheck %s
-; CHECK-DAG: module-foo/0.NoOpModulePass.0-before.ll
-; CHECK-DAG: module-foo/0.NoOpModulePass.0-after.ll
-; CHECK-DAG: module-foo/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
-; CHECK-DAG: module-foo/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
-; CHECK-DAG: module-foo/3.NoOpModulePass.1-before.ll
-; CHECK-DAG: module-foo/3.NoOpModulePass.1-after.ll
-; CHECK-DAG: module-bar/0.NoOpModulePass.0-before.ll
-; CHECK-DAG: module-bar/0.NoOpModulePass.0-after.ll
-; CHECK-DAG: module-bar/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-before.ll
-; CHECK-DAG: module-bar/1.ModuleToFunctionPassAdaptor.0/0.PassManager<llvm::Function>.0/0.NoOpFunctionPass.0-after.ll
-; CHECK-DAG: module-bar/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll
-; CHECK-DAG: module-bar/2.ModuleToFunctionPassAdaptor.1/0.PassManager<llvm::Function>.0/0.FunctionToLoopPassAdaptor.0/1.PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
-; CHECK-DAG: module-bar/3.NoOpModulePass.1-before.ll
-; CHECK-DAG: module-bar/3.NoOpModulePass.1-after.ll
-
-;--- module-foo
-
-define void @foo() {
-    ret void
-}
-
-;--- module-bar
-
-define void @bar() {
-entry:
-    br label %loop
-loop:
-    br label %loop
-}

>From c3a0df4bb0e5851f6a874019bcb17ee102fed0e4 Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Sun, 3 Sep 2023 10:51:47 -0700
Subject: [PATCH 3/4] Loosen filename regex in dump-before-afer-filenames

Tests are still failing in CI because the expected output
paths do not match. Loosen the regexes to allow for more
variation in the output paths.
---
 llvm/test/Other/dump-before-after-filenames | 40 ++++++++++-----------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/llvm/test/Other/dump-before-after-filenames b/llvm/test/Other/dump-before-after-filenames
index 8173e6affcb089..9334ac64382512 100644
--- a/llvm/test/Other/dump-before-after-filenames
+++ b/llvm/test/Other/dump-before-after-filenames
@@ -24,12 +24,12 @@
 ; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=MULTIPLE-NESTED-RUNS -DSOURCE_FILE_NAME=%s
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{[^/]+}}>.1/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{[^/]+}}>.1/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{[^/]+}}>.0/0.NoOpLoopPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{[^/]+}}>.0/0.NoOpLoopPass.0-after.ll
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-before.ll
 ; MULTIPLE-NESTED-RUNS-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-after.ll
 ; RUN: rm -rf %t/logs
@@ -39,20 +39,20 @@
 ; RUN: find %t/logs -type f -print | FileCheck %s --check-prefix=MULTIPLE-NESTED-RUNS-DUMP-ALL -DSOURCE_FILE_NAME=%s
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-before.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/0.NoOpModulePass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{(llvm::)?}}Function>.1/0.NoOpFunctionPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{(llvm::)?}}Function>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/0.LoopSimplifyPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-before.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{(llvm::)?}}Function>.0/1.LCSSAPass.0-after.ll
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-before.l
-; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{(llvm::)?}}Function>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{(llvm::)?}}Loop, {{(llvm::)?}}AnalysisManager<{{(llvm::)?}}Loop, {{(llvm::)?}}LoopStandardAnalysisResults&>, {{(llvm::)?}}LoopStandardAnalysisResults&, {{(llvm::)?}}LPMUpdater&>.0/0.NoOpLoopPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{[^/]+}}>.1/0.NoOpFunctionPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/1.ModuleToFunctionPassAdaptor.0/1.PassManager<{{[^/]+}}>.1/0.NoOpFunctionPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{[^/]+}}>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.LoopSimplifyPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{[^/]+}}>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.LoopSimplifyPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{[^/]+}}>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/1.LCSSAPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/0.PassManager<{{[^/]+}}>.0/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/1.LCSSAPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.LoopSimplifyPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/0.LoopSimplifyPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/1.LCSSAPass.0-before.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/0.PassManager<{{[^/]+}}>.0/1.LCSSAPass.0-after.ll
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{[^/]+}}>.0/0.NoOpLoopPass.0-before.l
+; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/2.ModuleToFunctionPassAdaptor.1/1.PassManager<{{[^/]+}}>.1/0.FunctionToLoopPassAdaptor.0/1.PassManager<{{[^/]+}}>.0/0.NoOpLoopPass.0-after.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-before.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/3.NoOpModulePass.1-after.ll
 ; MULTIPLE-NESTED-RUNS-DUMP-ALL-DAG: [[SOURCE_FILE_NAME]]/4.VerifierPass.0-before.ll

>From 72b6502cbcbdd90e3c261f95dd9a541bb904db60 Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Wed, 6 Sep 2023 06:06:50 -0700
Subject: [PATCH 4/4] Fix Windows build

Use a relative source filename rather than an absolute source filename
when crafting an output path. Previously two absolute paths would be
concatenated like so:

```
/foo/bar + /baz/qux => /foo/bar/baz/qux
```

Which is fine on Linux, but on windows absolute paths start with
the partition (ie. C:\foo\bar) so we can't just append them.
---
 llvm/lib/Passes/StandardInstrumentations.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index d32071e26f867c..93b2efbf998711 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -968,7 +968,8 @@ DumpIRInstrumentation::fetchCurrentInstrumentationDumpFile(StringRef Suffix) {
   SmallString<16> OutputPath;
   sys::path::append(OutputPath, fetchInstrumentationDumpDirectory());
   assert(CurrentModule);
-  sys::path::append(OutputPath, CurrentModule->getName());
+  sys::path::append(OutputPath,
+                    sys::path::relative_path(CurrentModule->getName()));
   auto *StateStackIt = PipelineStateStack.begin();
   // Skip over the first frame in the stack which represents the module being
   // processed



More information about the cfe-commits mailing list