From a0999d67b0ec4c7cde7f87c1f838c1aaa30f8f4b Mon Sep 17 00:00:00 2001 From: Martin Erhart Date: Sat, 23 Nov 2024 19:02:36 +0000 Subject: [PATCH] [RTG][RTGTest] Add CAPI and a basic lowering pipeline --- include/circt-c/Dialect/RTG.h | 54 +++++++++ include/circt-c/Dialect/RTGTest.h | 38 +++++++ include/circt-c/RtgTool.h | 83 ++++++++++++++ .../circt/Dialect/RTGTest/IR/RTGTestTypes.td | 2 +- include/circt/Tools/rtgtool/RtgToolOptions.h | 107 ++++++++++++++++++ lib/CAPI/CMakeLists.txt | 1 + lib/CAPI/Dialect/CMakeLists.txt | 21 ++++ lib/CAPI/Dialect/RTG.cpp | 66 +++++++++++ lib/CAPI/Dialect/RTGTest.cpp | 32 ++++++ lib/CAPI/RtgTool/CMakeLists.txt | 7 ++ lib/CAPI/RtgTool/RtgTool.cpp | 100 ++++++++++++++++ lib/Tools/CMakeLists.txt | 1 + lib/Tools/rtgtool/CMakeLists.txt | 11 ++ lib/Tools/rtgtool/RtgToolOptions.cpp | 40 +++++++ test/CAPI/CMakeLists.txt | 40 +++++++ test/CAPI/rtg-pipelines.c | 58 ++++++++++ test/CAPI/rtg.c | 70 ++++++++++++ test/CAPI/rtgtest.c | 33 ++++++ test/CMakeLists.txt | 3 + test/lit.cfg.py | 8 +- 20 files changed, 771 insertions(+), 4 deletions(-) create mode 100644 include/circt-c/Dialect/RTG.h create mode 100644 include/circt-c/Dialect/RTGTest.h create mode 100644 include/circt-c/RtgTool.h create mode 100644 include/circt/Tools/rtgtool/RtgToolOptions.h create mode 100644 lib/CAPI/Dialect/RTG.cpp create mode 100644 lib/CAPI/Dialect/RTGTest.cpp create mode 100644 lib/CAPI/RtgTool/CMakeLists.txt create mode 100644 lib/CAPI/RtgTool/RtgTool.cpp create mode 100644 lib/Tools/rtgtool/CMakeLists.txt create mode 100644 lib/Tools/rtgtool/RtgToolOptions.cpp create mode 100644 test/CAPI/rtg-pipelines.c create mode 100644 test/CAPI/rtg.c create mode 100644 test/CAPI/rtgtest.c diff --git a/include/circt-c/Dialect/RTG.h b/include/circt-c/Dialect/RTG.h new file mode 100644 index 000000000000..0fd3a011beea --- /dev/null +++ b/include/circt-c/Dialect/RTG.h @@ -0,0 +1,54 @@ +//===- RTG.h - C interface for the for RTG dialect ----------------*- C -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_C_DIALECT_RTG_H +#define CIRCT_C_DIALECT_RTG_H + +#include "mlir-c/IR.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(RTG, rtg); +MLIR_CAPI_EXPORTED void registerRTGPasses(void); + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +/// If the type is an RTG sequence. +MLIR_CAPI_EXPORTED bool rtgTypeIsASequence(MlirType type); + +/// Creates an RTG sequence type in the context. +MLIR_CAPI_EXPORTED MlirType rtgSequenceTypeGet(MlirContext ctxt); + +/// If the type is an RTG set. +MLIR_CAPI_EXPORTED bool rtgTypeIsASet(MlirType type); + +/// Creates an RTG set type in the context. +MLIR_CAPI_EXPORTED MlirType rtgSetTypeGet(MlirType elementType); + +/// If the type is an RTG dict. +MLIR_CAPI_EXPORTED bool rtgTypeIsADict(MlirType type); + +/// Creates an RTG dict type in the context. +MLIR_CAPI_EXPORTED MlirType rtgDictTypeGet(MlirContext ctxt, + intptr_t numEntries, + MlirAttribute const *entryNames, + MlirType const *entryTypes); + +#ifdef __cplusplus +} +#endif + +#endif // CIRCT_C_DIALECT_RTG_H diff --git a/include/circt-c/Dialect/RTGTest.h b/include/circt-c/Dialect/RTGTest.h new file mode 100644 index 000000000000..0462795588a0 --- /dev/null +++ b/include/circt-c/Dialect/RTGTest.h @@ -0,0 +1,38 @@ +//===- RTGTest.h - C interface for the for RTGTest dialect --------*- C -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_C_DIALECT_RTGTEST_H +#define CIRCT_C_DIALECT_RTGTEST_H + +#include "mlir-c/IR.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(RTGTest, rtgtest); + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +/// If the type is an RTGTest CPUType. +MLIR_CAPI_EXPORTED bool rtgtestTypeIsACPU(MlirType type); + +/// Creates an RTGTest CPU type in the context. +MLIR_CAPI_EXPORTED MlirType rtgtestCPUTypeGet(MlirContext ctxt); + +#ifdef __cplusplus +} +#endif + +#endif // CIRCT_C_DIALECT_RTGTEST_H diff --git a/include/circt-c/RtgTool.h b/include/circt-c/RtgTool.h new file mode 100644 index 000000000000..8c0c8384efab --- /dev/null +++ b/include/circt-c/RtgTool.h @@ -0,0 +1,83 @@ +//===-- circt-c/RtgTool.h - C API for the rtgtool -----------------*- C -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_C_RTGTOOL_H +#define CIRCT_C_RTGTOOL_H + +#include "mlir-c/Pass.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//===----------------------------------------------------------------------===// +// Tool Options API. +//===----------------------------------------------------------------------===// + +#define DEFINE_C_API_STRUCT(name, storage) \ + struct name { \ + storage *ptr; \ + }; \ + typedef struct name name + +DEFINE_C_API_STRUCT(CirctRtgToolOptions, void); + +#undef DEFINE_C_API_STRUCT + +// NOLINTNEXTLINE(modernize-use-using) +typedef enum CiretRtgToolOutputFormat { + CIRCT_RTGTOOL_OUTPUT_FORMAT_MLIR, + CIRCT_RTGTOOL_OUTPUT_FORMAT_ELABORATED_MLIR, + CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM, +} CirctRtgToolOutputFormat; + +MLIR_CAPI_EXPORTED CirctRtgToolOptions circtRtgToolOptionsCreateDefault(void); +MLIR_CAPI_EXPORTED void circtRtgToolOptionsDestroy(CirctRtgToolOptions options); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetOutputFormat(CirctRtgToolOptions options, + CirctRtgToolOutputFormat format); + +MLIR_CAPI_EXPORTED void circtRtgToolOptionsSetSeed(CirctRtgToolOptions options, + unsigned seed); +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsUnsetSeed(CirctRtgToolOptions options); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetVerifyPasses(CirctRtgToolOptions options, bool enable); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options, + bool enable); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetDebugMode(CirctRtgToolOptions options, bool enable); + +MLIR_CAPI_EXPORTED void circtRtgToolOptionsSetUnsupportedInstructions( + CirctRtgToolOptions options, unsigned numInstr, + const char **unsupportedInstructions); + +MLIR_CAPI_EXPORTED void circtRtgToolOptionsAddUnsupportedInstruction( + CirctRtgToolOptions options, const char *unsupportedInstruction); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetUnsupportedInstructionsFile(CirctRtgToolOptions options, + const char *filename); + +//===----------------------------------------------------------------------===// +// Pipeline Population API. +//===----------------------------------------------------------------------===// + +MLIR_CAPI_EXPORTED void +circtRtgToolRandomizerPipeline(MlirPassManager pm, CirctRtgToolOptions options); + +#ifdef __cplusplus +} +#endif + +#endif // CIRCT_C_RTGTOOL_H diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td index 8351cd8b9661..3db49151a2f1 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td +++ b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td @@ -20,7 +20,7 @@ include "mlir/IR/AttrTypeBase.td" class RTGTestTypeDef traits = []> : TypeDef; -def CPUType : RTGTestTypeDef<"cpu", [ContextResourceTypeInterface]> { +def CPUType : RTGTestTypeDef<"CPU", [ContextResourceTypeInterface]> { let summary = "handle to a specific CPU"; let description = [{ This type implements a specific context resource to test RTG operations diff --git a/include/circt/Tools/rtgtool/RtgToolOptions.h b/include/circt/Tools/rtgtool/RtgToolOptions.h new file mode 100644 index 000000000000..8af4847e19fe --- /dev/null +++ b/include/circt/Tools/rtgtool/RtgToolOptions.h @@ -0,0 +1,107 @@ +//===- RtgToolOptions.h - Configuration Options for rtgtool -----*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This header file defines configuration options for the rtgtool. +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_TOOLS_RTGTOOL_RTGTOOLOPTIONS_H +#define CIRCT_TOOLS_RTGTOOL_RTGTOOLOPTIONS_H + +#include "circt/Support/LLVM.h" +#include "mlir/Pass/PassManager.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include + +namespace circt { +namespace rtg { + +/// The set of options used to control the behavior of the RTG tool. +class RtgToolOptions { +public: + enum class OutputFormat { MLIR, ElaboratedMLIR, ASM }; + + void setOutputFormat(OutputFormat format) { outputFormat = format; } + OutputFormat getOutputFormat() const { return outputFormat; } + + RtgToolOptions &setSeed(unsigned seed) { + this->seed = seed; + return *this; + } + RtgToolOptions &unsetSeed() { + this->seed = std::nullopt; + return *this; + } + bool hasSeed() const { return seed != std::nullopt; } + unsigned getSeed() const { + assert(hasSeed()); + return *seed; + } + + RtgToolOptions &setVerifyPasses(bool enable) { + verifyPasses = enable; + return *this; + } + bool getVerifyPasses() const { return verifyPasses; } + + RtgToolOptions &setVerbosePassExecution(bool enable) { + verbosePassExecution = enable; + return *this; + } + bool getVerbosePassExecution() const { return verbosePassExecution; } + + RtgToolOptions &setDebugMode(bool enable) { + debugMode = enable; + return *this; + } + bool getDebugMode() const { return debugMode; } + + RtgToolOptions &setUnsupportedInstructions(SmallVector &&instr) { + unsupportedInstructions = instr; + return *this; + } + RtgToolOptions &setUnsupportedInstructions(ArrayRef instr) { + unsupportedInstructions = SmallVector(instr); + return *this; + } + RtgToolOptions &addUnsupportedInstruction(const std::string &instr) { + unsupportedInstructions.push_back(instr); + return *this; + } + ArrayRef getUnsupportedInstructions() const { + return unsupportedInstructions; + } + + RtgToolOptions &setUnsupportedInstructionsFile(StringRef filename) { + unsupportedInstructionsFile = filename; + return *this; + } + std::string getUnsupportedInstructionsFile() const { + return unsupportedInstructionsFile; + } + +private: + OutputFormat outputFormat = OutputFormat::ElaboratedMLIR; + std::optional seed = std::nullopt; + bool verifyPasses = true; + bool verbosePassExecution = false; + bool debugMode = false; + SmallVector unsupportedInstructions; + std::string unsupportedInstructionsFile; +}; + +/// Populates the passes necessary to lower IR with RTG randomization operations +/// to fully elaborated IR (i.e., IR without random constructs). +void populateRandomizerPipeline(mlir::PassManager &pm, + const RtgToolOptions &options); + +} // namespace rtg +} // namespace circt + +#endif // CIRCT_TOOLS_RTGTOOL_RTGTOOLOPTIONS_H diff --git a/lib/CAPI/CMakeLists.txt b/lib/CAPI/CMakeLists.txt index 5c7865400325..d9ca6a0fe83b 100644 --- a/lib/CAPI/CMakeLists.txt +++ b/lib/CAPI/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(ExportFIRRTL) add_subdirectory(ExportVerilog) add_subdirectory(Dialect) add_subdirectory(Firtool) +add_subdirectory(RtgTool) diff --git a/lib/CAPI/Dialect/CMakeLists.txt b/lib/CAPI/Dialect/CMakeLists.txt index 365e74c7c63d..82196f3a774d 100644 --- a/lib/CAPI/Dialect/CMakeLists.txt +++ b/lib/CAPI/Dialect/CMakeLists.txt @@ -16,6 +16,8 @@ set(LLVM_OPTIONAL_SOURCES MSFT.cpp Moore.cpp OM.cpp + RTG.cpp + RTGTest.cpp SV.cpp Seq.cpp Verif.cpp @@ -119,6 +121,25 @@ add_circt_public_c_api_library(CIRCTCAPIOM CIRCTOMEvaluator ) +add_circt_public_c_api_library(CIRCTCAPIRTG + RTG.cpp + + LINK_LIBS PUBLIC + MLIRCAPIIR + CIRCTRTGDialect + CIRCTRTGTransforms +) + +if(CIRCT_INCLUDE_TESTS) + add_circt_public_c_api_library(CIRCTCAPIRTGTest + RTGTest.cpp + + LINK_LIBS PUBLIC + MLIRCAPIIR + CIRCTRTGTestDialect + ) +endif() + add_circt_public_c_api_library(CIRCTCAPISeq Seq.cpp diff --git a/lib/CAPI/Dialect/RTG.cpp b/lib/CAPI/Dialect/RTG.cpp new file mode 100644 index 000000000000..f860d94e35c7 --- /dev/null +++ b/lib/CAPI/Dialect/RTG.cpp @@ -0,0 +1,66 @@ +//===- RTG.cpp - C interface for the RTG dialect --------------------------===// +// +// 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 "circt-c/Dialect/RTG.h" +#include "circt/Dialect/RTG/IR/RTGDialect.h" +#include "circt/Dialect/RTG/IR/RTGTypes.h" + +#include "circt/Dialect/RTG/Transforms/RTGPasses.h" +#include "mlir/CAPI/Registration.h" + +using namespace circt; +using namespace circt::rtg; + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(RTG, rtg, RTGDialect) +void registerRTGPasses() { registerPasses(); } + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +// SequenceType +//===----------------------------------------------------------------------===// + +bool rtgTypeIsASequence(MlirType type) { + return isa(unwrap(type)); +} + +MlirType rtgSequenceTypeGet(MlirContext ctxt) { + return wrap(SequenceType::get(unwrap(ctxt))); +} + +// SetType +//===----------------------------------------------------------------------===// + +bool rtgTypeIsASet(MlirType type) { return isa(unwrap(type)); } + +MlirType rtgSetTypeGet(MlirType elementType) { + auto ty = unwrap(elementType); + return wrap(SetType::get(ty.getContext(), ty)); +} + +// DictType +//===----------------------------------------------------------------------===// + +bool rtgTypeIsADict(MlirType type) { return isa(unwrap(type)); } + +MlirType rtgDictTypeGet(MlirContext ctxt, intptr_t numEntries, + MlirAttribute const *entryNames, + MlirType const *entryTypes) { + SmallVector names; + SmallVector types; + for (unsigned i = 0; i < numEntries; ++i) { + names.push_back(cast(unwrap(entryNames[i]))); + types.push_back(unwrap(entryTypes[i])); + } + return wrap(DictType::get(unwrap(ctxt), names, types)); +} diff --git a/lib/CAPI/Dialect/RTGTest.cpp b/lib/CAPI/Dialect/RTGTest.cpp new file mode 100644 index 000000000000..a4564b94e08b --- /dev/null +++ b/lib/CAPI/Dialect/RTGTest.cpp @@ -0,0 +1,32 @@ +//===- RTGTest.cpp - C interface for the RTGTest dialect ------------------===// +// +// 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 "circt-c/Dialect/RTGTest.h" +#include "circt/Dialect/RTGTest/IR/RTGTestDialect.h" +#include "circt/Dialect/RTGTest/IR/RTGTestTypes.h" + +#include "mlir/CAPI/Registration.h" + +using namespace circt; +using namespace circt::rtgtest; + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(RTGTest, rtgtest, RTGTestDialect) + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +bool rtgtestTypeIsACPU(MlirType type) { return isa(unwrap(type)); } + +MlirType rtgtestCPUTypeGet(MlirContext ctxt) { + return wrap(CPUType::get(unwrap(ctxt))); +} diff --git a/lib/CAPI/RtgTool/CMakeLists.txt b/lib/CAPI/RtgTool/CMakeLists.txt new file mode 100644 index 000000000000..8369bc43e78f --- /dev/null +++ b/lib/CAPI/RtgTool/CMakeLists.txt @@ -0,0 +1,7 @@ +add_circt_public_c_api_library(CIRCTCAPIRtgTool + RtgTool.cpp + + LINK_LIBS PUBLIC + CIRCTRtgToolLib + MLIRCAPIIR +) diff --git a/lib/CAPI/RtgTool/RtgTool.cpp b/lib/CAPI/RtgTool/RtgTool.cpp new file mode 100644 index 000000000000..5414954f245b --- /dev/null +++ b/lib/CAPI/RtgTool/RtgTool.cpp @@ -0,0 +1,100 @@ +//===- RtgTool.cpp - C Interface for the rtgtool --------------------------===// +// +// 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 "circt-c/RtgTool.h" + +#include "circt/Tools/rtgtool/RtgToolOptions.h" +#include "mlir/CAPI/Pass.h" +#include + +using namespace circt; +using namespace circt::rtg; + +//===----------------------------------------------------------------------===// +// Tool Option API. +//===----------------------------------------------------------------------===// + +DEFINE_C_API_PTR_METHODS(CirctRtgToolOptions, RtgToolOptions) + +CirctRtgToolOptions circtRtgToolOptionsCreateDefault() { + auto *options = new RtgToolOptions(); + return wrap(options); +} + +void circtRtgToolOptionsDestroy(CirctRtgToolOptions options) { + delete unwrap(options); +} + +void circtRtgToolOptionsSetOutputFormat(CirctRtgToolOptions options, + CirctRtgToolOutputFormat format) { + RtgToolOptions::OutputFormat converted; + switch (format) { + case CIRCT_RTGTOOL_OUTPUT_FORMAT_MLIR: + converted = RtgToolOptions::OutputFormat::MLIR; + break; + case CIRCT_RTGTOOL_OUTPUT_FORMAT_ELABORATED_MLIR: + converted = RtgToolOptions::OutputFormat::ElaboratedMLIR; + break; + case CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM: + converted = RtgToolOptions::OutputFormat::ASM; + break; + } + + unwrap(options)->setOutputFormat(converted); +} + +void circtRtgToolOptionsSetSeed(CirctRtgToolOptions options, unsigned seed) { + unwrap(options)->setSeed(seed); +} + +void circtRtgToolOptionsUnsetSeed(CirctRtgToolOptions options) { + unwrap(options)->unsetSeed(); +} + +void circtRtgToolOptionsSetVerifyPasses(CirctRtgToolOptions options, + bool enable) { + unwrap(options)->setVerifyPasses(enable); +} + +void circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options, + bool enable) { + unwrap(options)->setVerbosePassExecution(enable); +} + +void circtRtgToolOptionsSetDebugMode(CirctRtgToolOptions options, bool enable) { + unwrap(options)->setDebugMode(enable); +} + +void circtRtgToolOptionsSetUnsupportedInstructions( + CirctRtgToolOptions options, unsigned numInstr, + const char **unsupportedInstructions) { + SmallVector instr; + for (unsigned i = 0; i < numInstr; ++i) + instr.push_back(std::string(unsupportedInstructions[i])); + unwrap(options)->setUnsupportedInstructions(std::move(instr)); +} + +void circtRtgToolOptionsAddUnsupportedInstruction( + CirctRtgToolOptions options, const char *unsupportedInstruction) { + unwrap(options)->addUnsupportedInstruction( + std::string(unsupportedInstruction)); +} + +void circtRtgToolOptionsSetUnsupportedInstructionsFile( + CirctRtgToolOptions options, const char *filename) { + unwrap(options)->setUnsupportedInstructionsFile(std::string(filename)); +} + +//===----------------------------------------------------------------------===// +// Pipeline Population API. +//===----------------------------------------------------------------------===// + +void circtRtgToolRandomizerPipeline(MlirPassManager pm, + CirctRtgToolOptions options) { + populateRandomizerPipeline(*unwrap(pm), *unwrap(options)); +} diff --git a/lib/Tools/CMakeLists.txt b/lib/Tools/CMakeLists.txt index aa66538d8bff..90e6c429baa0 100644 --- a/lib/Tools/CMakeLists.txt +++ b/lib/Tools/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(circt-bmc) add_subdirectory(circt-lec) +add_subdirectory(rtgtool) diff --git a/lib/Tools/rtgtool/CMakeLists.txt b/lib/Tools/rtgtool/CMakeLists.txt new file mode 100644 index 000000000000..0122219dd6a1 --- /dev/null +++ b/lib/Tools/rtgtool/CMakeLists.txt @@ -0,0 +1,11 @@ +add_circt_library(CIRCTRtgToolLib + RtgToolOptions.cpp + + LINK_LIBS PUBLIC + CIRCTRTGTransforms + CIRCTSupport + + MLIRIR + MLIRPass + MLIRTransforms +) diff --git a/lib/Tools/rtgtool/RtgToolOptions.cpp b/lib/Tools/rtgtool/RtgToolOptions.cpp new file mode 100644 index 000000000000..4502fbf90d66 --- /dev/null +++ b/lib/Tools/rtgtool/RtgToolOptions.cpp @@ -0,0 +1,40 @@ +//===- RtgToolOptions.cpp -------------------------------------------------===// +// +// 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 "circt/Tools/rtgtool/RtgToolOptions.h" +#include "circt/Dialect/RTG/Transforms/RTGPasses.h" +#include "circt/Support/Passes.h" +#include "mlir/Transforms/Passes.h" + +using namespace circt; +using namespace circt::rtg; + +//===----------------------------------------------------------------------===// +// RTG Tool Pipelines +//===----------------------------------------------------------------------===// + +void rtg::populateRandomizerPipeline(mlir::PassManager &pm, + const RtgToolOptions &options) { + pm.enableVerifier(options.getVerifyPasses()); + + if (options.getVerbosePassExecution()) + pm.addInstrumentation( + std::make_unique>( + "rtgtool")); + + pm.addPass(createSimpleCanonicalizerPass()); + if (options.getOutputFormat() != RtgToolOptions::OutputFormat::MLIR) { + ElaborationOptions elabOptions; + if (options.hasSeed()) + elabOptions.seed = options.getSeed(); + elabOptions.debugMode = options.getDebugMode(); + pm.addPass(createElaborationPass(elabOptions)); + pm.addPass(mlir::createCSEPass()); + pm.addPass(createSimpleCanonicalizerPass()); + } +} diff --git a/test/CAPI/CMakeLists.txt b/test/CAPI/CMakeLists.txt index ba59ddecb483..20a09b422db3 100644 --- a/test/CAPI/CMakeLists.txt +++ b/test/CAPI/CMakeLists.txt @@ -69,3 +69,43 @@ target_link_libraries(circt-capi-arc-test MLIRCAPIIR CIRCTCAPIArc ) + +add_llvm_executable(circt-capi-rtg-pipelines-test + PARTIAL_SOURCES_INTENDED + rtg-pipelines.c +) +llvm_update_compile_flags(circt-capi-rtg-pipelines-test) + +target_link_libraries(circt-capi-rtg-pipelines-test + PRIVATE + + MLIRCAPIIR + CIRCTCAPIRTG + CIRCTCAPIRtgTool +) + +add_llvm_executable(circt-capi-rtg-test + PARTIAL_SOURCES_INTENDED + rtg.c +) +llvm_update_compile_flags(circt-capi-rtg-test) + +target_link_libraries(circt-capi-rtg-test + PRIVATE + + MLIRCAPIIR + CIRCTCAPIRTG +) + +add_llvm_executable(circt-capi-rtgtest-test + PARTIAL_SOURCES_INTENDED + rtgtest.c +) +llvm_update_compile_flags(circt-capi-rtgtest-test) + +target_link_libraries(circt-capi-rtgtest-test + PRIVATE + + MLIRCAPIIR + CIRCTCAPIRTGTest +) diff --git a/test/CAPI/rtg-pipelines.c b/test/CAPI/rtg-pipelines.c new file mode 100644 index 000000000000..f183f4ba547b --- /dev/null +++ b/test/CAPI/rtg-pipelines.c @@ -0,0 +1,58 @@ +//===- rtg-pipelines.c - RTG pipeline CAPI unit tests ---------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// RUN: circt-capi-rtg-pipelines-test 2>&1 | FileCheck %s + +#include + +#include "circt-c/Dialect/RTG.h" +#include "circt-c/RtgTool.h" + +int main(int argc, char **argv) { + MlirContext ctx = mlirContextCreate(); + mlirDialectHandleRegisterDialect(mlirGetDialectHandle__rtg__(), ctx); + + MlirModule moduleOp = mlirModuleCreateParse( + ctx, mlirStringRefCreateFromCString("rtg.sequence @seq {\n" + "}\n" + "rtg.test @test : !rtg.dict<> {\n" + " %0 = rtg.sequence_closure @seq\n" + " rtg.invoke_sequence %0\n" + "}\n")); + if (mlirModuleIsNull(moduleOp)) { + printf("ERROR: Could not parse.\n"); + mlirContextDestroy(ctx); + return 1; + } + + MlirPassManager pm = mlirPassManagerCreate(ctx); + CirctRtgToolOptions options = circtRtgToolOptionsCreateDefault(); + circtRtgToolOptionsSetDebugMode(options, true); + circtRtgToolRandomizerPipeline(pm, options); + + MlirOperation op = mlirModuleGetOperation(moduleOp); + + if (mlirLogicalResultIsFailure(mlirPassManagerRunOnOp(pm, op))) { + printf("ERROR: Pipeline run failed.\n"); + mlirModuleDestroy(moduleOp); + mlirPassManagerDestroy(pm); + circtRtgToolOptionsDestroy(options); + mlirContextDestroy(ctx); + return 1; + } + + // CHECK-LABEL: rtg.test @test + // CHECK-NEXT: } + mlirOperationDump(op); + + mlirModuleDestroy(moduleOp); + mlirPassManagerDestroy(pm); + circtRtgToolOptionsDestroy(options); + mlirContextDestroy(ctx); + return 0; +} diff --git a/test/CAPI/rtg.c b/test/CAPI/rtg.c new file mode 100644 index 000000000000..aac18f4be43e --- /dev/null +++ b/test/CAPI/rtg.c @@ -0,0 +1,70 @@ +//===- rtg.c - RTG Dialect CAPI unit tests --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// RUN: circt-capi-rtg-test 2>&1 | FileCheck %s + +#include + +#include "circt-c/Dialect/RTG.h" +#include "mlir-c/BuiltinAttributes.h" +#include "mlir-c/BuiltinTypes.h" + +static void testSequenceType(MlirContext ctx) { + MlirType sequenceTy = rtgSequenceTypeGet(ctx); + + // CHECK: is_sequence + fprintf(stderr, rtgTypeIsASequence(sequenceTy) ? "is_sequence\n" + : "isnot_sequence\n"); + // CHECK: !rtg.sequence + mlirTypeDump(sequenceTy); +} + +static void testSetType(MlirContext ctx) { + MlirType elTy = mlirIntegerTypeGet(ctx, 32); + MlirType setTy = rtgSetTypeGet(elTy); + + // CHECK: is_set + fprintf(stderr, rtgTypeIsASet(setTy) ? "is_set\n" : "isnot_set\n"); + // CHECK: !rtg.set + mlirTypeDump(setTy); +} + +static void testDictType(MlirContext ctx) { + MlirType elTy = mlirIntegerTypeGet(ctx, 32); + MlirAttribute name0 = + mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("entry0")); + MlirAttribute name1 = + mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("entry1")); + const MlirAttribute names[] = {name0, name1}; + const MlirType types[] = {elTy, elTy}; + MlirType dictTy = rtgDictTypeGet(ctx, 2, names, types); + + // CHECK: is_dict + fprintf(stderr, rtgTypeIsADict(dictTy) ? "is_dict\n" : "isnot_dict\n"); + // CHECK: !rtg.dict + mlirTypeDump(dictTy); + + MlirType emptyDictTy = rtgDictTypeGet(ctx, 0, NULL, NULL); + // CHECK: is_dict + fprintf(stderr, rtgTypeIsADict(dictTy) ? "is_dict\n" : "isnot_dict\n"); + // CHECK: !rtg.dict<> + mlirTypeDump(emptyDictTy); +} + +int main(int argc, char **argv) { + MlirContext ctx = mlirContextCreate(); + mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtg__(), ctx); + + testSequenceType(ctx); + testSetType(ctx); + testDictType(ctx); + + mlirContextDestroy(ctx); + + return 0; +} diff --git a/test/CAPI/rtgtest.c b/test/CAPI/rtgtest.c new file mode 100644 index 000000000000..e14f27667a62 --- /dev/null +++ b/test/CAPI/rtgtest.c @@ -0,0 +1,33 @@ +//===- rtgtest.c - RTGTest Dialect CAPI unit tests ------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// RUN: circt-capi-rtgtest-test 2>&1 | FileCheck %s + +#include + +#include "circt-c/Dialect/RTGTest.h" + +static void testCPUType(MlirContext ctx) { + MlirType cpuTy = rtgtestCPUTypeGet(ctx); + + // CHECK: is_cpu + fprintf(stderr, rtgtestTypeIsACPU(cpuTy) ? "is_cpu\n" : "isnot_cpu\n"); + // CHECK: !rtgtest.cpu + mlirTypeDump(cpuTy); +} + +int main(int argc, char **argv) { + MlirContext ctx = mlirContextCreate(); + mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtgtest__(), ctx); + + testCPUType(ctx); + + mlirContextDestroy(ctx); + + return 0; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3bc76409af63..235d7222e9ba 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,6 +22,9 @@ set(CIRCT_TEST_DEPENDS circt-capi-om-test circt-capi-firrtl-test circt-capi-firtool-test + circt-capi-rtg-pipelines-test + circt-capi-rtg-test + circt-capi-rtgtest-test circt-as circt-dis circt-lec diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 911bff304966..cee2cd4b4f31 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -59,9 +59,11 @@ ] tools = [ 'arcilator', 'circt-as', 'circt-capi-ir-test', 'circt-capi-om-test', - 'circt-capi-firrtl-test', 'circt-capi-firtool-test', 'circt-dis', - 'circt-lec', 'circt-reduce', 'circt-synth', 'circt-test', 'circt-translate', - 'firtool', 'hlstool', 'om-linker', 'ibistool' + 'circt-capi-firrtl-test', 'circt-capi-firtool-test', + 'circt-capi-rtg-pipelines-test', 'circt-capi-rtg-test', + 'circt-capi-rtgtest-test', 'circt-dis', 'circt-lec', 'circt-reduce', + 'circt-synth', 'circt-test', 'circt-translate', 'firtool', 'hlstool', + 'om-linker', 'ibistool' ] if "CIRCT_OPT_CHECK_IR_ROUNDTRIP" in os.environ: