Skip to content

Add option to dump IR to files instead of stderr #66412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 29, 2023

Conversation

NuriAmari
Copy link
Contributor

This patch adds a flag to LLVM such that the output generated by the -print-(before|after|all)
family of flags is written to files in a directory rather than to stderr.

This new flag is -ir-dump-directory and is used to specify where to write the files. No other flags are added, it just modifies the behavior of the print flags.

This is a second simplified version of the changes proposed in #65179.

This patch only adds support for the new pass manager. If this patch is accepted, similar support can be added to the legacy pass manager.

@llvmbot
Copy link
Member

llvmbot commented Sep 14, 2023

@llvm/pr-subscribers-llvm-ir

Changes This patch adds a flag to LLVM such that the output generated by the `-print-(before|after|all)` family of flags is written to files in a directory rather than to stderr.

This new flag is -ir-dump-directory and is used to specify where to write the files. No other flags are added, it just modifies the behavior of the print flags.

This is a second simplified version of the changes proposed in #65179.

This patch only adds support for the new pass manager. If this patch is accepted, similar support can be added to the legacy pass manager.

Full diff: https://github.com/llvm/llvm-project/pull/66412.diff

5 Files Affected:

  • (modified) llvm/include/llvm/IR/PrintPasses.h (+4)
  • (modified) llvm/include/llvm/Passes/StandardInstrumentations.h (+17-3)
  • (modified) llvm/lib/IR/PrintPasses.cpp (+9)
  • (modified) llvm/lib/Passes/StandardInstrumentations.cpp (+144-23)
  • (added) llvm/test/Other/dump-before-after.ll (+57)
diff --git a/llvm/include/llvm/IR/PrintPasses.h b/llvm/include/llvm/IR/PrintPasses.h
index 95b97e76c867cb2..c4baadfa3975531 100644
--- a/llvm/include/llvm/IR/PrintPasses.h
+++ b/llvm/include/llvm/IR/PrintPasses.h
@@ -55,6 +55,10 @@ bool forcePrintModuleIR();
 bool isPassInPrintList(StringRef PassName);
 bool isFilterPassesEmpty();
 
+// Returns a non-empty string if printing before/after passes is to be
+// dumped into files in the returned directory instead of written to stderr.
+std::string irDumpDirectory();
+
 // Returns true if we should print the function.
 bool isFunctionInPrintList(StringRef FunctionName);
 
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index 331130c6b22d990..fd512635356e5dd 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -46,6 +46,16 @@ class PrintIRInstrumentation {
   void registerCallbacks(PassInstrumentationCallbacks &PIC);
 
 private:
+  enum SuffixType {
+    before,
+    after,
+    invalidated,
+  };
+
+  using PrintModuleDesc = std::tuple<const Module *, std::string /* IRName */,
+                                     StringRef /* StoredPassID */,
+                                     SmallString<128> /* DumpFilename */>;
+
   void printBeforePass(StringRef PassID, Any IR);
   void printAfterPass(StringRef PassID, Any IR);
   void printAfterPassInvalidated(StringRef PassID);
@@ -55,11 +65,15 @@ class PrintIRInstrumentation {
   bool shouldPrintPassNumbers();
   bool shouldPrintAtPassNumber();
 
-  using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>;
-
-  void pushModuleDesc(StringRef PassID, Any IR);
+  void pushModuleDesc(StringRef PassID, Any IR,
+                      SmallString<128> DumpIRFilename);
   PrintModuleDesc popModuleDesc(StringRef PassID);
 
+  SmallString<128> fetchDumpFilename(StringRef PassId, Any IR);
+  StringRef getFileSuffix(SuffixType);
+
+  static constexpr std::array FileSuffixes = {"-before.ll", "-after.ll",
+                                              "-invalidated.ll"};
   PassInstrumentationCallbacks *PIC;
   /// Stack of Module description, enough to print the module after a given
   /// pass.
diff --git a/llvm/lib/IR/PrintPasses.cpp b/llvm/lib/IR/PrintPasses.cpp
index e2ef20bb81ba7d7..406af4a0a5e004e 100644
--- a/llvm/lib/IR/PrintPasses.cpp
+++ b/llvm/lib/IR/PrintPasses.cpp
@@ -103,6 +103,13 @@ static cl::list<std::string>
                             "options"),
                    cl::CommaSeparated, cl::Hidden);
 
