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 
270  // Load IRDL dialects.
271  return irdl::loadDialects(module.get());
272 }
273 
274 // Return success if the module can correctly round-trip. This intended to test
275 // that the custom printers/parsers are complete.
277  const MlirOptMainConfig &config,
278  bool useBytecode) {
279  // We use a new context to avoid resource handle renaming issue in the diff.
280  MLIRContext roundtripContext;
281  OwningOpRef<Operation *> roundtripModule;
282  roundtripContext.appendDialectRegistry(
283  op->getContext()->getDialectRegistry());
285  roundtripContext.allowUnregisteredDialects();
286  StringRef irdlFile = config.getIrdlFile();
287  if (!irdlFile.empty() && failed(loadIRDLDialects(irdlFile, roundtripContext)))
288  return failure();
289 
290  std::string testType = (useBytecode) ? "bytecode" : "textual";
291  // Print a first time with custom format (or bytecode) and parse it back to
292  // the roundtripModule.
293  {
294  std::string buffer;
295  llvm::raw_string_ostream ostream(buffer);
296  if (useBytecode) {
297  if (failed(writeBytecodeToFile(op, ostream))) {
298  op->emitOpError()
299  << "failed to write bytecode, cannot verify round-trip.\n";
300  return failure();
301  }
302  } else {
303  op->print(ostream,
304  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
305  }
306  FallbackAsmResourceMap fallbackResourceMap;
307  ParserConfig parseConfig(&roundtripContext, /*verifyAfterParse=*/true,
308  &fallbackResourceMap);
309  roundtripModule =
310  parseSourceString<Operation *>(ostream.str(), parseConfig);
311  if (!roundtripModule) {
312  op->emitOpError() << "failed to parse " << testType
313  << " content back, cannot verify round-trip.\n";
314  return failure();
315  }
316  }
317 
318  // Print in the generic form for the reference module and the round-tripped
319  // one and compare the outputs.
320  std::string reference, roundtrip;
321  {
322  llvm::raw_string_ostream ostreamref(reference);
323  op->print(ostreamref,
324  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
325  llvm::raw_string_ostream ostreamrndtrip(roundtrip);
326  roundtripModule.get()->print(
327  ostreamrndtrip,
328  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
329  }
330  if (reference != roundtrip) {
331  // TODO implement a diff.
332  return op->emitOpError()
333  << testType
334  << " roundTrip testing roundtripped module differs "
335  "from reference:\n<<<<<<Reference\n"
336  << reference << "\n=====\n"
337  << roundtrip << "\n>>>>>roundtripped\n";
338  }
339 
340  return success();
341 }
342 
344  const MlirOptMainConfig &config) {
345  auto txtStatus = doVerifyRoundTrip(op, config, /*useBytecode=*/false);
346  auto bcStatus = doVerifyRoundTrip(op, config, /*useBytecode=*/true);
347  return success(succeeded(txtStatus) && succeeded(bcStatus));
348 }
349 
350 /// Perform the actions on the input file indicated by the command line flags
351 /// within the specified context.
352 ///
353 /// This typically parses the main source file, runs zero or more optimization
354 /// passes, then prints the output.
355 ///
356 static LogicalResult
357 performActions(raw_ostream &os,
358  const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
359  MLIRContext *context, const MlirOptMainConfig &config) {
362  TimingScope timing = tm.getRootScope();
363 
364  // Disable multi-threading when parsing the input file. This removes the
365  // unnecessary/costly context synchronization when parsing.
366  bool wasThreadingEnabled = context->isMultithreadingEnabled();
367  context->disableMultithreading();
368 
369  // Prepare the parser config, and attach any useful/necessary resource
370  // handlers. Unhandled external resources are treated as passthrough, i.e.
371  // they are not processed and will be emitted directly to the output
372  // untouched.
373  PassReproducerOptions reproOptions;
374  FallbackAsmResourceMap fallbackResourceMap;
375  ParserConfig parseConfig(context, /*verifyAfterParse=*/true,
376  &fallbackResourceMap);
377  if (config.shouldRunReproducer())
378  reproOptions.attachResourceParser(parseConfig);
379 
380  // Parse the input file and reset the context threading state.
381  TimingScope parserTiming = timing.nest("Parser");
383  sourceMgr, parseConfig, !config.shouldUseExplicitModule());
384  parserTiming.stop();
385  if (!op)
386  return failure();
387 
388  // Perform round-trip verification if requested
389  if (config.shouldVerifyRoundtrip() &&
390  failed(doVerifyRoundTrip(op.get(), config)))
391  return failure();
392 
393  context->enableMultithreading(wasThreadingEnabled);
394 
395  // Prepare the pass manager, applying command-line and reproducer options.
397  pm.enableVerifier(config.shouldVerifyPasses());
399  return failure();
400  pm.enableTiming(timing);
401  if (config.shouldRunReproducer() && failed(reproOptions.apply(pm)))
402  return failure();
403  if (failed(config.setupPassPipeline(pm)))
404  return failure();
405 
406  // Run the pipeline.
407  if (failed(pm.run(*op)))
408  return failure();
409 
410  // Generate reproducers if requested
411  if (!config.getReproducerFilename().empty()) {
412  StringRef anchorName = pm.getAnyOpAnchorName();
413  const auto &passes = pm.getPasses();
414  makeReproducer(anchorName, passes, op.get(),
415  config.getReproducerFilename());
416  }
417 
418  // Print the output.
419  TimingScope outputTiming = timing.nest("Output");
420  if (config.shouldEmitBytecode()) {
421  BytecodeWriterConfig writerConfig(fallbackResourceMap);
422  if (auto v = config.bytecodeVersionToEmit())
423  writerConfig.setDesiredBytecodeVersion(*v);
425  writerConfig.setElideResourceDataFlag();
426  return writeBytecodeToFile(op.get(), os, writerConfig);
427  }
428 
429  if (config.bytecodeVersionToEmit().has_value())
430  return emitError(UnknownLoc::get(pm.getContext()))
431  << "bytecode version while not emitting bytecode";
432  AsmState asmState(op.get(), OpPrintingFlags(), /*locationMap=*/nullptr,
433  &fallbackResourceMap);
434  op.get()->print(os, asmState);
435  os << '\n';
436  return success();
437 }
438 
439 /// Parses the memory buffer. If successfully, run a series of passes against
440 /// it and print the result.
441 static LogicalResult processBuffer(raw_ostream &os,
442  std::unique_ptr<MemoryBuffer> ownedBuffer,
443  const MlirOptMainConfig &config,
444  DialectRegistry &registry,
445  llvm::ThreadPoolInterface *threadPool) {
446  // Tell sourceMgr about this buffer, which is what the parser will pick up.
447  auto sourceMgr = std::make_shared<SourceMgr>();
448  sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc());
449 
450  // Create a context just for the current buffer. Disable threading on creation
451  // since we'll inject the thread-pool separately.
453  if (threadPool)
454  context.setThreadPool(*threadPool);
455 
456  StringRef irdlFile = config.getIrdlFile();
457  if (!irdlFile.empty() && failed(loadIRDLDialects(irdlFile, context)))
458  return failure();
459 
460  // Parse the input file.
462  if (config.shouldVerifyDiagnostics())
463  context.printOpOnDiagnostic(false);
464 
465  tracing::InstallDebugHandler installDebugHandler(context,
466  config.getDebugConfig());
467 
468  // If we are in verify diagnostics mode then we have a lot of work to do,
469  // otherwise just perform the actions without worrying about it.
470  if (!config.shouldVerifyDiagnostics()) {
471  SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &context);
472  return performActions(os, sourceMgr, &context, config);
473  }
474 
475  SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &context);
476 
477  // Do any processing requested by command line flags. We don't care whether
478  // these actions succeed or fail, we only care what diagnostics they produce
479  // and whether they match our expectations.
480  (void)performActions(os, sourceMgr, &context, config);
481 
482  // Verify the diagnostic handler to make sure that each of the diagnostics
483  // matched.
484  return sourceMgrHandler.verify();
485 }
486 
487 std::pair<std::string, std::string>
488 mlir::registerAndParseCLIOptions(int argc, char **argv,
489  llvm::StringRef toolName,
490  DialectRegistry &registry) {
491  static cl::opt<std::string> inputFilename(
492  cl::Positional, cl::desc("<input file>"), cl::init("-"));
493 
494  static cl::opt<std::string> outputFilename("o", cl::desc("Output filename"),
495  cl::value_desc("filename"),
496  cl::init("-"));
497  // Register any command line options.
504 
505  // Build the list of dialects as a header for the --help message.
506  std::string helpHeader = (toolName + "\nAvailable Dialects: ").str();
507  {
508  llvm::raw_string_ostream os(helpHeader);
509  interleaveComma(registry.getDialectNames(), os,
510  [&](auto name) { os << name; });
511  }
512  // Parse pass names in main to ensure static initialization completed.
513  cl::ParseCommandLineOptions(argc, argv, helpHeader);
514  return std::make_pair(inputFilename.getValue(), outputFilename.getValue());
515 }
516 
518  llvm::outs() << "Available Dialects: ";
519  interleave(registry.getDialectNames(), llvm::outs(), ",");
520  llvm::outs() << "\n";
521  return success();
522 }
523 
524 LogicalResult mlir::MlirOptMain(llvm::raw_ostream &outputStream,
525  std::unique_ptr<llvm::MemoryBuffer> buffer,
526  DialectRegistry &registry,
527  const MlirOptMainConfig &config) {
528  if (config.shouldShowDialects())
529  return printRegisteredDialects(registry);
530 
531  // The split-input-file mode is a very specific mode that slices the file
532  // up into small pieces and checks each independently.
533  // We use an explicit threadpool to avoid creating and joining/destroying
534  // threads for each of the split.
535  ThreadPoolInterface *threadPool = nullptr;
536 
537  // Create a temporary context for the sake of checking if
538  // --mlir-disable-threading was passed on the command line.
539  // We use the thread-pool this context is creating, and avoid
540  // creating any thread when disabled.
541  MLIRContext threadPoolCtx;
542  if (threadPoolCtx.isMultithreadingEnabled())
543  threadPool = &threadPoolCtx.getThreadPool();
544 
545  auto chunkFn = [&](std::unique_ptr<MemoryBuffer> chunkBuffer,
546  raw_ostream &os) {
547  return processBuffer(os, std::move(chunkBuffer), config, registry,
548  threadPool);
549  };
550  return splitAndProcessBuffer(std::move(buffer), chunkFn, outputStream,
551  config.inputSplitMarker(),
552  config.outputSplitMarker());
553 }
554 
555 LogicalResult mlir::MlirOptMain(int argc, char **argv,
556  llvm::StringRef inputFilename,
557  llvm::StringRef outputFilename,
558  DialectRegistry &registry) {
559 
560  InitLLVM y(argc, argv);
561 
563 
564  if (config.shouldShowDialects())
565  return printRegisteredDialects(registry);
566 
567  // When reading from stdin and the input is a tty, it is often a user mistake
568  // and the process "appears to be stuck". Print a message to let the user know
569  // about it!
570  if (inputFilename == "-" &&
571  sys::Process::FileDescriptorIsDisplayed(fileno(stdin)))
572  llvm::errs() << "(processing input from stdin now, hit ctrl-c/ctrl-d to "
573  "interrupt)\n";
574 
575  // Set up the input file.
576  std::string errorMessage;
577  auto file = openInputFile(inputFilename, &errorMessage);
578  if (!file) {
579  llvm::errs() << errorMessage << "\n";
580  return failure();
581  }
582 
583  auto output = openOutputFile(outputFilename, &errorMessage);
584  if (!output) {
585  llvm::errs() << errorMessage << "\n";
586  return failure();
587  }
588  if (failed(MlirOptMain(output->os(), std::move(file), registry, config)))
589  return failure();
590 
591  // Keep the output file if the invocation of MlirOptMain was successful.
592  output->keep();
593  return success();
594 }
595 
596 LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
597  DialectRegistry &registry) {
598 
599  // Register and parse command line options.
600  std::string inputFilename, outputFilename;
601  std::tie(inputFilename, outputFilename) =
602  registerAndParseCLIOptions(argc, argv, toolName, registry);
603 
604  return MlirOptMain(argc, argv, inputFilename, outputFilename, registry);
605 }
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:199
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.