diff --git a/include/Dialect/HLSCpp/CMakeLists.txt b/include/Dialect/HLSCpp/CMakeLists.txt index e69de29..c13bedf 100644 --- a/include/Dialect/HLSCpp/CMakeLists.txt +++ b/include/Dialect/HLSCpp/CMakeLists.txt @@ -0,0 +1 @@ +add_mlir_dialect(HLSCpp hlscpp) diff --git a/include/Dialect/HLSCpp/Dialect.h b/include/Dialect/HLSCpp/Dialect.h new file mode 100644 index 0000000..153b7ed --- /dev/null +++ b/include/Dialect/HLSCpp/Dialect.h @@ -0,0 +1,20 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +//===----------------------------------------------------------------------===// + +#ifndef SCALEHLS_DIALECT_HLSCPP_DIALECT_H +#define SCALEHLS_DIALECT_HLSCPP_DIALECT_H + +#include "mlir/IR/Dialect.h" + +namespace mlir { +namespace scalehls { +namespace hlscpp { + +#include "Dialect/HLSCpp/HLSCppDialect.h.inc" + +} // namespace hlscpp +} // namespace scalehls +} // namespace mlir + +#endif // SCALEHLS_DIALECT_HLSCPP_DIALECT_H diff --git a/include/Dialect/HLSCpp/Dialect.td b/include/Dialect/HLSCpp/Dialect.td new file mode 100644 index 0000000..733eb9f --- /dev/null +++ b/include/Dialect/HLSCpp/Dialect.td @@ -0,0 +1,28 @@ +//===-------------------------------------------------------*- tablegen -*-===// +// +//===----------------------------------------------------------------------===// + +include "mlir/IR/OpBase.td" + +//===----------------------------------------------------------------------===// +// HLSCpp dialect definition. +//===----------------------------------------------------------------------===// + +def HLSCppDialect : Dialect { + let name = "hlscpp"; + let summary = "An HLSCpp out-of-tree MLIR dialect."; + let description = [{ + This dialect is designed for HLS-specific C++ operations, attributes, and + types. Operations in this dialect can be emitted as optimization directives + decorated C++ code, which is fully synthesizable for commercial HLS tools, + such as Vivado HLS. + }]; + let cppNamespace = "hlscpp"; +} + +//===----------------------------------------------------------------------===// +// Base HLSCpp operation definition. +//===----------------------------------------------------------------------===// + +class HLSCppOp traits = []> : + Op; diff --git a/include/Dialect/HLSCpp/HLSCpp.td b/include/Dialect/HLSCpp/HLSCpp.td new file mode 100644 index 0000000..446663d --- /dev/null +++ b/include/Dialect/HLSCpp/HLSCpp.td @@ -0,0 +1,11 @@ +//===-------------------------------------------------------*- tablegen -*-===// +// +//===----------------------------------------------------------------------===// + +#ifndef SCALEHLS_DIALECT_HLSCPP_TD +#define SCALEHLS_DIALECT_HLSCPP_TD + +include "Dialect.td" +include "Ops.td" + +#endif // SCALEHLS_DIALECT_HLSCPP_TD diff --git a/include/Dialect/HLSCpp/Ops.h b/include/Dialect/HLSCpp/Ops.h new file mode 100644 index 0000000..c5e4abe --- /dev/null +++ b/include/Dialect/HLSCpp/Ops.h @@ -0,0 +1,22 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +//===----------------------------------------------------------------------===// + +#ifndef SCALEHLS_DIALECT_HLSCPP_OPS_H +#define SCALEHLS_DIALECT_HLSCPP_OPS_H + +#include "Dialect/HLSCpp/Dialect.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" + +namespace mlir { +namespace scalehls { +namespace hlscpp { + +#define GET_OP_CLASSES +#include "Dialect/HLSCpp/HLSCpp.h.inc" + +} // namespace hlscpp +} // namespace scalehls +} // namespace mlir + +#endif // SCALEHLS_DIALECT_HLSCPP_OPS_H diff --git a/include/Dialect/HLSCpp/Ops.td b/include/Dialect/HLSCpp/Ops.td new file mode 100644 index 0000000..9995e72 --- /dev/null +++ b/include/Dialect/HLSCpp/Ops.td @@ -0,0 +1,30 @@ +//===-------------------------------------------------------*- tablegen -*-===// +// +//===----------------------------------------------------------------------===// + +include "mlir/Interfaces/SideEffectInterfaces.td" + +def HLSCppFooOp : HLSCppOp<"foo", [NoSideEffect, SameOperandsAndResultType]> { + let summary = "Illustrates how to define an operation."; + let description = [{ + The `hlscpp.foo` operation illustrates how to define a new operation in a + dialect. + + This operation takes an integer argument and returns an integer. + + Example: + + ```mlir + %0 = constant 2 : i32 + // Apply the foo operation to %0 + %1 = hlscpp.foo %0 : i32 + ``` + }]; + + let arguments = (ins I32:$input); + let results = (outs I32:$res); + + let assemblyFormat = [{ + $input attr-dict `:` type($input) + }]; +} diff --git a/include/EmitHLSCpp.h b/include/EmitHLSCpp.h index aeb8bc1..b5d0ae7 100644 --- a/include/EmitHLSCpp.h +++ b/include/EmitHLSCpp.h @@ -2,11 +2,15 @@ // //===----------------------------------------------------------------------===// -#ifndef SCALEHLS_EMIT_HLSCPP_H -#define SCALEHLS_EMIT_HLSCPP_H +#ifndef SCALEHLS_EMITHLSCPP_H +#define SCALEHLS_EMITHLSCPP_H +namespace mlir { namespace scalehls { -void registerHLSCppEmitterTranslation(); -} // namespace scalehls -#endif // SCALEHLS_EMIT_HLSCPP_H +void registerHLSCppEmitterTranslation(); + +} // namespace scalehls +} // namespace mlir + +#endif // SCALEHLS_EMITHLSCPP_H diff --git a/lib/Dialect/HLSCpp/CMakeLists.txt b/lib/Dialect/HLSCpp/CMakeLists.txt index e69de29..2670c98 100644 --- a/lib/Dialect/HLSCpp/CMakeLists.txt +++ b/lib/Dialect/HLSCpp/CMakeLists.txt @@ -0,0 +1,14 @@ +file(GLOB globbed *.cpp) + +add_mlir_dialect_library(MLIRHLSCpp + ${globbed} + + ADDITIONAL_HEADER_DIRS + ${PROJECT_SOURCE_DIR}/include/Dialect/HLSCpp + + DEPENDS + MLIRHLSCppIncGen + + LINK_LIBS PUBLIC + MLIRIR + ) diff --git a/lib/Dialect/HLSCpp/Dialect.cpp b/lib/Dialect/HLSCpp/Dialect.cpp new file mode 100644 index 0000000..7ce92ac --- /dev/null +++ b/lib/Dialect/HLSCpp/Dialect.cpp @@ -0,0 +1,19 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +//===----------------------------------------------------------------------===// + +#include "Dialect/HLSCpp/Dialect.h" +#include "Dialect/HLSCpp/Ops.h" + +using namespace mlir; +using namespace scalehls; +using namespace hlscpp; + +HLSCppDialect::HLSCppDialect(mlir::MLIRContext *context) + : Dialect(getDialectNamespace(), context) { + + addOperations< +#define GET_OP_LIST +#include "Dialect/HLSCpp/HLSCpp.cpp.inc" + >(); +} diff --git a/lib/Dialect/HLSCpp/Ops.cpp b/lib/Dialect/HLSCpp/Ops.cpp new file mode 100644 index 0000000..a4001ad --- /dev/null +++ b/lib/Dialect/HLSCpp/Ops.cpp @@ -0,0 +1,13 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +//===----------------------------------------------------------------------===// + +#include "Dialect/HLSCpp/Ops.h" +#include "mlir/IR/OpImplementation.h" + +using namespace mlir; +using namespace scalehls; +using namespace hlscpp; + +#define GET_OP_CLASSES +#include "Dialect/HLSCpp/HLSCpp.cpp.inc" diff --git a/lib/EmitHLSCpp/EmitHLSCpp.cpp b/lib/EmitHLSCpp/EmitHLSCpp.cpp index 77aa0f9..1da8b5e 100644 --- a/lib/EmitHLSCpp/EmitHLSCpp.cpp +++ b/lib/EmitHLSCpp/EmitHLSCpp.cpp @@ -19,8 +19,9 @@ #include "EmitHLSCpp.h" -using namespace mlir; using namespace std; +using namespace mlir; +using namespace scalehls; //===----------------------------------------------------------------------===// // Some Base Classes diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 86cf079..61da7ca 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,6 +7,7 @@ configure_lit_site_cfg( set(SCALEHLS_TEST_DEPENDS FileCheck count not + scalehls-opt scalehls-translate ) diff --git a/tools/scalehls-opt/CMakeLists.txt b/tools/scalehls-opt/CMakeLists.txt index e69de29..c190bde 100644 --- a/tools/scalehls-opt/CMakeLists.txt +++ b/tools/scalehls-opt/CMakeLists.txt @@ -0,0 +1,15 @@ +get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) +get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) + +set(LIBS + ${dialect_libs} + ${conversion_libs} + MLIROptLib + + MLIRHLSCpp + ) + +add_llvm_executable(scalehls-opt scalehls-opt.cpp) + +llvm_update_compile_flags(scalehls-opt) +target_link_libraries(scalehls-opt PRIVATE ${LIBS}) diff --git a/tools/scalehls-opt/scalehls-opt.cpp b/tools/scalehls-opt/scalehls-opt.cpp index e69de29..a91110f 100644 --- a/tools/scalehls-opt/scalehls-opt.cpp +++ b/tools/scalehls-opt/scalehls-opt.cpp @@ -0,0 +1,103 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +//===----------------------------------------------------------------------===// + +#include "mlir/IR/Dialect.h" +#include "mlir/IR/MLIRContext.h" +#include "mlir/InitAllDialects.h" +#include "mlir/InitAllPasses.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassManager.h" +#include "mlir/Support/FileUtilities.h" +#include "mlir/Support/MlirOptMain.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/ToolOutputFile.h" + +#include "Dialect/HLSCpp/Dialect.h" + +static llvm::cl::opt inputFilename(llvm::cl::Positional, + llvm::cl::desc(""), + llvm::cl::init("-")); + +static llvm::cl::opt + outputFilename("o", llvm::cl::desc("Output filename"), + llvm::cl::value_desc("filename"), llvm::cl::init("-")); + +static llvm::cl::opt 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 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 verifyPasses( + "verify-each", + llvm::cl::desc("Run the verifier after each transformation pass"), + llvm::cl::init(true)); + +static llvm::cl::opt allowUnregisteredDialects( + "allow-unregistered-dialect", + llvm::cl::desc("Allow operation with no registered dialects"), + llvm::cl::init(false)); + +static llvm::cl::opt + showDialects("show-dialects", + llvm::cl::desc("Print the list of registered dialects"), + llvm::cl::init(false)); + +int main(int argc, char **argv) { + mlir::registerAllDialects(); + mlir::registerAllPasses(); + + mlir::registerDialect(); + // TODO: Register HLSCpp passes here. + + llvm::InitLLVM y(argc, argv); + + // Register any pass manager command line options. + mlir::registerPassManagerCLOptions(); + mlir::PassPipelineCLParser passPipeline("", "Compiler passes to run"); + + // Parse pass names in main to ensure static initialization completed. + llvm::cl::ParseCommandLineOptions(argc, argv, + "MLIR modular optimizer driver\n"); + + if (showDialects) { + mlir::MLIRContext context; + llvm::outs() << "Registered Dialects:\n"; + for (mlir::Dialect *dialect : context.getRegisteredDialects()) { + llvm::outs() << dialect->getNamespace() << "\n"; + } + return 0; + } + + // Set up the input file. + std::string errorMessage; + auto file = mlir::openInputFile(inputFilename, &errorMessage); + if (!file) { + llvm::errs() << errorMessage << "\n"; + return 1; + } + + auto output = mlir::openOutputFile(outputFilename, &errorMessage); + if (!output) { + llvm::errs() << errorMessage << "\n"; + exit(1); + } + + if (failed(MlirOptMain(output->os(), std::move(file), passPipeline, + splitInputFile, verifyDiagnostics, verifyPasses, + allowUnregisteredDialects))) { + return 1; + } + // Keep the output file if the invocation of MlirOptMain was successful. + output->keep(); + return 0; +} diff --git a/tools/scalehls-translate/scalehls-translate.cpp b/tools/scalehls-translate/scalehls-translate.cpp index 74fa652..705dda4 100644 --- a/tools/scalehls-translate/scalehls-translate.cpp +++ b/tools/scalehls-translate/scalehls-translate.cpp @@ -42,7 +42,7 @@ int main(int argc, char **argv) { mlir::registerAllDialects(); mlir::registerAllTranslations(); - scalehls::registerHLSCppEmitterTranslation(); + mlir::scalehls::registerHLSCppEmitterTranslation(); llvm::InitLLVM y(argc, argv);