+static cl::opt<std::string> IRDumpDirectory(
+    "ir-dump-directory",
+    llvm::cl::desc("If specified, IR printed using the "
+                   "-print-[before|after]{-all} options will be dumped into "
+                   "files in this directory rather than written to stderr"),
+    cl::init(""), cl::Hidden, cl::value_desc("filename"));
+
 /// This is a helper to determine whether to print IR before or
 /// after a pass.
 
@@ -139,6 +146,8 @@ std::vector<std::string> llvm::printAfterPasses() {
   return std::vector<std::string>(PrintAfter);
 }
 
+std::string llvm::irDumpDirectory() { return IRDumpDirectory; }
+
 bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
 
 bool llvm::isPassInPrintList(StringRef PassName) {
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 6244c0a5a949ba1..64bf306438d99d2 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -14,6 +14,7 @@
 
 #include "llvm/Passes/StandardInstrumentations.h"
 #include "llvm/ADT/Any.h"
+#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/CallGraphSCCPass.h"
 #include "llvm/Analysis/LazyCallGraph.h"
@@ -33,6 +34,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"
@@ -684,9 +686,64 @@ PrintIRInstrumentation::~PrintIRInstrumentation() {
   assert(ModuleDescStack.empty() && "ModuleDescStack is not empty at exit");
 }
 
-void PrintIRInstrumentation::pushModuleDesc(StringRef PassID, Any IR) {
+static SmallString<32> getIRDisplayName(Any IR) {
+
+  auto hashName = [](StringRef name) {
+    const size_t hashValue = hash_value(name);
+    return std::to_string(hashValue);
+  };
+
+  SmallString<32> Result;
+  const Module *M = unwrapModule(IR);
+  std::string ModuleName = hashName(M->getName());
+  SmallString<32> IRName;
+  if (any_cast<const Module *>(&IR)) {
+    IRName += "-module";
+  } else if (const Function **F = any_cast<const Function *>(&IR)) {
+    IRName += "-function-";
+    IRName += hashName((*F)->getName());
+  } else if (const LazyCallGraph::SCC **C =
+                 any_cast<const LazyCallGraph::SCC *>(&IR)) {
+    IRName += "-scc-";
+    IRName += hashName((*C)->getName());
+  } else if (const Loop **L = any_cast<const Loop *>(&IR)) {
+    IRName += "-loop-";
+    IRName += hashName((*L)->getName());
+  } else {
+    llvm_unreachable("Unknown wrapped IR type");
+  }
+
+  Result += ModuleName;
+  Result += IRName;
+  return Result;
+}
+
+SmallString<128> PrintIRInstrumentation::fetchDumpFilename(StringRef PassID,
+                                                           Any IR) {
+  const std::string &RootDirectory = irDumpDirectory();
+  assert(!RootDirectory.empty() &&
+         "The flag -ir-dump-directory must be passed to dump IR to files");
+  SmallString<128> ResultPath;
+  ResultPath += RootDirectory;
+  SmallString<16> Filename;
+  Filename += std::to_string(CurrentPassNumber);
+  Filename += "-";
+  Filename += getIRDisplayName(IR);
+  Filename += "-";
+  Filename += PassID;
+  sys::path::append(ResultPath, Filename);
+  return ResultPath;
+}
+
+StringRef
+PrintIRInstrumentation::getFileSuffix(PrintIRInstrumentation::SuffixType Type) {
+  return FileSuffixes[Type];
+}
+
+void PrintIRInstrumentation::pushModuleDesc(StringRef PassID, Any IR,
+                                            SmallString<128> DumpIRFilename) {
   const Module *M = unwrapModule(IR);
-  ModuleDescStack.emplace_back(M, getIRName(IR), PassID);
+  ModuleDescStack.emplace_back(M, getIRName(IR), PassID, DumpIRFilename);
 }
 
 PrintIRInstrumentation::PrintModuleDesc
@@ -697,17 +754,42 @@ PrintIRInstrumentation::popModuleDesc(StringRef PassID) {
   return ModuleDesc;
 }
 
+// Callers are responsible for closing the returned file descriptor
+static int prepareDumpIRFileDescriptor(StringRef DumpIRFilename) {
+  std::error_code EC;
+  auto ParentPath = llvm::sys::path::parent_path(DumpIRFilename);
+  if (!ParentPath.empty()) {
+    std::error_code EC = llvm::sys::fs::create_directories(ParentPath);
+    if (EC)
+      report_fatal_error(Twine("Failed to create directory ") + ParentPath +
+                         " to support -ir-dump-directory: " + EC.message());
+  }
+  int Result = 0;
+  EC =
+      sys::fs::openFile(DumpIRFilename, Result, sys::fs::CD_OpenAlways,
+                        sys::fs::FA_Write | sys::fs::FA_Read, sys::fs::OF_None);
+  if (EC)
+    report_fatal_error(Twine("Failed to open ") + DumpIRFilename +
+                       " to support -ir-dump-directory: " + EC.message());
+  return Result;
+}
+
 void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
   if (isIgnored(PassID))
     return;
 
+  SmallString<128> DumpIRFilename;
+  if (!irDumpDirectory().empty() &&
+      (shouldPrintBeforePass(PassID) || shouldPrintAfterPass(PassID)))
+    DumpIRFilename = fetchDumpFilename(PassID, IR);
+
   // Saving Module for AfterPassInvalidated operations.
   // Note: here we rely on a fact that we do not change modules while
   // traversing the pipeline, so the latest captured module is good
   // for all print operations that has not happen yet.
   if (shouldPrintPassNumbers() || shouldPrintAtPassNumber() ||
       shouldPrintAfterPass(PassID))
-    pushModuleDesc(PassID, IR);
+    pushModuleDesc(PassID, IR, DumpIRFilename);
 
   if (!shouldPrintIR(IR))
     return;
@@ -720,9 +802,20 @@ void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
   if (!shouldPrintBeforePass(PassID))
     return;
 
-  dbgs() << "*** IR Dump Before " << PassID << " on " << getIRName(IR)
-         << " ***\n";
-  unwrapAndPrint(dbgs(), IR);
+  auto WriteIRToStream = [&](raw_ostream &Stream) {
+    Stream << "*** IR Dump Before " << PassID << " on " << getIRName(IR)
+           << " ***\n";
+    unwrapAndPrint(Stream, IR);
+  };
+
+  if (!DumpIRFilename.empty()) {
+    DumpIRFilename += getFileSuffix(SuffixType::before);
+    llvm::raw_fd_ostream DumpIRFileStream{
+        prepareDumpIRFileDescriptor(DumpIRFilename), /* shouldClose */ true};
+    WriteIRToStream(DumpIRFileStream);
+  } else {
+    WriteIRToStream(dbgs());
+  }
 }
 
 void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) {
@@ -736,18 +829,32 @@ void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) {
   const Module *M;
   std::string IRName;
   StringRef StoredPassID;
-  std::tie(M, IRName, StoredPassID) = popModuleDesc(PassID);
+  SmallString<128> DumpIRFilename;
+  std::tie(M, IRName, StoredPassID, DumpIRFilename) = popModuleDesc(PassID);
   assert(StoredPassID == PassID && "mismatched PassID");
 
   if (!shouldPrintIR(IR) || !shouldPrintAfterPass(PassID))
     return;
 
-  dbgs() << "*** IR Dump "
-         << (shouldPrintAtPassNumber()
-                 ? StringRef(formatv("At {0}-{1}", CurrentPassNumber, PassID))
-                 : StringRef(formatv("After {0}", PassID)))
-         << " on " << IRName << " ***\n";
-  unwrapAndPrint(dbgs(), IR);
+  auto WriteIRToStream = [&](raw_ostream &Stream) {
+    Stream << "*** IR Dump "
+           << (shouldPrintAtPassNumber()
+                   ? StringRef(formatv("At {0}-{1}", CurrentPassNumber, PassID))
+                   : StringRef(formatv("After {0}", PassID)))
+           << " on " << IRName << " ***\n";
+    unwrapAndPrint(Stream, IR);
+  };
+
+  if (!irDumpDirectory().empty()) {
+    assert(!DumpIRFilename.empty() && "DumpIRFilename must not be empty and "
+                                      "should be set in printBeforePass");
+    DumpIRFilename += getFileSuffix(SuffixType::after);
+    llvm::raw_fd_ostream DumpIRFileStream{
+        prepareDumpIRFileDescriptor(DumpIRFilename), /* shouldClose */ true};
+    WriteIRToStream(DumpIRFileStream);
+  } else {
+    WriteIRToStream(dbgs());
+  }
 }
 
 void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
