1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
//===- MlirTranslateMain.cpp - MLIR Translation entry point ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "mlir/Tools/mlir-translate/MlirTranslateMain.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/Verifier.h"
#include "mlir/Parser/Parser.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Support/Timing.h"
#include "mlir/Support/ToolUtilities.h"
#include "mlir/Tools/mlir-translate/Translation.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
using namespace mlir;
//===----------------------------------------------------------------------===//
// Diagnostic Filter
//===----------------------------------------------------------------------===//
namespace {
/// A scoped diagnostic handler that marks non-error diagnostics as handled. As
/// a result, the main diagnostic handler does not print non-error diagnostics.
class ErrorDiagnosticFilter : public ScopedDiagnosticHandler {
public:
ErrorDiagnosticFilter(MLIRContext *ctx) : ScopedDiagnosticHandler(ctx) {
setHandler([](Diagnostic &diag) {
if (diag.getSeverity() != DiagnosticSeverity::Error)
return success();
return failure();
});
}
};
} // namespace
//===----------------------------------------------------------------------===//
// Translate Entry Point
//===----------------------------------------------------------------------===//
LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
llvm::StringRef toolName) {
static llvm::cl::opt<std::string> inputFilename(
llvm::cl::Positional, llvm::cl::desc("<input file>"),
llvm::cl::init("-"));
static llvm::cl::opt<std::string> outputFilename(
"o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"),
llvm::cl::init("-"));
static llvm::cl::opt<bool> allowUnregisteredDialects(
"allow-unregistered-dialect",
llvm::cl::desc("Allow operation with no registered dialects (discouraged: testing only!)"),
llvm::cl::init(false));
static llvm::cl::opt<bool> splitInputFile(
"split-input-file",
llvm::cl::desc("Split the input file into pieces and "
"process each chunk independently"),
llvm::cl::init(false));
static llvm::cl::opt<bool> verifyDiagnostics(
"verify-diagnostics",
llvm::cl::desc("Check that emitted diagnostics match "
"expected-* lines on the corresponding line"),
llvm::cl::init(false));
static llvm::cl::opt<bool> errorDiagnosticsOnly(
"error-diagnostics-only",
llvm::cl::desc("Filter all non-error diagnostics "
"(discouraged: testing only!)"),
llvm::cl::init(false));
llvm::InitLLVM y(argc, argv);
// Add flags for all the registered translations.
llvm::cl::list<const Translation *, bool, TranslationParser>
translationsRequested("", llvm::cl::desc("Translations to perform"),
llvm::cl::Required);
registerAsmPrinterCLOptions();
registerMLIRContextCLOptions();
registerTranslationCLOptions();
registerDefaultTimingManagerCLOptions();
llvm::cl::ParseCommandLineOptions(argc, argv, toolName);
// Initialize the timing manager.
DefaultTimingManager tm;
applyDefaultTimingManagerCLOptions(tm);
TimingScope timing = tm.getRootScope();
std::string errorMessage;
std::unique_ptr<llvm::MemoryBuffer> input;
if (auto inputAlignment = translationsRequested[0]->getInputAlignment())
input = openInputFile(inputFilename, *inputAlignment, &errorMessage);
else
input = openInputFile(inputFilename, &errorMessage);
if (!input) {
llvm::errs() << errorMessage << "\n";
return failure();
}
auto output = openOutputFile(outputFilename, &errorMessage);
if (!output) {
llvm::errs() << errorMessage << "\n";
return failure();
}
// Processes the memory buffer with a new MLIRContext.
auto processBuffer = [&](std::unique_ptr<llvm::MemoryBuffer> ownedBuffer,
raw_ostream &os) {
// Temporary buffers for chained translation processing.
std::string dataIn;
std::string dataOut;
LogicalResult result = LogicalResult::success();
for (size_t i = 0, e = translationsRequested.size(); i < e; ++i) {
llvm::raw_ostream *stream;
llvm::raw_string_ostream dataStream(dataOut);
if (i == e - 1) {
// Output last translation to output.
stream = &os;
} else {
// Output translation to temporary data buffer.
stream = &dataStream;
}
const Translation *translationRequested = translationsRequested[i];
TimingScope translationTiming =
timing.nest(translationRequested->getDescription());
MLIRContext context;
context.allowUnregisteredDialects(allowUnregisteredDialects);
context.printOpOnDiagnostic(!verifyDiagnostics);
auto sourceMgr = std::make_shared<llvm::SourceMgr>();
sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc());
if (verifyDiagnostics) {
// In the diagnostic verification flow, we ignore whether the
// translation failed (in most cases, it is expected to fail) and we do
// not filter non-error diagnostics even if `errorDiagnosticsOnly` is
// set. Instead, we check if the diagnostics were produced as expected.
SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr,
&context);
(void)(*translationRequested)(sourceMgr, os, &context);
result = sourceMgrHandler.verify();
} else if (errorDiagnosticsOnly) {
SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &context);
ErrorDiagnosticFilter diagnosticFilter(&context);
result = (*translationRequested)(sourceMgr, *stream, &context);
} else {
SourceMgrDiagnosticHandler sourceMgrHandler(*sourceMgr, &context);
result = (*translationRequested)(sourceMgr, *stream, &context);
}
if (failed(result))
return result;
if (i < e - 1) {
// If there are further translations, create a new buffer with the
// output data.
dataIn = dataOut;
dataOut.clear();
ownedBuffer = llvm::MemoryBuffer::getMemBuffer(dataIn);
}
}
return result;
};
if (failed(splitAndProcessBuffer(std::move(input), processBuffer,
output->os(), splitInputFile)))
return failure();
output->keep();
return success();
}
|