|
23 | 23 | #include "mlir/IR/Diagnostics.h" |
24 | 24 | #include "mlir/IR/Location.h" |
25 | 25 | #include "mlir/IR/MLIRContext.h" |
| 26 | +#include "mlir/IR/Remarks.h" |
26 | 27 | #include "mlir/Parser/Parser.h" |
27 | 28 | #include "mlir/Pass/PassManager.h" |
28 | 29 | #include "mlir/Pass/PassRegistry.h" |
| 30 | +#include "mlir/Remark/RemarkStreamer.h" |
29 | 31 | #include "mlir/Support/FileUtilities.h" |
30 | 32 | #include "mlir/Support/Timing.h" |
31 | 33 | #include "mlir/Support/ToolUtilities.h" |
32 | 34 | #include "mlir/Tools/ParseUtilities.h" |
33 | 35 | #include "mlir/Tools/Plugins/DialectPlugin.h" |
34 | 36 | #include "mlir/Tools/Plugins/PassPlugin.h" |
35 | 37 | #include "llvm/ADT/StringRef.h" |
| 38 | +#include "llvm/Remarks/RemarkFormat.h" |
36 | 39 | #include "llvm/Support/CommandLine.h" |
37 | 40 | #include "llvm/Support/InitLLVM.h" |
38 | 41 | #include "llvm/Support/LogicalResult.h" |
@@ -204,6 +207,41 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig { |
204 | 207 | cl::location(generateReproducerFileFlag), cl::init(""), |
205 | 208 | cl::value_desc("filename")); |
206 | 209 |
|
| 210 | + static cl::OptionCategory remarkCategory( |
| 211 | + "Remark Options", |
| 212 | + "Filter remarks by regular expression (llvm::Regex syntax)."); |
| 213 | + |
| 214 | + static llvm::cl::opt<RemarkFormat, /*ExternalStorage=*/true> remarkFormat{ |
| 215 | + "remark-format", |
| 216 | + llvm::cl::desc("Specify the format for remark output."), |
| 217 | + cl::location(remarkFormatFlag), |
| 218 | + llvm::cl::value_desc("format"), |
| 219 | + llvm::cl::init(REMARK_FORMAT_STDOUT), |
| 220 | + llvm::cl::values( |
| 221 | + clEnumValN(REMARK_FORMAT_STDOUT, "emitRemark", |
| 222 | + "Print as emitRemark to command-line"), |
| 223 | + clEnumValN(REMARK_FORMAT_YAML, "yaml", "Print yaml file"), |
| 224 | + clEnumValN(REMARK_FORMAT_BITSTREAM, "bitstream", |
| 225 | + "Print bitstream file")), |
| 226 | + llvm::cl::cat(remarkCategory)}; |
| 227 | + |
| 228 | + static cl::opt<std::string, /*ExternalStorage=*/true> remarksPassed( |
| 229 | + "remarks-passed", cl::desc("Show passed remarks"), |
| 230 | + cl::location(remarksPassedFlag), cl::init(""), cl::cat(remarkCategory)); |
| 231 | + |
| 232 | + static cl::opt<std::string, /*ExternalStorage=*/true> remarksFailed( |
| 233 | + "remarks-failed", cl::desc("Show failed remarks"), |
| 234 | + cl::location(remarksFailedFlag), cl::init(""), cl::cat(remarkCategory)); |
| 235 | + |
| 236 | + static cl::opt<std::string, /*ExternalStorage=*/true> remarksMissed( |
| 237 | + "remarks-missed", cl::desc("Show missed remarks"), |
| 238 | + cl::location(remarksMissedFlag), cl::init(""), cl::cat(remarkCategory)); |
| 239 | + |
| 240 | + static cl::opt<std::string, /*ExternalStorage=*/true> remarksAnalyse( |
| 241 | + "remarks-analyse", cl::desc("Show analysis remarks"), |
| 242 | + cl::location(remarksAnalyseFlag), cl::init(""), |
| 243 | + cl::cat(remarkCategory)); |
| 244 | + |
207 | 245 | /// Set the callback to load a pass plugin. |
208 | 246 | passPlugins.setCallback([&](const std::string &pluginPath) { |
209 | 247 | auto plugin = PassPlugin::load(pluginPath); |
@@ -241,23 +279,23 @@ class DiagnosticFilter : public ScopedDiagnosticHandler { |
241 | 279 | setHandler([verbosityLevel, showNotes](Diagnostic &diag) { |
242 | 280 | auto severity = diag.getSeverity(); |
243 | 281 | switch (severity) { |
244 | | - case DiagnosticSeverity::Error: |
| 282 | + case mlir::DiagnosticSeverity::Error: |
245 | 283 | // failure indicates that the error is not handled by the filter and |
246 | 284 | // goes through to the default handler. Therefore, the error can be |
247 | 285 | // successfully printed. |
248 | 286 | return failure(); |
249 | | - case DiagnosticSeverity::Warning: |
| 287 | + case mlir::DiagnosticSeverity::Warning: |
250 | 288 | if (verbosityLevel == VerbosityLevel::ErrorsOnly) |
251 | 289 | return success(); |
252 | 290 | else |
253 | 291 | return failure(); |
254 | | - case DiagnosticSeverity::Remark: |
| 292 | + case mlir::DiagnosticSeverity::Remark: |
255 | 293 | if (verbosityLevel == VerbosityLevel::ErrorsOnly || |
256 | 294 | verbosityLevel == VerbosityLevel::ErrorsAndWarnings) |
257 | 295 | return success(); |
258 | 296 | else |
259 | 297 | return failure(); |
260 | | - case DiagnosticSeverity::Note: |
| 298 | + case mlir::DiagnosticSeverity::Note: |
261 | 299 | if (showNotes) |
262 | 300 | return failure(); |
263 | 301 | else |
@@ -462,6 +500,38 @@ performActions(raw_ostream &os, |
462 | 500 |
|
463 | 501 | context->enableMultithreading(wasThreadingEnabled); |
464 | 502 |
|
| 503 | + // Set up optimization remarks. |
| 504 | + if (config.shouldEmitRemarks()) { |
| 505 | + remark::RemarkCategories cats{ |
| 506 | + config.remarksPassedFlag, config.remarksFailedFlag, |
| 507 | + config.remarksMissedFlag, config.remarksAnalyseFlag}; |
| 508 | + |
| 509 | + mlir::MLIRContext &ctx = *context; |
| 510 | + |
| 511 | + switch (config.remarkFormatFlag) { |
| 512 | + case REMARK_FORMAT_STDOUT: |
| 513 | + if (failed(mlir::remark::enableOptimizationRemarks(ctx, nullptr, cats))) |
| 514 | + return failure(); |
| 515 | + break; |
| 516 | + |
| 517 | + case REMARK_FORMAT_YAML: { |
| 518 | + constexpr llvm::StringLiteral file{"mlir-remarks.yaml"}; |
| 519 | + if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer( |
| 520 | + ctx, file, llvm::remarks::Format::YAML, cats))) |
| 521 | + return failure(); |
| 522 | + break; |
| 523 | + } |
| 524 | + |
| 525 | + case REMARK_FORMAT_BITSTREAM: { |
| 526 | + constexpr llvm::StringLiteral File{"mlir-remarks.bitstream"}; |
| 527 | + if (failed(mlir::remark::enableOptimizationRemarksWithLLVMStreamer( |
| 528 | + ctx, File, llvm::remarks::Format::Bitstream, cats))) |
| 529 | + return failure(); |
| 530 | + break; |
| 531 | + } |
| 532 | + } |
| 533 | + } |
| 534 | + |
465 | 535 | // Prepare the pass manager, applying command-line and reproducer options. |
466 | 536 | PassManager pm(op.get()->getName(), PassManager::Nesting::Implicit); |
467 | 537 | pm.enableVerifier(config.shouldVerifyPasses()); |
@@ -523,8 +593,8 @@ processBuffer(raw_ostream &os, std::unique_ptr<MemoryBuffer> ownedBuffer, |
523 | 593 | SMLoc()); |
524 | 594 | sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc()); |
525 | 595 |
|
526 | | - // Create a context just for the current buffer. Disable threading on creation |
527 | | - // since we'll inject the thread-pool separately. |
| 596 | + // Create a context just for the current buffer. Disable threading on |
| 597 | + // creation since we'll inject the thread-pool separately. |
528 | 598 | MLIRContext context(registry, MLIRContext::Threading::DISABLED); |
529 | 599 | if (threadPool) |
530 | 600 | context.setThreadPool(*threadPool); |
@@ -669,9 +739,9 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv, |
669 | 739 | if (config.shouldListPasses()) |
670 | 740 | return printRegisteredPassesAndReturn(); |
671 | 741 |
|
672 | | - // When reading from stdin and the input is a tty, it is often a user mistake |
673 | | - // and the process "appears to be stuck". Print a message to let the user know |
674 | | - // about it! |
| 742 | + // When reading from stdin and the input is a tty, it is often a user |
| 743 | + // mistake and the process "appears to be stuck". Print a message to let the |
| 744 | + // user know about it! |
675 | 745 | if (inputFilename == "-" && |
676 | 746 | sys::Process::FileDescriptorIsDisplayed(fileno(stdin))) |
677 | 747 | llvm::errs() << "(processing input from stdin now, hit ctrl-c/ctrl-d to " |
|
0 commit comments