@@ -761,22 +868,36 @@ void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
   const Module *M;
   std::string IRName;
   StringRef StoredPassID;
-  std::tie(M, IRName, StoredPassID) = popModuleDesc(PassID);
+  SmallString<128> DumpIRFilename;
+  std::tie(M, IRName, StoredPassID, DumpIRFilename) = popModuleDesc(PassID);
   assert(StoredPassID == PassID && "mismatched PassID");
   // Additional filtering (e.g. -filter-print-func) can lead to module
   // printing being skipped.
   if (!M || !shouldPrintAfterPass(PassID))
     return;
 
-  SmallString<20> Banner;
-  if (shouldPrintAtPassNumber())
-    Banner = formatv("*** IR Dump At {0}-{1} on {2} (invalidated) ***",
-                     CurrentPassNumber, PassID, IRName);
-  else 
-    Banner = formatv("*** IR Dump After {0} on {1} (invalidated) ***", 
-                     PassID, IRName);
-  dbgs() << Banner << "\n";
-  printIR(dbgs(), M);
+  auto WriteIRToStream = [&](raw_ostream &Stream) {
+    SmallString<20> Banner;
+    if (shouldPrintAtPassNumber())
+      Banner = formatv("*** IR Dump At {0}-{1} on {2} (invalidated) ***",
+                       CurrentPassNumber, PassID, IRName);
+    else
+      Banner = formatv("*** IR Dump After {0} on {1} (invalidated) ***", PassID,
+                       IRName);
+    Stream << Banner << "\n";
+    printIR(Stream, M);
+  };
+
+  if (!irDumpDirectory().empty()) {
+    assert(!DumpIRFilename.empty() && "DumpIRFilename must not be empty and "
+                                      "should be set in printBeforePass");
+    DumpIRFilename += getFileSuffix(SuffixType::invalidated);
+    llvm::raw_fd_ostream DumpIRFileStream{
+        prepareDumpIRFileDescriptor(DumpIRFilename), /* shouldClose */ true};
+    WriteIRToStream(DumpIRFileStream);
+  } else {
+    WriteIRToStream(dbgs());
+  }
 }
 
 bool PrintIRInstrumentation::shouldPrintBeforePass(StringRef PassID) {
diff --git a/llvm/test/Other/dump-before-after.ll b/llvm/test/Other/dump-before-after.ll
new file mode 100644
index 000000000000000..1f0d01022551123
--- /dev/null
+++ b/llvm/test/Other/dump-before-after.ll
@@ -0,0 +1,57 @@
+; 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 -print-after=no-op-module -print-before=no-op-module
+; RUN: find %t/logs -type f -print | sort | FileCheck %s --check-prefix=SINGLE-PASS
+; SINGLE-PASS: {{[0-9]+}}-[[MODULE_NAME_HASH:[0-9]+]]-module-NoOpModulePass-after.ll
+; SINGLE-PASS: {{[0-9]+}}-[[MODULE_NAME_HASH]]-module-NoOpModulePass-before.ll
+; RUN: rm -rf %t/logs
+
+
+; Dump before and after multiple runs of the same module pass
+; The integers preceeding log files represent relative pass execution order,
+; but they are not necessarily continuous. That is passes which are run
+; but not printed, still increment the count -- leading to gaps in the printed
+; integers.
+
+; RUN: opt %s -disable-output -passes='no-op-module,no-op-module,no-op-module' -ir-dump-directory %t/logs -print-after=no-op-module -print-before=no-op-module
+; RUN: find %t/logs -type f -print | sort | FileCheck %s --check-prefix=MULTIPLE-PASSES
+; MULTIPLE-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH:[0-9]+]]-module-NoOpModulePass-after.ll
+; MULTIPLE-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-module-NoOpModulePass-before.ll
+; MULTIPLE-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-module-NoOpModulePass-after.ll
+; MULTIPLE-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-module-NoOpModulePass-before.ll
+; MULTIPLE-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-module-NoOpModulePass-after.ll
+; MULTIPLE-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-module-NoOpModulePass-before.ll
+; RUN: rm -rf %t/logs
+
+; Dump before and after multiple passes, of various levels of granularity
+
+; RUN: opt %s -disable-output -passes='no-op-module,cgscc(no-op-cgscc),function(no-op-function),function(loop(no-op-loop))' -ir-dump-directory %t/logs -print-after=no-op-module,no-op-cgscc,no-op-function,no-op-loop -print-before=no-op-module,no-op-cgscc,no-op-function,no-op-loop
+; RUN: find %t/logs -type f -print | sort | FileCheck %s --check-prefix=MULTIPLE-GRANULAR-PASSES
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH:[0-9]+]]-module-NoOpModulePass-after.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-module-NoOpModulePass-before.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-scc-[[SCC_FOO_HASH:[0-9]+]]-NoOpCGSCCPass-after.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-scc-[[SCC_FOO_HASH]]-NoOpCGSCCPass-before.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-scc-[[SCC_BAR_HASH:[0-9]+]]-NoOpCGSCCPass-after.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-scc-[[SCC_BAR_HASH]]-NoOpCGSCCPass-before.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-function-[[FUNCTION_FOO_HASH:[0-9]+]]-NoOpFunctionPass-after.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-function-[[FUNCTION_FOO_HASH]]-NoOpFunctionPass-before.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-function-[[FUNCTION_BAR_HASH:[0-9]+]]-NoOpFunctionPass-after.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-function-[[FUNCTION_BAR_HASH]]-NoOpFunctionPass-before.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-loop-[[LOOP_NAME_HASH:[0-9]+]]-NoOpLoopPass-after.ll
+; MULTIPLE-GRANULAR-PASSES: {{[0-9]+}}-[[MODULE_NAME_HASH]]-loop-[[LOOP_NAME_HASH]]-NoOpLoopPass-before.ll
+
+; RUN: rm -rf %t/logs
+
+define void @foo() {
+    ret void
+}
+
+define void @bar() {
+entry:
+    br label %my-loop
+my-loop:
+    br label %my-loop
+}

