[firtool] Refactor firtool.cpp, emit more specific --mlir-timing output.

Just pass down the output filename instead of a lambda, there is no
need for the extra abstraction here.  While here, change the timer
in the various flavors of output to be more specific than "Output".
This commit is contained in:
Chris Lattner 2021-08-27 10:31:41 -07:00
parent 972b4fb316
commit 648a7f3e95
1 changed files with 44 additions and 30 deletions

View File

@ -201,7 +201,7 @@ static std::unique_ptr<Pass> createSimpleCanonicalizerPass() {
/// Process a single buffer of the input.
static LogicalResult
processBuffer(MLIRContext &context, TimingScope &ts, llvm::SourceMgr &sourceMgr,
llvm::function_ref<LogicalResult(ModuleOp)> callback) {
Optional<std::unique_ptr<llvm::ToolOutputFile>> &outputFile) {
// Add the annotation file if one was explicitly specified.
std::string annotationFilenameDetermined;
if (!inputAnnotationFilename.empty()) {
@ -231,8 +231,21 @@ processBuffer(MLIRContext &context, TimingScope &ts, llvm::SourceMgr &sourceMgr,
// If the user asked for just a parse, stop here.
if (parseOnly) {
auto outputTimer = ts.nest("Output");
return callback(module.release());
mlir::ModuleOp theModule = module.release();
switch (outputFormat) {
case OutputMLIR: {
auto outputTimer = ts.nest("Print .mlir output");
theModule->print(outputFile.getValue()->os());
return success();
}
case OutputDisabled:
return success();
case OutputVerilog:
case OutputSplitVerilog:
llvm::errs()
<< "verilog emission is not supported in -parse-only mode.\n";
return failure();
}
}
// Apply any pass manager command line options.
@ -347,12 +360,30 @@ processBuffer(MLIRContext &context, TimingScope &ts, llvm::SourceMgr &sourceMgr,
if (failed(pm.run(module.get())))
return failure();
auto outputTimer = ts.nest("Output");
// Note that we intentionally "leak" the Module into the MLIRContext instead
// of deallocating it. There is no need to deallocate it right before
// process exit.
return callback(module.release());
mlir::ModuleOp theModule = module.release();
// Emit a single file or multiple files depending on the output format.
switch (outputFormat) {
case OutputMLIR: {
auto outputTimer = ts.nest("Print .mlir output");
theModule->print(outputFile.getValue()->os());
return success();
}
case OutputDisabled:
return success();
case OutputVerilog: {
auto outputTimer = ts.nest("ExportVerilog emission");
return exportVerilog(theModule, outputFile.getValue()->os());
}
case OutputSplitVerilog: {
auto outputTimer = ts.nest("Split ExportVerilog emission");
return exportSplitVerilog(theModule, outputFilename);
}
}
return failure();
}
/// Process a single split of the input. This allocates a source manager and
@ -361,17 +392,17 @@ processBuffer(MLIRContext &context, TimingScope &ts, llvm::SourceMgr &sourceMgr,
static LogicalResult
processInputSplit(MLIRContext &context, TimingScope &ts,
std::unique_ptr<llvm::MemoryBuffer> buffer,
llvm::function_ref<LogicalResult(ModuleOp)> emitCallback) {
Optional<std::unique_ptr<llvm::ToolOutputFile>> &outputFile) {
llvm::SourceMgr sourceMgr;
sourceMgr.AddNewSourceBuffer(std::move(buffer), llvm::SMLoc());
if (verifyDiagnostics) {
SourceMgrDiagnosticVerifierHandler sourceMgrHandler(sourceMgr, &context);
context.printOpOnDiagnostic(false);
(void)processBuffer(context, ts, sourceMgr, emitCallback);
(void)processBuffer(context, ts, sourceMgr, outputFile);
return sourceMgrHandler.verify();
} else {
SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, &context);
return processBuffer(context, ts, sourceMgr, emitCallback);
return processBuffer(context, ts, sourceMgr, outputFile);
}
}
@ -380,7 +411,7 @@ processInputSplit(MLIRContext &context, TimingScope &ts,
static LogicalResult
processInput(MLIRContext &context, TimingScope &ts,
std::unique_ptr<llvm::MemoryBuffer> input,
llvm::function_ref<LogicalResult(ModuleOp)> emitCallback) {
Optional<std::unique_ptr<llvm::ToolOutputFile>> &outputFile) {
if (splitInputFile) {
// Emit an error if the user provides a separate annotation file alongside
// split input. This is technically not a problem, but the user likely
@ -398,12 +429,11 @@ processInput(MLIRContext &context, TimingScope &ts,
return splitAndProcessBuffer(
std::move(input),
[&](std::unique_ptr<MemoryBuffer> buffer, raw_ostream &) {
return processInputSplit(context, ts, std::move(buffer),
emitCallback);
return processInputSplit(context, ts, std::move(buffer), outputFile);
},
llvm::outs());
} else {
return processInputSplit(context, ts, std::move(input), emitCallback);
return processInputSplit(context, ts, std::move(input), outputFile);
}
}
@ -460,28 +490,12 @@ static LogicalResult executeFirtool(MLIRContext &context) {
}
}
// Emit a single file or multiple files depending on the output format.
auto emitCallback = [&](ModuleOp module) -> LogicalResult {
switch (outputFormat) {
case OutputMLIR:
module->print(outputFile.getValue()->os());
return success();
case OutputDisabled:
return success();
case OutputVerilog:
return exportVerilog(module, outputFile.getValue()->os());
case OutputSplitVerilog:
return exportSplitVerilog(module, outputFilename);
}
return failure();
};
// Register our dialects.
context.loadDialect<firrtl::FIRRTLDialect, hw::HWDialect, comb::CombDialect,
sv::SVDialect>();
// Process the input.
if (failed(processInput(context, ts, std::move(input), emitCallback)))
if (failed(processInput(context, ts, std::move(input), outputFile)))
return failure();
// If the result succeeded and we're emitting a file, close it.