[mlir] Add option to read reproducer options from file
authorJacques Pienaar <jpienaar@google.com>
Wed, 30 Dec 2020 18:46:01 +0000 (10:46 -0800)
committerJacques Pienaar <jpienaar@google.com>
Wed, 30 Dec 2020 18:46:01 +0000 (10:46 -0800)
Add command line option to read the configuration dumped by the MLIR crash
reproducer and adds those to the other command line options parsed by mlir-opt.

Simple convenience that enables `mlir-opt --run-reproducer /tmp/repro.mlir`
instead of needing to copy&paste the configuration.

Differential Revision: https://reviews.llvm.org/D93924

mlir/docs/PassManagement.md
mlir/lib/Support/MlirOptMain.cpp
mlir/test/Pass/run-reproducer.mlir [new file with mode: 0644]

index a3a5a49..b71859f 100644 (file)
@@ -1138,6 +1138,10 @@ module {
 }
 ```
 
+The configuration dumped can be passed to `mlir-opt` by specifying
+`-run-reproducer` flag. This will result in parsing the first line configuration
+of the reproducer and adding those to the command line options.
+
 ### Local Reproducer Generation
 
 An additional flag may be passed to
index 5d85229..f7d8372 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/StringSaver.h"
 #include "llvm/Support/ToolOutputFile.h"
 
 using namespace mlir;
@@ -182,6 +183,11 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
       "show-dialects", cl::desc("Print the list of registered dialects"),
       cl::init(false));
 
+  static cl::opt<bool> runRepro(
+      "run-reproducer",
+      cl::desc("Append the command line options of the reproducer"),
+      cl::init(false));
+
   InitLLVM y(argc, argv);
 
   // Register any command line options.
@@ -219,6 +225,23 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
     return failure();
   }
 
+  // Parse reproducer options.
+  BumpPtrAllocator a;
+  StringSaver saver(a);
+  if (runRepro) {
+    auto pair = file->getBuffer().split('\n');
+    if (!pair.first.consume_front("// configuration:")) {
+      llvm::errs() << "Failed to find repro configuration, expect file to "
+                      "begin with '// configuration:'\n";
+      return failure();
+    }
+    // Tokenize & parse the first line.
+    SmallVector<const char *, 4> newArgv;
+    newArgv.push_back(argv[0]);
+    llvm::cl::TokenizeGNUCommandLine(pair.first, saver, newArgv);
+    cl::ParseCommandLineOptions(newArgv.size(), &newArgv[0], helpHeader);
+  }
+
   auto output = openOutputFile(outputFilename, &errorMessage);
   if (!output) {
     llvm::errs() << errorMessage << "\n";
diff --git a/mlir/test/Pass/run-reproducer.mlir b/mlir/test/Pass/run-reproducer.mlir
new file mode 100644 (file)
index 0000000..9caa3f6
--- /dev/null
@@ -0,0 +1,22 @@
+// configuration: -mlir-disable-threading=true -pass-pipeline='func(cse,canonicalize)' -print-ir-before=cse -o /dev/null
+
+// Test of the reproducer run option. The first line has to be the
+// configuration (matching what is produced by reproducer).
+
+// RUN: mlir-opt %s -run-reproducer 2>&1 | FileCheck -check-prefix=BEFORE %s
+
+func @foo() {
+  %0 = constant 0 : i32
+  return
+}
+
+func @bar() {
+  return
+}
+
+// BEFORE: *** IR Dump Before{{.*}}CSE ***
+// BEFORE-NEXT: func @foo()
+// BEFORE: *** IR Dump Before{{.*}}CSE ***
+// BEFORE-NEXT: func @bar()
+// BEFORE-NOT: *** IR Dump Before{{.*}}Canonicalizer ***
+// BEFORE-NOT: *** IR Dump After