MLIR  18.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"
34 #include "mlir/Support/Timing.h"
39 #include "llvm/ADT/StringRef.h"
40 #include "llvm/Support/CommandLine.h"
41 #include "llvm/Support/FileUtilities.h"
42 #include "llvm/Support/InitLLVM.h"
43 #include "llvm/Support/ManagedStatic.h"
44 #include "llvm/Support/Process.h"
45 #include "llvm/Support/Regex.h"
46 #include "llvm/Support/SourceMgr.h"
47 #include "llvm/Support/StringSaver.h"
48 #include "llvm/Support/ThreadPool.h"
49 #include "llvm/Support/ToolOutputFile.h"
50 
51 using namespace mlir;
52 using namespace llvm;
53 
54 namespace {
55 class BytecodeVersionParser : public cl::parser<std::optional<int64_t>> {
56 public:
57  BytecodeVersionParser(cl::Option &O)
58  : cl::parser<std::optional<int64_t>>(O) {}
59 
60  bool parse(cl::Option &O, StringRef /*argName*/, StringRef arg,
61  std::optional<int64_t> &v) {
62  long long w;
63  if (getAsSignedInteger(arg, 10, w))
64  return O.error("Invalid argument '" + arg +
65  "', only integer is supported.");
66  v = w;
67  return false;
68  }
69 };
70 
71 /// This class is intended to manage the handling of command line options for
72 /// creating a *-opt config. This is a singleton.
73 struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
74  MlirOptMainConfigCLOptions() {
75  // These options are static but all uses ExternalStorage to initialize the
76  // members of the parent class. This is unusual but since this class is a
77  // singleton it basically attaches command line option to the singleton
78  // members.
79 
80  static cl::opt<bool, /*ExternalStorage=*/true> allowUnregisteredDialects(
81  "allow-unregistered-dialect",
82  cl::desc("Allow operation with no registered dialects"),
83  cl::location(allowUnregisteredDialectsFlag), cl::init(false));
84 
85  static cl::opt<bool, /*ExternalStorage=*/true> dumpPassPipeline(
86  "dump-pass-pipeline", cl::desc("Print the pipeline that will be run"),
87  cl::location(dumpPassPipelineFlag), cl::init(false));
88 
89  static cl::opt<bool, /*ExternalStorage=*/true> emitBytecode(
90  "emit-bytecode", cl::desc("Emit bytecode when generating output"),
91  cl::location(emitBytecodeFlag), cl::init(false));
92 
93  static cl::opt<bool, /*ExternalStorage=*/true> elideResourcesFromBytecode(
94  "elide-resource-data-from-bytecode",
95  cl::desc("Elide resources when generating bytecode"),
96  cl::location(elideResourceDataFromBytecodeFlag), cl::init(false));
97 
98  static cl::opt<std::optional<int64_t>, /*ExternalStorage=*/true,
99  BytecodeVersionParser>
100  bytecodeVersion(
101  "emit-bytecode-version",
102  cl::desc("Use specified bytecode when generating output"),
103  cl::location(emitBytecodeVersion), cl::init(std::nullopt));
104 
105  static cl::opt<std::string, /*ExternalStorage=*/true> irdlFile(
106  "irdl-file",
107  cl::desc("IRDL file to register before processing the input"),
108  cl::location(irdlFileFlag), cl::init(""), cl::value_desc("filename"));
109 
110  static cl::opt<bool, /*ExternalStorage=*/true> enableDebuggerHook(
111  "mlir-enable-debugger-hook",
112  cl::desc("Enable Debugger hook for debugging MLIR Actions"),
113  cl::location(enableDebuggerActionHookFlag), cl::init(false));
114 
115  static cl::opt<bool, /*ExternalStorage=*/true> explicitModule(
116  "no-implicit-module",
117  cl::desc("Disable implicit addition of a top-level module op during "
118  "parsing"),
119  cl::location(useExplicitModuleFlag), cl::init(false));
120 
121  static cl::opt<bool, /*ExternalStorage=*/true> runReproducer(
122  "run-reproducer", cl::desc("Run the pipeline stored in the reproducer"),
123  cl::location(runReproducerFlag), cl::init(false));
124 
125  static cl::opt<bool, /*ExternalStorage=*/true> showDialects(
126  "show-dialects",
127  cl::desc("Print the list of registered dialects and exit"),
128  cl::location(showDialectsFlag), cl::init(false));
129 
130  static cl::opt<bool, /*ExternalStorage=*/true> splitInputFile(
131  "split-input-file",
132  cl::desc("Split the input file into pieces and process each "
133  "chunk independently"),
134  cl::location(splitInputFileFlag), cl::init(false));
135 
136  static cl::opt<bool, /*ExternalStorage=*/true> verifyDiagnostics(
137  "verify-diagnostics",
138  cl::desc("Check that emitted diagnostics match "
139  "expected-* lines on the corresponding line"),
140  cl::location(verifyDiagnosticsFlag), cl::init(false));
141 
142  static cl::opt<bool, /*ExternalStorage=*/true> verifyPasses(
143  "verify-each",
144  cl::desc("Run the verifier after each transformation pass"),
145  cl::location(verifyPassesFlag), cl::init(true));
146 
147  static cl::opt<bool, /*ExternalStorage=*/true> verifyRoundtrip(
148  "verify-roundtrip",
149  cl::desc("Round-trip the IR after parsing and ensure it succeeds"),
150  cl::location(verifyRoundtripFlag), cl::init(false));
151 
152  static cl::list<std::string> passPlugins(
153  "load-pass-plugin", cl::desc("Load passes from plugin library"));
154  /// Set the callback to load a pass plugin.
155  passPlugins.setCallback([&](const std::string &pluginPath) {
156  auto plugin = PassPlugin::load(pluginPath);
157  if (!plugin) {
158  errs() << "Failed to load passes from '" << pluginPath
159  << "'. Request ignored.\n";
160  return;
161  }
162  plugin.get().registerPassRegistryCallbacks();
163  });
164 
165  static cl::list<std::string> dialectPlugins(
166  "load-dialect-plugin", cl::desc("Load dialects from plugin library"));
167  this->dialectPlugins = std::addressof(dialectPlugins);
168 
169  static PassPipelineCLParser passPipeline("", "Compiler passes to run", "p");
170  setPassPipelineParser(passPipeline);
171  }
172 
173  /// Set the callback to load a dialect plugin.
174  void setDialectPluginsCallback(DialectRegistry &registry);
175 
176  /// Pointer to static dialectPlugins variable in constructor, needed by
177  /// setDialectPluginsCallback(DialectRegistry&).
178  cl::list<std::string> *dialectPlugins = nullptr;
179 };
180 } // namespace
181 
182 ManagedStatic<MlirOptMainConfigCLOptions> clOptionsConfig;
183 
185  clOptionsConfig->setDialectPluginsCallback(registry);
187 }
188 
191  return *clOptionsConfig;
192 }
193 
195  const PassPipelineCLParser &passPipeline) {
196  passPipelineCallback = [&](PassManager &pm) {
197  auto errorHandler = [&](const Twine &msg) {
198  emitError(UnknownLoc::get(pm.getContext())) << msg;
199  return failure();
200  };
201  if (failed(passPipeline.addToPipeline(pm, errorHandler)))
202  return failure();
203  if (this->shouldDumpPassPipeline()) {
204 
205  pm.dump();
206  llvm::errs() << "\n";
207  }
208  return success();
209  };
210  return *this;
211 }
212 
213 void MlirOptMainConfigCLOptions::setDialectPluginsCallback(
214  DialectRegistry &registry) {
215  dialectPlugins->setCallback([&](const std::string &pluginPath) {
216  auto plugin = DialectPlugin::load(pluginPath);
217  if (!plugin) {
218  errs() << "Failed to load dialect plugin from '" << pluginPath
219  << "'. Request ignored.\n";
220  return;
221  };
222  plugin.get().registerDialectRegistryCallbacks(registry);
223  });
224 }
225 
226 LogicalResult loadIRDLDialects(StringRef irdlFile, MLIRContext &ctx) {
227  DialectRegistry registry;
228  registry.insert<irdl::IRDLDialect>();
229  ctx.appendDialectRegistry(registry);
230 
231  // Set up the input file.
232  std::string errorMessage;
233  std::unique_ptr<MemoryBuffer> file = openInputFile(irdlFile, &errorMessage);
234  if (!file) {
235  emitError(UnknownLoc::get(&ctx)) << errorMessage;
236  return failure();
237  }
238 
239  // Give the buffer to the source manager.
240  // This will be picked up by the parser.
241  SourceMgr sourceMgr;
242  sourceMgr.AddNewSourceBuffer(std::move(file), SMLoc());
243 
244  SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, &ctx);
245 
246  // Parse the input file.
247  OwningOpRef<ModuleOp> module(parseSourceFile<ModuleOp>(sourceMgr, &ctx));
248 
249  // Load IRDL dialects.
250  return irdl::loadDialects(module.get());
251 }
252 
253 // Return success if the module can correctly round-trip. This intended to test
254 // that the custom printers/parsers are complete.
256  const MlirOptMainConfig &config,
257  bool useBytecode) {
258  // We use a new context to avoid resource handle renaming issue in the diff.
259  MLIRContext roundtripContext;
260  OwningOpRef<Operation *> roundtripModule;
261  roundtripContext.appendDialectRegistry(
262  op->getContext()->getDialectRegistry());
264  roundtripContext.allowUnregisteredDialects();
265  StringRef irdlFile = config.getIrdlFile();
266  if (!irdlFile.empty() && failed(loadIRDLDialects(irdlFile, roundtripContext)))
267  return failure();
268 
269  // Print a first time with custom format (or bytecode) and parse it back to
270  // the roundtripModule.
271  {
272  std::string buffer;
273  llvm::raw_string_ostream ostream(buffer);
274  if (useBytecode) {
275  if (failed(writeBytecodeToFile(op, ostream))) {
276  op->emitOpError()
277  << "failed to write bytecode, cannot verify round-trip.\n";
278  return failure();
279  }
280  } else {
281  op->print(ostream,
282  OpPrintingFlags().printGenericOpForm(false).enableDebugInfo());
283  }
284  FallbackAsmResourceMap fallbackResourceMap;
285  ParserConfig parseConfig(&roundtripContext, /*verifyAfterParse=*/true,
286  &fallbackResourceMap);
287  roundtripModule =
288  parseSourceString<Operation *>(ostream.str(), parseConfig);
289  if (!roundtripModule) {
290  op->emitOpError()
291  << "failed to parse bytecode back, cannot verify round-trip.\n";
292  return failure();
293  }
294  }
295 
296  // Print in the generic form for the reference module and the round-tripped
297  // one and compare the outputs.
298  std::string reference, roundtrip;
299  {
300  llvm::raw_string_ostream ostreamref(reference);
301  op->print(ostreamref,
302  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
303  llvm::raw_string_ostream ostreamrndtrip(roundtrip);
304  roundtripModule.get()->print(
305  ostreamrndtrip,
306  OpPrintingFlags().printGenericOpForm().enableDebugInfo());
307  }
308  if (reference != roundtrip) {
309  // TODO implement a diff.
310  return op->emitOpError() << "roundTrip testing roundtripped module differs "
311  "from reference:\n<<<<<<Reference\n"
312  << reference << "\n=====\n"
313  << roundtrip << "\n>>>>>roundtripped\n";
314  }
315 
316  return success();
317 }
318 
320  const MlirOptMainConfig &config) {
321  // Textual round-trip isn't fully robust at the moment (for example implicit
322  // terminator are losing location informations).
323 
324  return doVerifyRoundTrip(op, config, /*useBytecode=*/true);
325 }
326 
327 /// Perform the actions on the input file indicated by the command line flags
328 /// within the specified context.
329 ///
330 /// This typically parses the main source file, runs zero or more optimization
331 /// passes, then prints the output.
332 ///
333 static LogicalResult
334 performActions(raw_ostream &os,
335  const std::shared_ptr<llvm::SourceMgr> &sourceMgr,
336  MLIRContext *context, const MlirOptMainConfig &config) {
339  TimingScope timing = tm.getRootScope();
340 
341  // Disable multi-threading when parsing the input file. This removes the
342  // unnecessary/costly context synchronization when parsing.
343  bool wasThreadingEnabled = context->isMultithreadingEnabled();
344  context->disableMultithreading();
345 
346  // Prepare the parser config, and attach any useful/necessary resource
347  // handlers. Unhandled external resources are treated as passthrough, i.e.
348  // they are not processed and will be emitted directly to the output
349  // untouched.
350  PassReproducerOptions reproOptions;
351  FallbackAsmResourceMap fallbackResourceMap;
352  ParserConfig parseConfig(context, /*verifyAfterParse=*/true,
353  &fallbackResourceMap);
354  if (config.shouldRunReproducer())
355  reproOptions.attachResourceParser(parseConfig);
356 
357  // Parse the input file and reset the context threading state.
358  TimingScope parserTiming = timing.nest("Parser");
360  sourceMgr, parseConfig, !config.shouldUseExplicitModule());
361  parserTiming.stop();
362  if (!op)
363  return failure();
364 
365  // Perform round-trip verification if requested
366  if (config.shouldVerifyRoundtrip() &&
367  failed(doVerifyRoundTrip(op.get(), config)))
368  return failure();
369 
370  context->enableMultithreading(wasThreadingEnabled);
371 
372  // Prepare the pass manager, applying command-line and reproducer options.
374  pm.enableVerifier(config.shouldVerifyPasses());
376  return failure();
377  pm.enableTiming(timing);
378  if (config.shouldRunReproducer() && failed(reproOptions.apply(pm)))
379  return failure();
380  if (failed(config.setupPassPipeline(pm)))
381  return failure();
382 
383  // Run the pipeline.
384  if (failed(pm.run(*op)))
385  return failure();
386 
387  // Print the output.
388  TimingScope outputTiming = timing.nest("Output");
389  if (config.shouldEmitBytecode()) {
390  BytecodeWriterConfig writerConfig(fallbackResourceMap);
391  if (auto v = config.bytecodeVersionToEmit())
392  writerConfig.setDesiredBytecodeVersion(*v);
394  writerConfig.setElideResourceDataFlag();
395  return writeBytecodeToFile(op.get(), os, writerConfig);
396  }
397 
398  if (config.bytecodeVersionToEmit().has_value())
399  return emitError(UnknownLoc::get(pm.getContext()))
400  << "bytecode version while not emitting bytecode";
401  AsmState asmState(op.get(), OpPrintingFlags(), /*locationMap=*/nullptr,
402  &fallbackResourceMap);
403  op.get()->print(os, asmState);
404  os << '\n';
405  return success();
406 }
407 
408 /// Parses the memory buffer. If successfully, run a series of passes against
409 /// it and print the result.
410 static LogicalResult processBuffer(raw_ostream &os,
411  std::unique_ptr<MemoryBuffer> ownedBuffer,
412  const MlirOptMainConfig &config,
413  DialectRegistry &registry,
414  llvm::ThreadPool *threadPool) {
415  // Tell sourceMgr about this buffer, which is what the parser will pick up.
416  auto sourceMgr = std::make_shared<SourceMgr>();
417  sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc());
418 
419  // Create a context just for the current buffer. Disable threading on creation
420  // since we'll inject the thread-pool separately.
422  if (threadPool)
423  context.setThreadPool(*threadPool);
424 
425  StringRef irdlFile = config.getIrdlFile();
426  if (!irdlFile.empty() && failed(loadIRDLDialects(irdlFile, context)))
427  return failure();
428 
429  // Parse the input file.
431  if (config.shouldVerifyDiagnostics())
432  context.printOpOnDiagnostic(false);
433 
434  tracing::InstallDebugHandler installDebugHandler(context,
435  config.getDebugConfig());
436 
437  // If we are in verify diagnostics mode then we have a lot of work to do,
438  // otherwise just perform the actions without worrying about it.
439  if (!config.shouldVerifyDiagnostics()) {
440  SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &context);
441  return performActions(os, sourceMgr, &context, config);
442  }
443 
444  SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &context);
445 
446  // Do any processing requested by command line flags. We don't care whether
447  // these actions succeed or fail, we only care what diagnostics they produce
448  // and whether they match our expectations.
449  (void)performActions(os, sourceMgr, &context, config);
450 
451  // Verify the diagnostic handler to make sure that each of the diagnostics
452  // matched.
453  return sourceMgrHandler.verify();
454 }
455 
456 std::pair<std::string, std::string>
457 mlir::registerAndParseCLIOptions(int argc, char **argv,
458  llvm::StringRef toolName,
459  DialectRegistry &registry) {
460  static cl::opt<std::string> inputFilename(
461  cl::Positional, cl::desc("<input file>"), cl::init("-"));
462 
463  static cl::opt<std::string> outputFilename("o", cl::desc("Output filename"),
464  cl::value_desc("filename"),
465  cl::init("-"));
466  // Register any command line options.
473 
474  // Build the list of dialects as a header for the --help message.
475  std::string helpHeader = (toolName + "\nAvailable Dialects: ").str();
476  {
477  llvm::raw_string_ostream os(helpHeader);
478  interleaveComma(registry.getDialectNames(), os,
479  [&](auto name) { os << name; });
480  }
481  // Parse pass names in main to ensure static initialization completed.
482  cl::ParseCommandLineOptions(argc, argv, helpHeader);
483  return std::make_pair(inputFilename.getValue(), outputFilename.getValue());
484 }
485 
486 LogicalResult mlir::MlirOptMain(llvm::raw_ostream &outputStream,
487  std::unique_ptr<llvm::MemoryBuffer> buffer,
488  DialectRegistry &registry,
489  const MlirOptMainConfig &config) {
490  if (config.shouldShowDialects()) {
491  llvm::outs() << "Available Dialects: ";
492  interleave(registry.getDialectNames(), llvm::outs(), ",");
493  llvm::outs() << "\n";
494  }
495 
496  // The split-input-file mode is a very specific mode that slices the file
497  // up into small pieces and checks each independently.
498  // We use an explicit threadpool to avoid creating and joining/destroying
499  // threads for each of the split.
500  ThreadPool *threadPool = nullptr;
501 
502  // Create a temporary context for the sake of checking if
503  // --mlir-disable-threading was passed on the command line.
504  // We use the thread-pool this context is creating, and avoid
505  // creating any thread when disabled.
506  MLIRContext threadPoolCtx;
507  if (threadPoolCtx.isMultithreadingEnabled())
508  threadPool = &threadPoolCtx.getThreadPool();
509 
510  auto chunkFn = [&](std::unique_ptr<MemoryBuffer> chunkBuffer,
511  raw_ostream &os) {
512  return processBuffer(os, std::move(chunkBuffer), config, registry,
513  threadPool);
514  };
515  return splitAndProcessBuffer(std::move(buffer), chunkFn, outputStream,
516  config.shouldSplitInputFile(),
517  /*insertMarkerInOutput=*/true);
518 }
519 
520 LogicalResult mlir::MlirOptMain(int argc, char **argv,
521  llvm::StringRef inputFilename,
522  llvm::StringRef outputFilename,
523  DialectRegistry &registry) {
524 
525  InitLLVM y(argc, argv);
526 
528 
529  // When reading from stdin and the input is a tty, it is often a user mistake
530  // and the process "appears to be stuck". Print a message to let the user know
531  // about it!
532  if (inputFilename == "-" &&
533  sys::Process::FileDescriptorIsDisplayed(fileno(stdin)))
534  llvm::errs() << "(processing input from stdin now, hit ctrl-c/ctrl-d to "
535  "interrupt)\n";
536 
537  // Set up the input file.
538  std::string errorMessage;
539  auto file = openInputFile(inputFilename, &errorMessage);
540  if (!file) {
541  llvm::errs() << errorMessage << "\n";
542  return failure();
543  }
544 
545  auto output = openOutputFile(outputFilename, &errorMessage);
546  if (!output) {
547  llvm::errs() << errorMessage << "\n";
548  return failure();
549  }
550  if (failed(MlirOptMain(output->os(), std::move(file), registry, config)))
551  return failure();
552 
553  // Keep the output file if the invocation of MlirOptMain was successful.
554  output->keep();
555  return success();
556 }
557 
558 LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
559  DialectRegistry &registry) {
560 
561  // Register and parse command line options.
562  std::string inputFilename, outputFilename;
563  std::tie(inputFilename, outputFilename) =
564  registerAndParseCLIOptions(argc, argv, toolName, registry);
565 
566  return MlirOptMain(argc, argv, inputFilename, outputFilename, registry);
567 }
LogicalResult loadIRDLDialects(StringRef irdlFile, MLIRContext &ctx)
static LogicalResult doVerifyRoundTrip(Operation *op, const MlirOptMainConfig &config, bool useBytecode)
static LogicalResult processBuffer(raw_ostream &os, std::unique_ptr< MemoryBuffer > ownedBuffer, const MlirOptMainConfig &config, DialectRegistry &registry, llvm::ThreadPool *threadPool)
Parses the memory buffer.
ManagedStatic< MlirOptMainConfigCLOptions > clOptionsConfig
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:341
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::ThreadPool &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::ThreadPool & 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:41
tracing::DebugConfig & getDebugConfig()
Definition: MlirOptMain.h:69
static MlirOptMainConfig createFromCLOptions()
Create a new config with the default set from the CL options.
bool shouldVerifyPasses() const
Definition: MlirOptMain.h:167
bool shouldSplitInputFile() const
Definition: MlirOptMain.h:145
bool shouldVerifyRoundtrip() const
Definition: MlirOptMain.h:174
std::optional< int64_t > bytecodeVersionToEmit() const
Definition: MlirOptMain.h:101
bool shouldShowDialects() const
Definition: MlirOptMain.h:137
bool shouldElideResourceDataFromBytecode() const
Definition: MlirOptMain.h:85
bool shouldEmitBytecode() const
Definition: MlirOptMain.h:84
LogicalResult setupPassPipeline(PassManager &pm) const
Populate the passmanager, if any callback was set.
Definition: MlirOptMain.h:116
static void registerCLOptions(DialectRegistry &dialectRegistry)
Register the options as global LLVM command line options.
bool shouldAllowUnregisteredDialects() const
Definition: MlirOptMain.h:60
bool shouldUseExplicitModule() const
Definition: MlirOptMain.h:152
bool shouldRunReproducer() const
Return true if the reproducer should be run.
Definition: MlirOptMain.h:130
bool shouldVerifyDiagnostics() const
Definition: MlirOptMain.h:160
StringRef getIrdlFile() const
Definition: MlirOptMain.h:94
MlirOptMainConfig & setPassPipelineParser(const PassPipelineCLParser &parser)
Set the parser to use to populate the pass manager.
@ Implicit
Implicit nesting behavior.
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:640
OpTy get() const
Allow accessing the internal op.
Definition: OwningOpRef.h:50
This class represents a configuration for the MLIR assembly parser.
Definition: AsmState.h:460
The main pass manager and pipeline builder.
Definition: PassManager.h:211
MLIRContext * getContext() const
Return an instance of the context.
Definition: PassManager.h:236
LogicalResult run(Operation *op)
Run the passes within this manager on the provided operation.
Definition: Pass.cpp:822
void enableVerifier(bool enabled=true)
Runs the verifier after each individual pass.
Definition: Pass.cpp:819
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:73
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:19
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...
void registerDefaultTimingManagerCLOptions()
Register a set of useful command-line options that can be used to configure a DefaultTimingManager.
Definition: Timing.cpp:557
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.
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
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
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:193
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:562
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult splitAndProcessBuffer(std::unique_ptr< llvm::MemoryBuffer > originalBuffer, ChunkBufferHandler processChunkBuffer, raw_ostream &os, bool enableSplitting=true, bool insertMarkerInOutput=false)
Splits the specified buffer on a marker (// -----), processes each chunk independently according to t...
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.