[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. /// Process a single buffer of the input.
static LogicalResult static LogicalResult
processBuffer(MLIRContext &context, TimingScope &ts, llvm::SourceMgr &sourceMgr, 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. // Add the annotation file if one was explicitly specified.
std::string annotationFilenameDetermined; std::string annotationFilenameDetermined;
if (!inputAnnotationFilename.empty()) { 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 the user asked for just a parse, stop here.
if (parseOnly) { if (parseOnly) {
auto outputTimer = ts.nest("Output"); mlir::ModuleOp theModule = module.release();
return callback(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. // 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()))) if (failed(pm.run(module.get())))
return failure(); return failure();
auto outputTimer = ts.nest("Output");
// Note that we intentionally "leak" the Module into the MLIRContext instead // Note that we intentionally "leak" the Module into the MLIRContext instead
// of deallocating it. There is no need to deallocate it right before // of deallocating it. There is no need to deallocate it right before
// process exit. // 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 /// 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 static LogicalResult
processInputSplit(MLIRContext &context, TimingScope &ts, processInputSplit(MLIRContext &context, TimingScope &ts,
std::unique_ptr<llvm::MemoryBuffer> buffer, std::unique_ptr<llvm::MemoryBuffer> buffer,
llvm::function_ref<LogicalResult(ModuleOp)> emitCallback) { Optional<std::unique_ptr<llvm::ToolOutputFile>> &outputFile) {
llvm::SourceMgr sourceMgr; llvm::SourceMgr sourceMgr;
sourceMgr.AddNewSourceBuffer(std::move(buffer), llvm::SMLoc()); sourceMgr.AddNewSourceBuffer(std::move(buffer), llvm::SMLoc());
if (verifyDiagnostics) { if (verifyDiagnostics) {
SourceMgrDiagnosticVerifierHandler sourceMgrHandler(sourceMgr, &context); SourceMgrDiagnosticVerifierHandler sourceMgrHandler(sourceMgr, &context);
context.printOpOnDiagnostic(false); context.printOpOnDiagnostic(false);
(void)processBuffer(context, ts, sourceMgr, emitCallback); (void)processBuffer(context, ts, sourceMgr, outputFile);
return sourceMgrHandler.verify(); return sourceMgrHandler.verify();
} else { } else {
SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, &context); 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 static LogicalResult
processInput(MLIRContext &context, TimingScope &ts, processInput(MLIRContext &context, TimingScope &ts,
std::unique_ptr<llvm::MemoryBuffer> input, std::unique_ptr<llvm::MemoryBuffer> input,
llvm::function_ref<LogicalResult(ModuleOp)> emitCallback) { Optional<std::unique_ptr<llvm::ToolOutputFile>> &outputFile) {
if (splitInputFile) { if (splitInputFile) {
// Emit an error if the user provides a separate annotation file alongside // Emit an error if the user provides a separate annotation file alongside
// split input. This is technically not a problem, but the user likely // split input. This is technically not a problem, but the user likely
@ -398,12 +429,11 @@ processInput(MLIRContext &context, TimingScope &ts,
return splitAndProcessBuffer( return splitAndProcessBuffer(
std::move(input), std::move(input),
[&](std::unique_ptr<MemoryBuffer> buffer, raw_ostream &) { [&](std::unique_ptr<MemoryBuffer> buffer, raw_ostream &) {
return processInputSplit(context, ts, std::move(buffer), return processInputSplit(context, ts, std::move(buffer), outputFile);
emitCallback);
}, },
llvm::outs()); llvm::outs());
} else { } 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. // Register our dialects.
context.loadDialect<firrtl::FIRRTLDialect, hw::HWDialect, comb::CombDialect, context.loadDialect<firrtl::FIRRTLDialect, hw::HWDialect, comb::CombDialect,
sv::SVDialect>(); sv::SVDialect>();
// Process the input. // Process the input.
if (failed(processInput(context, ts, std::move(input), emitCallback))) if (failed(processInput(context, ts, std::move(input), outputFile)))
return failure(); return failure();
// If the result succeeded and we're emitting a file, close it. // If the result succeeded and we're emitting a file, close it.