circt-{as,dis}: init basic MLIR <--> MLIRBC utilities. (#3941)

This commit is contained in:
Will Dietz 2022-09-22 10:43:31 -05:00 committed by GitHub
parent 20891276ff
commit fba580565b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 322 additions and 2 deletions

View File

@ -19,6 +19,8 @@ set(CIRCT_TEST_DEPENDS
FileCheck count not
split-file
circt-capi-ir-test
circt-as
circt-dis
circt-opt
circt-translate
circt-reduce

View File

@ -0,0 +1,14 @@
// RUN: circt-as %s -o - | circt-opt | FileCheck %s
// RUN: circt-opt %s -emit-bytecode | circt-dis | FileCheck %s
// RUN: circt-as %s -o - | circt-dis | FileCheck %s
firrtl.circuit "Top" {
firrtl.module @Top(in %in : !firrtl.uint<8>,
out %out : !firrtl.uint<8>) {
firrtl.strictconnect %out, %in : !firrtl.uint<8>
}
}
// CHECK-LABEL: firrtl.module @Top(in %in: !firrtl.uint<8>, out %out: !firrtl.uint<8>) {
// CHECK-NEXT: firrtl.strictconnect %out, %in : !firrtl.uint<8>
// CHECK-NEXT: }

View File

@ -56,8 +56,8 @@ tool_dirs = [
config.circt_tools_dir, config.mlir_tools_dir, config.llvm_tools_dir
]
tools = [
'firtool', 'circt-opt', 'circt-reduce', 'circt-translate',
'circt-capi-ir-test', 'esi-tester', 'hlstool'
'firtool', 'circt-as', 'circt-dis', 'circt-opt', 'circt-reduce',
'circt-translate', 'circt-capi-ir-test', 'esi-tester', 'hlstool'
]
# Enable Verilator if it has been detected.

View File

@ -1,4 +1,6 @@
add_subdirectory(circt-as)
add_subdirectory(circt-dis)
add_subdirectory(circt-lsp-server)
add_subdirectory(circt-opt)
add_subdirectory(circt-reduce)

View File

@ -0,0 +1,22 @@
set(LLVM_LINK_COMPONENTS
Support
)
get_property(dialect_libs GLOBAL PROPERTY CIRCT_DIALECT_LIBS)
get_property(mlir_dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
set(LIBS
${dialect_libs}
${mlir_dialect_libs}
MLIRIR
MLIRBytecodeWriter
MLIRParser
MLIRSupport
)
add_llvm_tool(circt-as circt-as.cpp DEPENDS ${LIBS})
target_link_libraries(circt-as PRIVATE ${LIBS})
llvm_update_compile_flags(circt-as)
mlir_check_all_link_libraries(circt-as)

138
tools/circt-as/circt-as.cpp Normal file
View File

@ -0,0 +1,138 @@
//===- circt-as.cpp - Convert MLIR to MLIRBC ------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Convert MLIR textual input to MLIR bytecode (MLIRBC).
//
//===----------------------------------------------------------------------===//
#include "circt/InitAllDialects.h"
#include "circt/Support/Version.h"
#include "mlir/Bytecode/BytecodeWriter.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Arithmetic/IR/Arithmetic.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
#include "mlir/Parser/Parser.h"
#include "mlir/Support/FileUtilities.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include <string>
using namespace llvm;
using namespace mlir;
using namespace circt;
static cl::opt<std::string> inputFilename(cl::Positional,
cl::desc("<input .mlir file>"),
cl::init("-"));
static cl::opt<std::string> outputFilename("o",
cl::desc("Override output filename"),
cl::value_desc("filename"));
static cl::opt<bool> forceOutput("f",
cl::desc("Enable binary output on terminals"),
cl::init(false));
static constexpr const char toolName[] = "circt-as";
/// Print error and return failure.
static LogicalResult emitError(const Twine &err) {
WithColor::error(errs(), toolName) << err << "\n";
return failure();
}
/// Check output stream before writing bytecode to it.
/// Warn and return true if output is known to be displayed.
static bool checkBytecodeOutputToConsole(raw_ostream &os) {
if (os.is_displayed()) {
WithColor::warning(errs(), toolName)
<< "you're attempting to print out a bytecode file."
<< " This is inadvisable as it may cause display problems\n";
WithColor::remark(errs(), toolName)
<< "if you really want to do this, force output with the `-f` option\n";
return true;
}
return false;
}
namespace {
/// Wrapper for OwningOpRef that leaks the module.
struct LeakModule {
OwningOpRef<ModuleOp> module;
~LeakModule() { (void)module.release(); }
};
} // end anonymous namespace
static LogicalResult execute(MLIRContext &context) {
// Figure out where we're writing the output.
if (outputFilename.empty()) {
StringRef input = inputFilename;
if (input == "-")
outputFilename = "-";
else {
input.consume_back(".mlir");
outputFilename = (input + ".mlirbc").str();
}
}
// Open output for writing, early error if problem.
std::string err;
auto output = openOutputFile(outputFilename, &err);
if (!output)
return emitError(err);
if (!forceOutput && checkBytecodeOutputToConsole(output->os()))
return failure();
// Read input MLIR.
SourceMgr srcMgr;
SourceMgrDiagnosticHandler handler(srcMgr, &context);
LeakModule leakMod{
parseSourceFile<ModuleOp>(inputFilename, srcMgr, &context)};
auto &module = leakMod.module;
if (!module)
return failure();
// Write bytecode.
writeBytecodeToFile(*module, output->os());
output->keep();
return success();
}
int main(int argc, char **argv) {
InitLLVM y(argc, argv);
mlir::DialectRegistry registry;
circt::registerAllDialects(registry);
// From circt-opt, register subset of MLIR dialects.
registry.insert<mlir::AffineDialect>();
registry.insert<mlir::LLVM::LLVMDialect>();
registry.insert<mlir::memref::MemRefDialect>();
registry.insert<mlir::func::FuncDialect>();
registry.insert<mlir::arith::ArithmeticDialect>();
registry.insert<mlir::cf::ControlFlowDialect>();
registry.insert<mlir::scf::SCFDialect>();
registry.insert<mlir::emitc::EmitCDialect>();
cl::ParseCommandLineOptions(argc, argv, "CIRCT .mlir -> .mlirbc assembler\n");
MLIRContext context(registry);
exit(failed(execute(context)));
}

View File

@ -0,0 +1,22 @@
set(LLVM_LINK_COMPONENTS
Support
)
get_property(dialect_libs GLOBAL PROPERTY CIRCT_DIALECT_LIBS)
get_property(mlir_dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
set(LIBS
${dialect_libs}
${mlir_dialect_libs}
MLIRIR
MLIRBytecodeReader
MLIRParser
MLIRSupport
)
add_llvm_tool(circt-dis circt-dis.cpp DEPENDS ${LIBS})
target_link_libraries(circt-dis PRIVATE ${LIBS})
llvm_update_compile_flags(circt-dis)
mlir_check_all_link_libraries(circt-dis)

View File

@ -0,0 +1,120 @@
//===- circt-dis.cpp - Convert MLIRBC to MLIR -----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Convert MLIR bytecode (MLIRBC) input to MLIR textual format.
//
//===----------------------------------------------------------------------===//
#include "circt/InitAllDialects.h"
#include "circt/Support/Version.h"
#include "mlir/Bytecode/BytecodeReader.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Arithmetic/IR/Arithmetic.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
#include "mlir/Parser/Parser.h"
#include "mlir/Support/FileUtilities.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include <string>
using namespace llvm;
using namespace mlir;
using namespace circt;
static cl::opt<std::string> inputFilename(cl::Positional,
cl::desc("<input .mlirbc file>"),
cl::init("-"));
static cl::opt<std::string> outputFilename("o",
cl::desc("Override output filename"),
cl::value_desc("filename"));
static constexpr const char toolName[] = "circt-dis";
/// Print error and return failure.
static LogicalResult emitError(const Twine &err) {
WithColor::error(errs(), toolName) << err << "\n";
return failure();
}
namespace {
/// Wrapper for OwningOpRef that leaks the module.
struct LeakModule {
OwningOpRef<ModuleOp> module;
~LeakModule() { (void)module.release(); }
};
} // end anonymous namespace
static LogicalResult execute(MLIRContext &context) {
// Figure out where we're writing the output.
if (outputFilename.empty()) {
StringRef input = inputFilename;
if (input == "-")
outputFilename = "-";
else {
input.consume_back(".mlirbc");
outputFilename = (input + ".mlir").str();
}
}
// Open output for writing, early error if problem.
std::string err;
auto output = openOutputFile(outputFilename, &err);
if (!output)
return emitError(err);
// Read input MLIR bytecode.
SourceMgr srcMgr;
SourceMgrDiagnosticHandler handler(srcMgr, &context);
LeakModule leakMod{
parseSourceFile<ModuleOp>(inputFilename, srcMgr, &context)};
auto &module = leakMod.module;
if (!module)
return failure();
// Write MLIR.
module->print(output->os());
output->keep();
return success();
}
int main(int argc, char **argv) {
InitLLVM y(argc, argv);
mlir::DialectRegistry registry;
circt::registerAllDialects(registry);
// From circt-opt, register subset of MLIR dialects.
registry.insert<mlir::AffineDialect>();
registry.insert<mlir::LLVM::LLVMDialect>();
registry.insert<mlir::memref::MemRefDialect>();
registry.insert<mlir::func::FuncDialect>();
registry.insert<mlir::arith::ArithmeticDialect>();
registry.insert<mlir::cf::ControlFlowDialect>();
registry.insert<mlir::scf::SCFDialect>();
registry.insert<mlir::emitc::EmitCDialect>();
registerAsmPrinterCLOptions();
cl::ParseCommandLineOptions(argc, argv,
"CIRCT .mlirbc -> .mlir disassembler\n");
MLIRContext context(registry);
exit(failed(execute(context)));
}