@NuriAmari NuriAmari marked this pull request as ready for review September 14, 2023 20:10
@ellishg ellishg requested review from aeubanks, asl and Flakebi September 14, 2023 20:28
asl
asl previously requested changes Sep 14, 2023
@@ -0,0 +1,57 @@
; RUN: mkdir -p %t/logs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the test could be run on Windows host

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this appears in lots of tests, it should work on windows

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this appears in lots of tests, it should work on windows

yeah, indeed. Are we sure about find / sort though?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It passes the windows CI on this PR, is that assurance enough?

@asl asl self-requested a review September 14, 2023 22:43
@asl asl dismissed their stale review September 14, 2023 22:47

Further clarifications are needed

return Result;
}

SmallString<128> PrintIRInstrumentation::fetchDumpFilename(StringRef PassID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you call this something other than PassID? I assumed this was the char& PassID initially

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what char& PassID refers to, but updated the name.

@nikic nikic changed the title Add option to dump IR to files intstead of stderr Add option to dump IR to files instead of stderr Sep 15, 2023
@NuriAmari NuriAmari requested a review from arsenm September 25, 2023 17:09
@NuriAmari
Copy link
Contributor Author

Could I get a review on the latest revision? Thanks.

Copy link
Member

@Flakebi Flakebi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a nice idea to me, I left some comments inline

@NuriAmari NuriAmari force-pushed the simple-dump-before-after branch 2 times, most recently from 535e648 to a5bd20a Compare September 27, 2023 15:44
Copy link
Member

@Flakebi Flakebi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, but please give it a day or two in case others have comments.

Copy link
Contributor

@kyulee-com kyulee-com left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@aeubanks aeubanks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the late review, still am reviewing but here are some initial comments

@@ -18,6 +18,7 @@
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/StableHashing.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should pull StableHashing.h out of CodeGen first

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#67704, although I'll wait for this PR to go in first

@@ -18,6 +18,7 @@
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/StableHashing.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#67704, although I'll wait for this PR to go in first

; CHECK: 2-{{[a-z0-9]+}}-loop-{{[a-z0-9]+}}-LoopDeletionPass-invalidated.ll

; RUN: ls %t/logs | count 1
; RUN: cat %t/logs/* | FileCheck %s --check-prefix=CHECK-CONTENTS
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully this globbing is ok

Copy link
Contributor

@aeubanks aeubanks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lg, thanks!

@NuriAmari
Copy link
Contributor Author

@aeubanks If I could ask quickly, what do you think the easiest way to test the same functionality but implemeted for the legacy pass manager would be?

Seems running opt with the legacy pass manager is no longer possible. Should I use llc, and if so is there a set of "no-op" like machine passes? Seems the original -print-after behavior was tested before the NPM came into the picture.

@aeubanks
Copy link
Contributor

@aeubanks If I could ask quickly, what do you think the easiest way to test the same functionality but implemeted for the legacy pass manager would be?

Seems running opt with the legacy pass manager is no longer possible. Should I use llc, and if so is there a set of "no-op" like machine passes? Seems the original -print-after behavior was tested before the NPM came into the picture.

You can't run specific passes with llc since some passes depend on others having already run, so you can't really nicely test it with no-op passes. See how https://reviews.llvm.org/D133055 tested functionality for inspiration. You'll probably have to run all the codegen passes and test that something happened for a random pass that ran.

Also the -print-before/after for the legacy PM is too complicated, it adds a whole pass to print rather than checking if it should print right before/after running the pass (like what https://reviews.llvm.org/D133055 does). We should probably rewrite it to be simpler first.

This patch adds a flag to LLVM such that the output
generated by the `-print-(before|after|all)`
family of flags is written to files in a directory rather
than to stderr.

This new flag is `-ir-dump-directory` and is used to
specify where to write the files. No other flags are
added, it just modifies the behavior of the print flags.
@NuriAmari NuriAmari force-pushed the simple-dump-before-after branch from 19b0fba to 840169e Compare September 28, 2023 23:03
@NuriAmari
Copy link
Contributor Author

Also the -print-before/after for the legacy PM is too complicated, it adds a whole pass to print rather than checking if it should print right before/after running the pass (like what https://reviews.llvm.org/D133055 does). We should probably rewrite it to be simpler first.

Yeah my plan was just to modify the created passes, but that wasn't straight forward either from what I remember. I will see about simplifying it.

Thanks for the reviews all.

@rmaz rmaz merged commit c718336 into llvm:main Sep 29, 2023
Guzhu-AMD pushed a commit to GPUOpen-Drivers/llvm-project that referenced this pull request Oct 12, 2023
Local branch amd-gfx 1d89173 Merged main:6dd96d6e80e9 into amd-gfx:6fb83d89c902
Remote branch main c718336 Add option to dump IR to files instead of stderr (llvm#66412)
@NuriAmari NuriAmari deleted the simple-dump-before-after branch June 5, 2024 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants