MLIR  19.0.0git
MlirOptMain.cpp
Go to the documentation of this file.
1 //===- MlirOptMain.cpp - MLIR Optimizer Driver ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This is a utility that runs an optimization pass and prints the result back
10 // out. It is designed to support unit testing.
11 //
12 //===----------------------------------------------------------------------===//
13 
17 #include "mlir/Debug/Counter.h"
23 #include "mlir/IR/AsmState.h"
24 #include "mlir/IR/Attributes.h"
25 #include "mlir/IR/BuiltinOps.h"
26 #include "mlir/IR/Diagnostics.h"
27 #include "mlir/IR/Dialect.h"
28 #include "mlir/IR/Location.h"
29 #include "mlir/IR/MLIRContext.h"
30 #include "mlir/Parser/Parser.h"
31 #include "mlir/Pass/Pass.h"
32 #include "mlir/Pass/PassManager.h"
35 #include "mlir/Support/Timing.h"
40 #include "llvm/ADT/StringRef.h"
41 #include "llvm/Support/CommandLine.h"
42 #include "llvm/Support/FileUtilities.h"
43 #include "llvm/Support/InitLLVM.h"
44 #include "llvm/Support/ManagedStatic.h"
45 #include "llvm/Support/Process.h"
46 #include "llvm/Support/Regex.h"
47 #include "llvm/Support/SourceMgr.h"
48 #include "llvm/Support/StringSaver.h"
49 #include "llvm/Support/ThreadPool.h"
50 #include "llvm/Support/ToolOutputFile.h"
51 
52 using namespace mlir;
53 using namespace llvm;
54 
55 namespace {
56 class BytecodeVersionParser : public cl::parser<std::optional<int64_t>> {
57 public:
58  BytecodeVersionParser(cl::Option &o)
59  : cl::parser<std::optional<int64_t>>(o) {}
60 
61  bool parse(cl::Option &o, StringRef /*argName*/, StringRef arg,
62  std::optional<int64_t> &v) {
63  long long w;
64  if (getAsSignedInteger(arg, 10, w))
65  return o.error("Invalid argument '" + arg +
66  "', only integer is supported.");
67  v = w;
68  return false;
69  }
70 };
71 
72 /// This class is intended to manage the handling of command line options for
73 /// creating a *-opt config. This is a singleton.
74 struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
75  MlirOptMainConfigCLOptions() {
76  // These options are static but all uses ExternalStorage to initialize the
77  // members of the parent class. This is unusual but since this class is a
78  // singleton it basically attaches command line option to the singleton
79  // members.
80 
81  static cl::opt<bool, /*ExternalStorage=*/true> allowUnregisteredDialects(
82  "allow-unregistered-dialect",
83  cl::desc("Allow operation with no registered dialects"),
84  cl::location(allowUnregisteredDialectsFlag), cl::init(false));
85 
86  static cl::opt<bool, /*ExternalStorage=*/true> dumpPassPipeline(
87  "dump-pass-pipeline", cl::desc("Print the pipeline that will be run"),
88  cl::location(dumpPassPipelineFlag), cl::init(false));
89 
90  static cl::opt<bool, /*ExternalStorage=*/true> emitBytecode(
91  "emit-bytecode", cl::desc("Emit bytecode when generating output"),
92  cl::location(emitBytecodeFlag), cl::init(false));
93 
94  static cl::opt<bool, /*ExternalStorage=*/true> elideResourcesFromBytecode(
95  "elide-resource-data-from-bytecode",
96  cl::desc("Elide resources when generating bytecode"),
97  cl::location(elideResourceDataFromBytecodeFlag), cl::init(false));
98 
99  static cl::opt<std::optional<int64_t>, /*ExternalStorage=*/true,
100  BytecodeVersionParser>
101  bytecodeVersion(
102  "emit-bytecode-version",
103  cl::desc("Use specified bytecode when generating output"),
104  cl::location(emitBytecodeVersion), cl::init(std::nullopt));
105 
106  static cl::opt<std::string, /*ExternalStorage=*/true> irdlFile(
107  "irdl-file",
108  cl::desc("IRDL file to register before processing the input"),
109  cl::location(irdlFileFlag), cl::init(""), cl::value_desc("filename"));
110 
111  static cl::opt<bool, /*ExternalStorage=*/true> enableDebuggerHook(
112  "mlir-enable-debugger-hook",
113  cl::desc("Enable Debugger hook for debugging MLIR Actions"),
114  cl::location(enableDebuggerActionHookFlag), cl::init(false));
115 
116  static cl::opt<bool, /*ExternalStorage=*/true> explicitModule(
117  "no-implicit-module",
118  cl::desc("Disable implicit addition of a top-level module op during "
119  "parsing"),
120  cl::location(useExplicitModuleFlag), cl::init(false));
121 
122  static cl::opt<bool, /*ExternalStorage=*/true> runReproducer(
123  "run-reproducer", cl::desc("Run the pipeline stored in the reproducer"),
124  cl::location(runReproducerFlag), cl::init(false));
125 
126  static cl::opt<bool, /*ExternalStorage=*/true> showDialects(
127  "show-dialects",
128  cl::desc("Print the list of registered dialects and exit"),
129  cl::location(showDialectsFlag), cl::init(false));
130 
131  static cl::opt<std::string, /*ExternalStorage=*/true> splitInputFile{
132  "split-input-file", llvm::cl::ValueOptional,
133  cl::callback([&](const std::string &str) {
134  // Implicit value: use default marker if flag was used without value.
135  if (str.empty())
136  splitInputFile.setValue(kDefaultSplitMarker);
137  }),
138  cl::desc("Split the input file into chunks using the given or "
139  "default marker and process each chunk independently"),
140  cl::location(splitInputFileFlag), cl::init("")};
141 
142  static cl::opt<std::string, /*ExternalStorage=*/true> outputSplitMarker(
143  "output-split-marker",
144  cl::desc("Split marker to use for merging the ouput"),
145  cl::location(outputSplitMarkerFlag), cl::init(kDefaultSplitMarker));
146 
147  static cl::opt<bool, /*ExternalStorage=*/true> verifyDiagnostics(
148  "verify-diagnostics",
149  cl::desc("Check that emitted diagnostics match "
150  "expected-* lines on the corresponding line"),
151  cl::location(verifyDiagnosticsFlag), cl::init(false));
152 
153  static cl::opt<bool, /*ExternalStorage=*/true> verifyPasses(
154  "verify-each",
155  cl::desc("Run the verifier after each transformation pass"),
156  cl::location(verifyPassesFlag), cl::init(true));
157 
158  static cl::opt<bool, /*ExternalStorage=*/true> verifyRoundtrip(
159  "verify-roundtrip",
160  cl::desc("Round-trip the IR after parsing and ensure it succeeds"),
161  cl::location(verifyRoundtripFlag), cl::init(false));
162 
163  static cl::list<std::string> passPlugins(
164  "load-pass-plugin", cl::desc("Load passes from plugin library"));
165 
166  static cl::opt<std::string, /*ExternalStorage=*/true>
167  generateReproducerFile(
168  "mlir-generate-reproducer",
169  llvm::cl::desc(
170  "Generate an mlir reproducer at the provided filename"
171  " (no crash required)"),
172  cl::location(generateReproducerFileFlag), cl::init(""),
173  cl::value_desc("filename"));
174 
175  /// Set the callback to load a pass plugin.
176  passPlugins.setCallback([&](const std::string &pluginPath) {
177  auto plugin = PassPlugin::load(pluginPath);
178  if (!plugin) {
179  errs() << "Failed to load passes from '" << pluginPath
180  << "'. Request ignored.\n";
181  return;
182  }
183  plugin.get().registerPassRegistryCallbacks();
184  });
185 
186  static cl::list<std::string> dialectPlugins(
187  "load-dialect-plugin", cl::desc("Load dialects from plugin library"));
188  this->dialectPlugins = std::addressof(dialectPlugins);
189 
190  static PassPipelineCLParser passPipeline("", "Compiler passes to run", "p");
191  setPassPipelineParser(passPipeline);
192  }
193 
194  /// Set the callback to load a dialect plugin.
195  void setDialectPluginsCallback(DialectRegistry &registry);
196 
197  /// Pointer to static dialectPlugins variable in constructor, needed by
198  /// setDialectPluginsCallback(DialectRegistry&).
199  cl::list<std::string> *dialectPlugins = nullptr;
200 };
201 } // namespace
202 
203 ManagedStatic<MlirOptMainConfigCLOptions> clOptionsConfig;
204 
206  clOptionsConfig->setDialectPluginsCallback(registry);
208 }
209 
212  return *clOptionsConfig;
213 }
214 
216  const PassPipelineCLParser &passPipeline) {
217  passPipelineCallback = [&](PassManager &pm) {
218  auto errorHandler = [&](const Twine &msg) {
219  emitError(UnknownLoc::get(pm.getContext())) << msg;
220  return failure();
221  };
222  if (failed(passPipeline.addToPipeline(pm, errorHandler)))
223  return failure();
224  if (this->shouldDumpPassPipeline()) {
225 
226  pm.dump();
227  llvm::errs() << "\n";
228  }
229  return success();
230  };
231  return *this;
232 }
233 
234 void MlirOptMainConfigCLOptions::setDialectPluginsCallback(
235  DialectRegistry &registry) {
236  dialectPlugins->setCallback([&](const std::string &pluginPath) {
237  auto plugin = DialectPlugin::load(pluginPath);
238  if (!plugin) {
239  errs() << "Failed to load dialect plugin from '" << pluginPath
240  << "'. Request ignored.\n";
241  return;
242  };
243  plugin.get().registerDialectRegistryCallbacks(registry);
244  });
245 }
246 
247 LogicalResult loadIRDLDialects(StringRef irdlFile, MLIRContext &ctx) {
248  DialectRegistry registry;
249  registry.insert<irdl::IRDLDialect>();
250  ctx.appendDialectRegistry(registry);
251 
252  // Set up the input file.
253  std::string errorMessage;
254  std::unique_ptr<MemoryBuffer> file = openInputFile(irdlFile, &errorMessage);
255  if (!file) {
256  emitError(UnknownLoc::get(&ctx)) << errorMessage;
257  return failure();
258  }
259 
260  // Give the buffer to the source manager.
261  // This will be picked up by the parser.
262  SourceMgr sourceMgr;
263  sourceMgr.AddNewSourceBuffer(std::move(file), SMLoc());
264 
265  SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, &ctx);
266 
267  // Parse the input file.
268  OwningOpRef<ModuleOp> module(parseSourceFile<ModuleOp>(sourceMgr, &ctx));
269  if (!module)
270  return failure();
271 
272  // Load IRDL dialects.
273  return irdl::loadDialects(module.get());
274 }
275 
276 // Return success if the module can correctly round-trip. This intended to test
277 // that the custom printers/parsers are complete.
279  const MlirOptMainConfig &config,
280  bool useBytecode) {
281  // We use a new context to avoid resource handle renaming issue in the diff.
282  MLIRContext roundtripContext;
283  OwningOpRef<Operation *> roundtripModule;
284  roundtripContext.appendDialectRegistry(
285  op->getContext()->getDialectRegistry());
287  roundtripContext.allowUnregisteredDialects();
288  StringRef irdlFile = config.getIrdlFile();
289  if (!irdlFile.empty() && failed(loadIRDLDialects(irdlFile, roundtripContext)))
290  return failure();
291 
292  std::string testType = (useBytecode) ? "bytecode" : "textual";
293  // Print a first time with custom format (or bytecode) and parse it back to
294  // the roundtripModule.
295  {
296  std::string buffer;
297  llvm::raw_string_ostream ostream(buffer);
298  if (useBytecode) {
299  if (failed(writeBytecodeToFile(op, ostream))) {
300  op->emitOpError()
301  << "failed to write bytecode, cannot verify round-trip.\n";
302  return failure();
303  }
304  } else {
305  op->print(ostream,
306  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
307  }
308  FallbackAsmResourceMap fallbackResourceMap;
309  ParserConfig parseConfig(&roundtripContext, /*verifyAfterParse=*/true,
310  &fallbackResourceMap);
311  roundtripModule =
312  parseSourceString<Operation *>(ostream.str(), parseConfig);
313  if (!roundtripModule) {
314  op->emitOpError() << "failed to parse " << testType
315  << " content back, cannot verify round-trip.\n";
316  return failure();
317  }
318  }
319 
320  // Print in the generic form for the reference module and the round-tripped
321  // one and compare the outputs.
322  std::string reference, roundtrip;
323  {
324  llvm::raw_string_ostream ostreamref(reference);
325  op->print(ostreamref,
326  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
327  llvm::raw_string_ostream ostreamrndtrip(roundtrip);
328  roundtripModule.get()->print(
329  ostreamrndtrip,
330  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
331  }
332  if (reference != roundtrip) {
333  // TODO implement a diff.
334  return op->emitOpError()
335  << testType
336  << " roundTrip testing roundtripped module differs "
337  "from reference:\n<<<<<<Reference\n"
338  << reference << "\n=====\n"
339  << roundtrip << "\n>>>>>roundtripped\n";
340  }
341 
342  return success();
343 }
344 
346  const MlirOptMainConfig &config) {
347  auto txtStatus = doVerifyRoundTrip(op, config, /*useBytecode=*/false);
348  auto bcStatus = doVerifyRoundTrip(op, config, /*useBytecode=*/true);
349  return success(succeeded(txtStatus) && succeeded(bcStatus));
350 }
351 
352 /// Perform the actions on the input file indicated by the command line flags
353 /// within the specified context.
354 ///
355 /// This typically parses the main source file, runs zero or more optimization
356 /// passes, then prints the output.
357 ///
358 static LogicalResult
359 performActions(raw_ostream &os,
360  const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
361  MLIRContext *context, const MlirOptMainConfig &config) {
364  TimingScope timing = tm.getRootScope();
365 
366  // Disable multi-threading when parsing the input file. This removes the
367  // unnecessary/costly context synchronization when parsing.
368  bool wasThreadingEnabled = context->isMultithreadingEnabled();
369  context->disableMultithreading();
370 
371  // Prepare the parser config, and attach any useful/necessary resource
372  // handlers. Unhandled external resources are treated as passthrough, i.e.
373  // they are not processed and will be emitted directly to the output
374  // untouched.
375  PassReproducerOptions reproOptions;
376  FallbackAsmResourceMap fallbackResourceMap;
377  ParserConfig parseConfig(context, /*verifyAfterParse=*/true,
378  &fallbackResourceMap);
379  if (config.shouldRunReproducer())
380  reproOptions.attachResourceParser(parseConfig);
381 
382  // Parse the input file and reset the context threading state.
383  TimingScope parserTiming = timing.nest("Parser");
385  sourceMgr, parseConfig, !config.shouldUseExplicitModule());
386  parserTiming.stop();
387  if (!op)
388  return failure();
389 
390  // Perform round-trip verification if requested
391  if (config.shouldVerifyRoundtrip() &&
392  failed(doVerifyRoundTrip(op.get(), config)))
393  return failure();
394 
395  context->enableMultithreading(wasThreadingEnabled);
396 
397  // Prepare the pass manager, applying command-line and reproducer options.
399  pm.enableVerifier(config.shouldVerifyPasses());
401  return failure();
402  pm.enableTiming(timing);
403  if (config.shouldRunReproducer() && failed(reproOptions.apply(pm)))
404  return failure();
405  if (failed(config.setupPassPipeline(pm)))
406  return failure();
407 
408  // Run the pipeline.
409  if (failed(pm.run(*op)))
410  return failure();
411 
412  // Generate reproducers if requested
413  if (!config.getReproducerFilename().empty()) {
414  StringRef anchorName = pm.getAnyOpAnchorName();
415  const auto &passes = pm.getPasses();
416  makeReproducer(anchorName, passes, op.get(),
417  config.getReproducerFilename());
418  }
419 
420  // Print the output.
421  TimingScope outputTiming = timing.nest("Output");
422  if (config.shouldEmitBytecode()) {
423  BytecodeWriterConfig writerConfig(fallbackResourceMap);
424  if (auto v = config.bytecodeVersionToEmit())
425  writerConfig.setDesiredBytecodeVersion(*v);
427  writerConfig.setElideResourceDataFlag();
428  return writeBytecodeToFile(op.get(), os, writerConfig);
429  }
430 
431  if (config.bytecodeVersionToEmit().has_value())
432  return emitError(UnknownLoc::get(pm.getContext()))
433  << "bytecode version while not emitting bytecode";
434  AsmState asmState(op.get(), OpPrintingFlags(), /*locationMap=*/nullptr,
435  &fallbackResourceMap);
436  op.get()->print(os, asmState);
437  os << '\n';
438  return success();
439 }
440 
441 /// Parses the memory buffer. If successfully, run a series of passes against
442 /// it and print the result.
443 static LogicalResult processBuffer(raw_ostream &os,
444  std::unique_ptr<MemoryBuffer> ownedBuffer,
445  const MlirOptMainConfig &config,
446  DialectRegistry &registry,
447  llvm::ThreadPoolInterface *threadPool) {
448  // Tell sourceMgr about this buffer, which is what the parser will pick up.
449  auto sourceMgr = std::make_shared<SourceMgr>();
450  sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc());
451 
452  // Create a context just for the current buffer. Disable threading on creation
453  // since we'll inject the thread-pool separately.
455  if (threadPool)
456  context.setThreadPool(*threadPool);
457 
458  StringRef irdlFile = config.getIrdlFile();
459  if (!irdlFile.empty() && failed(loadIRDLDialects(irdlFile, context)))
460  return failure();
461 
462  // Parse the input file.
464  if (config.shouldVerifyDiagnostics())
465  context.printOpOnDiagnostic(false);
466 
467  tracing::InstallDebugHandler installDebugHandler(context,
468  config.getDebugConfig());
469 
470  // If we are in verify diagnostics mode then we have a lot of work to do,
471  // otherwise just perform the actions without worrying about it.
472  if (!config.shouldVerifyDiagnostics()) {
473  SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &context);
474  return performActions(os, sourceMgr, &context, config);
475  }
476 
477  SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &context);
478 
479  // Do any processing requested by command line flags. We don't care whether
480  // these actions succeed or fail, we only care what diagnostics they produce
481  // and whether they match our expectations.
482  (void)performActions(os, sourceMgr, &context, config);
483 
484  // Verify the diagnostic handler to make sure that each of the diagnostics
485  // matched.
486  return sourceMgrHandler.verify();
487 }
488 
489 std::pair<std::string, std::string>
490 mlir::registerAndParseCLIOptions(int argc, char **argv,
491  llvm::StringRef toolName,
492  DialectRegistry &registry) {
493  static cl::opt<std::string> inputFilename(
494  cl::Positional, cl::desc("<input file>"), cl::init("-"));
495 
496  static cl::opt<std::string> outputFilename("o", cl::desc("Output filename"),
497  cl::value_desc("filename"),
498  cl::init("-"));
499  // Register any command line options.
506 
507  // Build the list of dialects as a header for the --help message.
508  std::string helpHeader = (toolName + "\nAvailable Dialects: ").str();
509  {
510  llvm::raw_string_ostream os(helpHeader);
511  interleaveComma(registry.getDialectNames(), os,
512  [&](auto name) { os << name; });
513  }
514  // Parse pass names in main to ensure static initialization completed.
515  cl::ParseCommandLineOptions(argc, argv, helpHeader);
516  return std::make_pair(inputFilename.getValue(), outputFilename.getValue());
517 }
518 
520  llvm::outs() << "Available Dialects: ";
521  interleave(registry.getDialectNames(), llvm::outs(), ",");
522  llvm::outs() << "\n";
523  return success();
524 }
525 
526 LogicalResult mlir::MlirOptMain(llvm::raw_ostream &outputStream,
527  std::unique_ptr<llvm::MemoryBuffer> buffer,
528  DialectRegistry &registry,
529  const MlirOptMainConfig &config) {
530  if (config.shouldShowDialects())
531  return printRegisteredDialects(registry);
532 
533  // The split-input-file mode is a very specific mode that slices the file
534  // up into small pieces and checks each independently.
535  // We use an explicit threadpool to avoid creating and joining/destroying
536  // threads for each of the split.
537  ThreadPoolInterface *threadPool = nullptr;
538 
539  // Create a temporary context for the sake of checking if
540  // --mlir-disable-threading was passed on the command line.
541  // We use the thread-pool this context is creating, and avoid
542  // creating any thread when disabled.
543  MLIRContext threadPoolCtx;
544  if (threadPoolCtx.isMultithreadingEnabled())
545  threadPool = &threadPoolCtx.getThreadPool();
546 
547  auto chunkFn = [&](std::unique_ptr<MemoryBuffer> chunkBuffer,
548  raw_ostream &os) {
549  return processBuffer(os, std::move(chunkBuffer), config, registry,
550  threadPool);
551  };
552  return splitAndProcessBuffer(std::move(buffer), chunkFn, outputStream,
553  config.inputSplitMarker(),
554  config.outputSplitMarker());
555 }
556 
557 LogicalResult mlir::MlirOptMain(int argc, char **argv,
558  llvm::StringRef inputFilename,
559  llvm::StringRef outputFilename,
560  DialectRegistry &registry) {
561 
562  InitLLVM y(argc, argv);
563 
565 
566  if (config.shouldShowDialects())
567  return printRegisteredDialects(registry);
568 
569  // When reading from stdin and the input is a tty, it is often a user mistake
570  // and the process "appears to be stuck". Print a message to let the user know
571  // about it!
572  if (inputFilename == "-" &&
573  sys::Process::FileDescriptorIsDisplayed(fileno(stdin)))
574  llvm::errs() << "(processing input from stdin now, hit ctrl-c/ctrl-d to "
575  "interrupt)\n";
576 
577  // Set up the input file.
578  std::string errorMessage;
579  auto file = openInputFile(inputFilename, &errorMessage);
580  if (!file) {
581  llvm::errs() << errorMessage << "\n";
582  return failure();
583  }
584 
585  auto output = openOutputFile(outputFilename, &errorMessage);
586  if (!output) {
587  llvm::errs() << errorMessage << "\n";
588  return failure();
589  }
590  if (failed(MlirOptMain(output->os(), std::move(file), registry, config)))
591  return failure();
592 
593  // Keep the output file if the invocation of MlirOptMain was successful.
594  output->keep();
595  return success();
596 }
597 
598 LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
599  DialectRegistry &registry) {
600 
601  // Register and parse command line options.
602  std::string inputFilename, outputFilename;
603  std::tie(inputFilename, outputFilename) =
604  registerAndParseCLIOptions(argc, argv, toolName, registry);
605 
606  return MlirOptMain(argc, argv, inputFilename, outputFilename, registry);
607 }
static LogicalResult printRegisteredDialects(DialectRegistry &registry)
LogicalResult loadIRDLDialects(StringRef irdlFile, MLIRContext &ctx)
static LogicalResult doVerifyRoundTrip(Operation *op, const MlirOptMainConfig &config, bool useBytecode)
ManagedStatic< MlirOptMainConfigCLOptions > clOptionsConfig
static LogicalResult processBuffer(raw_ostream &os, std::unique_ptr< MemoryBuffer > ownedBuffer, const MlirOptMainConfig &config, DialectRegistry &registry, llvm::ThreadPoolInterface *threadPool)
Parses the memory buffer.
static LogicalResult performActions(raw_ostream &os, const std::shared_ptr< llvm::SourceMgr > &sourceMgr, MLIRContext *context, const MlirOptMainConfig &config)
Perform the actions on the input file indicated by the command line flags within the specified contex...
This class provides management for the lifetime of the state used when printing the IR.
Definition: AsmState.h:533
This class contains the configuration used for the bytecode writer.
void setElideResourceDataFlag(bool shouldElideResourceData=true)
Set a boolean flag to skip emission of resources into the bytecode file.
void setDesiredBytecodeVersion(int64_t bytecodeVersion)
Set the desired bytecode version to emit.
Facilities for time measurement and report printing to an output stream.
Definition: Timing.h:388
static llvm::Expected< DialectPlugin > load(const std::string &filename)
Attempts to load a dialect plugin from a given file.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
auto getDialectNames() const
Return the names of dialects known to this registry.
A fallback map containing external resources not explicitly handled by another parser/printer.
Definition: AsmState.h:412
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
void appendDialectRegistry(const DialectRegistry &registry)
Append the contents of the given dialect registry to the registry associated with this context.
void disableMultithreading(bool disable=true)
Set the flag specifying if multi-threading is disabled by the context.
void setThreadPool(llvm::ThreadPoolInterface &pool)
Set a new thread pool to be used in this context.
void enableMultithreading(bool enable=true)
Definition: MLIRContext.h:152
void printOpOnDiagnostic(bool enable)
Set the flag specifying if we should attach the operation to diagnostics emitted via Operation::emit.
const DialectRegistry & getDialectRegistry()
Return the dialect registry associated with this context.
llvm::ThreadPoolInterface & getThreadPool()
Return the thread pool used by this context.
bool isMultithreadingEnabled()
Return true if multi-threading is enabled by the context.
void allowUnregisteredDialects(bool allow=true)
Enables creating operations in unregistered dialects.
bool allowsUnregisteredDialects()
Return true if we allow to create operation for unregistered dialects.
Configuration options for the mlir-opt tool.
Definition: MlirOptMain.h:42
tracing::DebugConfig & getDebugConfig()
Definition: MlirOptMain.h:70
static MlirOptMainConfig createFromCLOptions()
Create a new config with the default set from the CL options.
bool shouldVerifyPasses() const
Definition: MlirOptMain.h:178
StringRef inputSplitMarker() const
Definition: MlirOptMain.h:147
bool shouldVerifyRoundtrip() const
Definition: MlirOptMain.h:185
std::optional< int64_t > bytecodeVersionToEmit() const
Definition: MlirOptMain.h:102
StringRef getReproducerFilename() const
Reproducer file generation (no crash required).
Definition: MlirOptMain.h:188
bool shouldShowDialects() const
Definition: MlirOptMain.h:138
MlirOptMainConfig & outputSplitMarker(std::string splitMarker=kDefaultSplitMarker)
Set whether to merge the output chunks into one file using the given marker.
Definition: MlirOptMain.h:152
bool shouldElideResourceDataFromBytecode() const
Definition: MlirOptMain.h:86
bool shouldEmitBytecode() const
Definition: MlirOptMain.h:85
LogicalResult setupPassPipeline(PassManager &pm) const
Populate the passmanager, if any callback was set.
Definition: MlirOptMain.h:117
static void registerCLOptions(DialectRegistry &dialectRegistry)
Register the options as global LLVM command line options.
bool shouldAllowUnregisteredDialects() const
Definition: MlirOptMain.h:61
bool shouldUseExplicitModule() const
Definition: MlirOptMain.h:163
bool shouldRunReproducer() const
Return true if the reproducer should be run.
Definition: MlirOptMain.h:131
bool shouldVerifyDiagnostics() const
Definition: MlirOptMain.h:171
StringRef getIrdlFile() const
Definition: MlirOptMain.h:95
MlirOptMainConfig & setPassPipelineParser(const PassPipelineCLParser &parser)
Set the parser to use to populate the pass manager.
@ Implicit
Implicit nesting behavior.
iterator_range< pass_iterator > getPasses()
Definition: PassManager.h:81
static StringRef getAnyOpAnchorName()
Return the string name used to anchor op-agnostic pass managers that operate generically on any viabl...
Definition: PassManager.h:139
Set of flags used to control the behavior of the various IR print methods (e.g.
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
void print(raw_ostream &os, const OpPrintingFlags &flags=std::nullopt)
MLIRContext * getContext()
Return the context this operation is associated with.
Definition: Operation.h:216
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:119
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
Definition: Operation.cpp:671
OpTy get() const
Allow accessing the internal op.
Definition: OwningOpRef.h:51
This class represents a configuration for the MLIR assembly parser.
Definition: AsmState.h:460
The main pass manager and pipeline builder.
Definition: PassManager.h:232
MLIRContext * getContext() const
Return an instance of the context.
Definition: PassManager.h:257
LogicalResult run(Operation *op)
Run the passes within this manager on the provided operation.
Definition: Pass.cpp:846
void enableVerifier(bool enabled=true)
Runs the verifier after each individual pass.
Definition: Pass.cpp:843
void enableTiming(TimingScope &timingScope)
Add an instrumentation to time the execution of passes and the computation of analyses.
Definition: PassTiming.cpp:148
This class implements a command-line parser for MLIR passes.
Definition: PassRegistry.h:244
LogicalResult addToPipeline(OpPassManager &pm, function_ref< LogicalResult(const Twine &)> errorHandler) const
Adds the passes defined by this parser entry to the given pass manager.
static llvm::Expected< PassPlugin > load(const std::string &filename)
Attempts to load a pass plugin from a given file.
Definition: PassPlugin.cpp:16
This class is a utility diagnostic handler for use with llvm::SourceMgr.
Definition: Diagnostics.h:553
This class is a utility diagnostic handler for use with llvm::SourceMgr that verifies that emitted di...
Definition: Diagnostics.h:619
LogicalResult verify()
Returns the status of the handler and verifies that all expected diagnostics were emitted.
TimingScope getRootScope()
Get the root timer of this timing manager wrapped in a TimingScope for convenience.
Definition: Timing.cpp:74
An RAII-style wrapper around a timer that ensures the timer is properly started and stopped.
Definition: Timing.h:272
TimingScope nest(Args... args)
Create a nested timing scope.
Definition: Timing.h:311
void stop()
Manually stop the timer early.
Definition: Timing.h:300
static DebugConfig createFromCLOptions()
Create a new config with the default set from the CL options.
static void registerCLOptions()
Register the options as global LLVM command line options.
static void registerCLOptions()
Register the command line options for debug counters.
This is a RAII class that installs the debug handlers on the context based on the provided configurat...
Include the generated interface declarations.
Definition: CallGraph.h:229
LogicalResult loadDialects(ModuleOp op)
Load all the dialects defined in the module.
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Definition: Query.cpp:21
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
std::unique_ptr< llvm::MemoryBuffer > openInputFile(llvm::StringRef inputFilename, std::string *errorMessage=nullptr)
Open the file specified by its name for reading.
LogicalResult applyPassManagerCLOptions(PassManager &pm)
Apply any values provided to the pass manager options that were registered with 'registerPassManagerO...
const char *const kDefaultSplitMarker
void registerDefaultTimingManagerCLOptions()
Register a set of useful command-line options that can be used to configure a DefaultTimingManager.
Definition: Timing.cpp:614
LogicalResult MlirOptMain(llvm::raw_ostream &outputStream, std::unique_ptr< llvm::MemoryBuffer > buffer, DialectRegistry &registry, const MlirOptMainConfig &config)
Perform the core processing behind mlir-opt.
std::unique_ptr< llvm::ToolOutputFile > openOutputFile(llvm::StringRef outputFilename, std::string *errorMessage=nullptr)
Open the file specified by its name for writing.
std::string makeReproducer(StringRef anchorName, const llvm::iterator_range< OpPassManager::pass_iterator > &passes, Operation *op, StringRef outputFile, bool disableThreads=false, bool verifyPasses=false)
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
void registerMLIRContextCLOptions()
Register a set of useful command-line options that can be used to configure various flags within the ...
Definition: MLIRContext.cpp:90
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
Definition: LogicalResult.h:68
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
LogicalResult splitAndProcessBuffer(std::unique_ptr< llvm::MemoryBuffer > originalBuffer, ChunkBufferHandler processChunkBuffer, raw_ostream &os, llvm::StringRef inputSplitMarker=kDefaultSplitMarker, llvm::StringRef outputSplitMarker="")
Splits the specified buffer on a marker (// ----- by default), processes each chunk independently acc...
OwningOpRef< Operation * > parseSourceFileForTool(const std::shared_ptr< llvm::SourceMgr > &sourceMgr, const ParserConfig &config, bool insertImplicitModule)
This parses the file specified by the indicated SourceMgr.
void registerAsmPrinterCLOptions()
Register a set of useful command-line options that can be used to configure various flags within the ...
Definition: AsmPrinter.cpp:204
void registerPassManagerCLOptions()
Register a set of useful command-line options that can be used to configure a pass manager.
void applyDefaultTimingManagerCLOptions(DefaultTimingManager &tm)
Apply any values that were registered with 'registerDefaultTimingManagerOptions' to a DefaultTimingMa...
Definition: Timing.cpp:619
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
std::pair< std::string, std::string > registerAndParseCLIOptions(int argc, char **argv, llvm::StringRef toolName, DialectRegistry &registry)
Register and parse command line options.
LogicalResult writeBytecodeToFile(Operation *op, raw_ostream &os, const BytecodeWriterConfig &config={})
Write the bytecode for the given operation to the provided output stream.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
void attachResourceParser(ParserConfig &config)
Attach an assembly resource parser to 'config' that collects the MLIR reproducer configuration into t...
LogicalResult apply(PassManager &pm) const
Apply the reproducer options to 'pm' and its context.