[RTG] Rely on textual pass pipeline in Python and CAPI

The textual pass pipeline has a bit more overhead due to the string parsing, but it reduces the required maintenance as we don't have to write CAPI and Python bindings for all the pass options.
This commit is contained in:
Martin Erhart 2025-07-29 17:06:33 +01:00 committed by Martin Erhart
parent 327def313c
commit 175e30d32f
20 changed files with 44 additions and 726 deletions

View File

@ -12,7 +12,7 @@ import os
from types import ModuleType
import pyrtg
from pyrtg.circt import ir, passmanager, rtgtool_support, register_dialects
from pyrtg.circt import ir, passmanager, register_dialects
class InputFormat(Enum):
@ -25,22 +25,15 @@ class InputFormat(Enum):
PYTHON = 'py'
def to_output_format(format: str) -> rtgtool_support.OutputFormat:
class OutputFormat(Enum):
"""
Convert the CLI argument choice string of the output format to the enum
understood by the CIRCT python bindings and thus also the C++ backend.
The output formats accepted by this tool. The enum's values correspond to the
selectable CLI argument choice, but not necessarily the file extension.
"""
if format == "mlir":
return rtgtool_support.OutputFormat.MLIR
if format == "elaborated":
return rtgtool_support.OutputFormat.ELABORATED_MLIR
if format == "asm":
return rtgtool_support.OutputFormat.ASM
assert False, "all output format options must be handled above"
MLIR = 'mlir'
ELABORATED = 'elaborated'
ASM = 'asm'
def parse_args() -> argparse.Namespace:
@ -64,18 +57,14 @@ def parse_args() -> argparse.Namespace:
type=bool,
default=True,
help="Run the verifier after each transformation pass")
parser.add_argument("--verbose-pass-executions",
type=bool,
default=False,
help="Log executions of toplevel module passes")
parser.add_argument("--input-format",
type=InputFormat,
choices=list(InputFormat),
help="Input Format")
parser.add_argument("--output-format",
type=str,
choices=output_format_choices,
default="asm",
type=OutputFormat,
choices=list(OutputFormat),
default=OutputFormat.ASM,
help="Output Format")
parser.add_argument(
"-o",
@ -88,6 +77,13 @@ def parse_args() -> argparse.Namespace:
type=bool,
default=True,
help="Lower memories as immediates")
parser.add_argument(
"--mlir-timing",
type=bool,
nargs='?',
default=False,
const=True,
help="Print pass timings of the MLIR compilation pipeline")
args = parser.parse_args()
@ -142,17 +138,27 @@ def compile(mlir_module: ir.Module, args: argparse.Namespace) -> None:
Populate and run the MLIR compilation pipeline according to the CLI arguments.
"""
pm = passmanager.PassManager()
options = rtgtool_support.Options(
seed=args.seed,
verify_passes=args.verify_passes,
verbose_pass_execution=args.verbose_pass_executions,
output_format=to_output_format(args.output_format),
output_path=args.output_path,
split_output=False,
memories_as_immediates=args.memories_as_immediates)
rtgtool_support.populate_randomizer_pipeline(pm, options)
pm.run(mlir_module.operation)
def get_populated_pm():
pm = passmanager.PassManager()
pm.enable_verifier(args.verify_passes)
if args.mlir_timing:
pm.enable_timing()
pm.add('any(cse,canonicalize)')
if args.output_format == OutputFormat.MLIR:
return pm
pm.add(
f'rtg-randomization-pipeline{{seed={args.seed} memories-as-immediates={str(args.memories_as_immediates).lower()}}}'
)
if args.output_format == OutputFormat.ELABORATED:
return pm
pm.add(f'rtg-emit-isa-assembly{{path={args.output_path}}}')
return pm
get_populated_pm().run(mlir_module.operation)
def print_output(mlir_module: ir.Module, args: argparse.Namespace) -> None:
@ -161,7 +167,7 @@ def print_output(mlir_module: ir.Module, args: argparse.Namespace) -> None:
"""
# The assembly emitter does print to the desired output itself, so we don't need to do anything here.
if to_output_format(args.output_format) == rtgtool_support.OutputFormat.ASM:
if args.output_format == OutputFormat.ASM:
return
if len(args.output_path) == 0:

View File

@ -1,89 +0,0 @@
//===-- 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(unsigned seed);
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
circtRtgToolOptionsSetVerifyPasses(CirctRtgToolOptions options, bool enable);
MLIR_CAPI_EXPORTED void
circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options,
bool enable);
MLIR_CAPI_EXPORTED void circtRtgToolOptionsSetUnsupportedInstructions(
CirctRtgToolOptions options, unsigned numInstr,
const void **unsupportedInstructions);
MLIR_CAPI_EXPORTED void circtRtgToolOptionsAddUnsupportedInstruction(
CirctRtgToolOptions options, const char *unsupportedInstruction);
MLIR_CAPI_EXPORTED void
circtRtgToolOptionsSetUnsupportedInstructionsFile(CirctRtgToolOptions options,
const char *filename);
MLIR_CAPI_EXPORTED void
circtRtgToolOptionsSetSplitOutput(CirctRtgToolOptions options, bool enable);
MLIR_CAPI_EXPORTED void
circtRtgToolOptionsSetOutputPath(CirctRtgToolOptions options, const char *path);
MLIR_CAPI_EXPORTED void
circtRtgToolOptionsSetMemoriesAsImmediates(CirctRtgToolOptions options,
bool enable);
//===----------------------------------------------------------------------===//
// Pipeline Population API.
//===----------------------------------------------------------------------===//
MLIR_CAPI_EXPORTED void
circtRtgToolRandomizerPipeline(MlirPassManager pm, CirctRtgToolOptions options);
#ifdef __cplusplus
}
#endif
#endif // CIRCT_C_RTGTOOL_H

View File

@ -1,114 +0,0 @@
//===- 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"
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 };
RtgToolOptions(unsigned seed) : seed(seed) {}
void setOutputFormat(OutputFormat format) { outputFormat = format; }
OutputFormat getOutputFormat() const { return outputFormat; }
RtgToolOptions &setSeed(unsigned seed) {
this->seed = seed;
return *this;
}
unsigned getSeed() const { 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 &setUnsupportedInstructions(SmallVector<std::string> &&instr) {
unsupportedInstructions = instr;
return *this;
}
RtgToolOptions &setUnsupportedInstructions(ArrayRef<std::string> instr) {
unsupportedInstructions = SmallVector<std::string>(instr);
return *this;
}
RtgToolOptions &addUnsupportedInstruction(const std::string &instr) {
unsupportedInstructions.push_back(instr);
return *this;
}
ArrayRef<std::string> getUnsupportedInstructions() const {
return unsupportedInstructions;
}
RtgToolOptions &setUnsupportedInstructionsFile(StringRef filename) {
unsupportedInstructionsFile = filename;
return *this;
}
std::string getUnsupportedInstructionsFile() const {
return unsupportedInstructionsFile;
}
RtgToolOptions &setSplitOutput(bool enable) {
splitOutput = enable;
return *this;
}
bool getSplitOutput() const { return splitOutput; }
RtgToolOptions &setOutputPath(StringRef path) {
outputPath = path;
return *this;
}
std::string getOutputPath() const { return outputPath; }
RtgToolOptions &setMemoriesAsImmediates(bool enable) {
memoriesAsImmediates = enable;
return *this;
}
bool getMemoriesAsImmediates() const { return memoriesAsImmediates; }
private:
OutputFormat outputFormat = OutputFormat::ElaboratedMLIR;
unsigned seed;
bool verifyPasses = true;
bool verbosePassExecution = false;
SmallVector<std::string> unsupportedInstructions;
std::string unsupportedInstructionsFile;
bool splitOutput = false;
std::string outputPath;
bool memoriesAsImmediates = true;
};
/// 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

View File

@ -6,7 +6,6 @@ import circt
from circt.dialects import rtg, rtgtest
from circt.ir import Context, Location, Module, InsertionPoint, Block, StringAttr, TypeAttr, IndexType
from circt.passmanager import PassManager
from circt import rtgtool_support as rtgtool
with Context() as ctx, Location.unknown():
circt.register_dialects(ctx)
@ -77,11 +76,7 @@ with Context() as ctx, Location.unknown():
print(m)
pm = PassManager()
options = rtgtool.Options(
seed=0,
output_format=rtgtool.OutputFormat.ELABORATED_MLIR,
)
rtgtool.populate_randomizer_pipeline(pm, options)
pm.add('rtg-randomization-pipeline{seed=0}')
pm.run(m.operation)
# CHECK: rtg.test @test_name_target() template "test_name" target @target {

View File

@ -1,46 +0,0 @@
# REQUIRES: bindings_python
# RUN: %PYTHON% %s %T && FileCheck %s --input-file=%T/test0_target.s --check-prefix=TEST0 && FileCheck %s --input-file=%T/test1_target.s --check-prefix=TEST1
import sys
import circt
from circt.dialects import rtg, rtgtest
from circt.ir import Context, Location, Module, InsertionPoint, Block, TypeAttr
from circt.passmanager import PassManager
from circt import rtgtool_support as rtgtool
# Tests the split_file option and that the strings of unsupported instructions
# are passed properly to the emission pass.
with Context() as ctx, Location.unknown():
circt.register_dialects(ctx)
m = Module.create()
with InsertionPoint(m.body):
test = rtg.TestOp('test0', 'test0', TypeAttr.get(rtg.DictType.get()))
block = Block.create_at_start(test.bodyRegion, [])
with InsertionPoint(block):
rtgtest.rv32i_ebreak()
test = rtg.TestOp('test1', 'test1', TypeAttr.get(rtg.DictType.get()))
block = Block.create_at_start(test.bodyRegion, [])
with InsertionPoint(block):
rtgtest.rv32i_ecall()
target = rtg.TargetOp('target', TypeAttr.get(rtg.DictType.get()))
block = Block.create_at_start(target.bodyRegion, [])
with InsertionPoint(block):
rtg.YieldOp([])
pm = PassManager()
options = rtgtool.Options(seed=0,
output_format=rtgtool.OutputFormat.ASM,
split_output=True,
unsupported_instructions=['rtgtest.rv32i.ebreak'],
output_path=sys.argv[1])
rtgtool.populate_randomizer_pipeline(pm, options)
pm.run(m.operation)
# TEST0: ebreak
# TEST0: .word 0x
# TEST1: ecall
print(m)

View File

@ -202,8 +202,6 @@ NB_MODULE(_circt, m) {
circt::python::populateDialectOMSubmodule(om);
nb::module_ rtg = m.def_submodule("_rtg", "RTG API");
circt::python::populateDialectRTGSubmodule(rtg);
nb::module_ rtgtool = m.def_submodule("_rtgtool", "RTGTool API");
circt::python::populateDialectRTGToolSubmodule(rtgtool);
#ifdef CIRCT_INCLUDE_TESTS
nb::module_ rtgtest = m.def_submodule("_rtgtest", "RTGTest API");
circt::python::populateDialectRTGTestSubmodule(rtgtest);

View File

@ -24,7 +24,6 @@ void populateDialectHWSubmodule(nanobind::module_ &m);
void populateDialectMSFTSubmodule(nanobind::module_ &m);
void populateDialectOMSubmodule(nanobind::module_ &m);
void populateDialectRTGSubmodule(nanobind::module_ &m);
void populateDialectRTGToolSubmodule(nanobind::module_ &m);
#ifdef CIRCT_INCLUDE_TESTS
void populateDialectRTGTestSubmodule(nanobind::module_ &m);
#endif

View File

@ -21,7 +21,6 @@ set(PYTHON_BINDINGS_SOURCES
MSFTModule.cpp
OMModule.cpp
RTGModule.cpp
RTGToolModule.cpp
SeqModule.cpp
SupportModule.cpp
SVModule.cpp
@ -50,7 +49,6 @@ set(PYTHON_BINDINGS_LINK_LIBS
CIRCTCAPIOM
CIRCTCAPIPipeline
CIRCTCAPIRTG
CIRCTCAPIRtgTool
CIRCTCAPISeq
CIRCTCAPISV
CIRCTCAPISupport
@ -103,7 +101,6 @@ declare_mlir_python_sources(CIRCTBindingsPythonSources.Support
ADD_TO_PARENT CIRCTBindingsPythonSources
SOURCES
support.py
rtgtool_support.py
)
################################################################################

View File

@ -1,155 +0,0 @@
//===- RTGToolModule.cpp - RTG Tool API nanobind module -------------------===//
//
// 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 "CIRCTModules.h"
#include "circt-c/RtgTool.h"
#include "mlir/Bindings/Python/NanobindAdaptors.h"
#include <nanobind/nanobind.h>
namespace nb = nanobind;
using namespace circt;
namespace {
/// Wrapper around an CirctRtgToolOptions.
class PyRtgToolOptions {
public:
PyRtgToolOptions(unsigned seed, CirctRtgToolOutputFormat outputFormat,
bool verifyPasses, bool verbosePassExecution,
const std::vector<std::string> &unsupportedInstructions,
const std::string &unsupportedInstructionsFile,
bool splitOutput, const std::string &outputPath,
bool memoriesAsImmediates)
: options(circtRtgToolOptionsCreateDefault(seed)) {
setOutputFormat(outputFormat);
setVerifyPasses(verifyPasses);
setVerbosePassExecution(verbosePassExecution);
setUnsupportedInstructions(unsupportedInstructions);
setUnsupportedInstructionsFile(unsupportedInstructionsFile);
setSplitOutput(splitOutput);
setOutputPath(outputPath);
setMemoriesAsImmediates(memoriesAsImmediates);
}
~PyRtgToolOptions() { circtRtgToolOptionsDestroy(options); }
operator CirctRtgToolOptions() const { return options; }
CirctRtgToolOptions get() const { return options; }
void setOutputFormat(CirctRtgToolOutputFormat format) {
circtRtgToolOptionsSetOutputFormat(options, format);
}
void setSeed(unsigned seed) { circtRtgToolOptionsSetSeed(options, seed); }
void setVerifyPasses(bool enable) {
circtRtgToolOptionsSetVerifyPasses(options, enable);
}
void setVerbosePassExecution(bool enable) {
circtRtgToolOptionsSetVerbosePassExecution(options, enable);
}
void
setUnsupportedInstructions(const std::vector<std::string> &instructions) {
circtRtgToolOptionsSetUnsupportedInstructions(
options, instructions.size(),
reinterpret_cast<const void **>(
const_cast<std::string *>(instructions.data())));
}
void addUnsupportedInstruction(const std::string &instruction) {
circtRtgToolOptionsAddUnsupportedInstruction(options, instruction.c_str());
}
void setUnsupportedInstructionsFile(const std::string &filename) {
circtRtgToolOptionsSetUnsupportedInstructionsFile(options,
filename.c_str());
}
void setSplitOutput(bool enable) {
circtRtgToolOptionsSetSplitOutput(options, enable);
}
void setOutputPath(const std::string &path) {
circtRtgToolOptionsSetOutputPath(options, path.c_str());
}
void setMemoriesAsImmediates(bool enable) {
circtRtgToolOptionsSetMemoriesAsImmediates(options, enable);
}
private:
CirctRtgToolOptions options;
};
} // namespace
/// Populate the rtgtool python module.
void circt::python::populateDialectRTGToolSubmodule(nb::module_ &m) {
m.doc() = "RTGTool Python native extension";
nb::enum_<CirctRtgToolOutputFormat>(m, "OutputFormat")
.value("MLIR", CIRCT_RTGTOOL_OUTPUT_FORMAT_MLIR)
.value("ELABORATED_MLIR", CIRCT_RTGTOOL_OUTPUT_FORMAT_ELABORATED_MLIR)
.value("ASM", CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM);
nb::class_<PyRtgToolOptions>(m, "Options")
.def(nb::init<unsigned, CirctRtgToolOutputFormat, bool, bool,
const std::vector<std::string> &, const std::string &, bool,
const std::string &, bool>(),
nb::arg("seed"),
nb::arg("output_format") = CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM,
nb::arg("verify_passes") = true,
nb::arg("verbose_pass_execution") = false,
nb::arg("unsupported_instructions") = std::vector<const char *>(),
nb::arg("unsupported_instructions_file") = "",
nb::arg("split_output") = false, nb::arg("output_path") = "",
nb::arg("memories_as_immediates") = true)
.def("set_output_format", &PyRtgToolOptions::setOutputFormat,
"Specify the output format of the tool", nb::arg("format"))
.def("set_seed", &PyRtgToolOptions::setSeed,
"Specify the seed for all RNGs used in the tool", nb::arg("seed"))
.def("set_verify_passes", &PyRtgToolOptions::setVerifyPasses,
"Specify whether the verifiers should be run after each pass",
nb::arg("enable"))
.def("set_verbose_pass_execution",
&PyRtgToolOptions::setVerbosePassExecution,
"Specify whether passes should run in verbose mode",
nb::arg("enable"))
.def("set_unsupported_instructions",
&PyRtgToolOptions::setUnsupportedInstructions,
"Set the list of of instructions unsupported by the assembler",
nb::arg("instructions"))
.def("add_unsupported_instruction",
&PyRtgToolOptions::addUnsupportedInstruction,
"Add the instruction given by name to the list of instructions not "
"supported by the assembler",
nb::arg("instruction_name"))
.def("set_unsupported_instructions_file",
&PyRtgToolOptions::setUnsupportedInstructionsFile,
"Register a file containing a comma-separated list of instruction "
"names which are not supported by the assembler.",
nb::arg("filename"))
.def("set_split_output", &PyRtgToolOptions::setSplitOutput,
"Determines whether each test should be emitted to a separate file.",
nb::arg("enable"))
.def("output_path", &PyRtgToolOptions::setOutputPath,
"The path of a file to be emitted to or a directory if "
"'split_output' is enabled.",
nb::arg("filename"))
.def("set_memories_as_immediates",
&PyRtgToolOptions::setMemoriesAsImmediates,
"Determines whether memories are lowered to immediates or labels.",
nb::arg("enable"));
m.def("populate_randomizer_pipeline",
[](MlirPassManager pm, const PyRtgToolOptions &options) {
circtRtgToolRandomizerPipeline(pm, options.get());
});
}

View File

@ -1,5 +0,0 @@
# 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
from ._mlir_libs._circt._rtgtool import *

View File

@ -3,7 +3,6 @@ add_subdirectory(ExportFIRRTL)
add_subdirectory(ExportVerilog)
add_subdirectory(Dialect)
add_subdirectory(Firtool)
add_subdirectory(RtgTool)
add_subdirectory(Support)
add_subdirectory(Synthesis)
add_subdirectory(Transforms)

View File

@ -1,7 +0,0 @@
add_circt_public_c_api_library(CIRCTCAPIRtgTool
RtgTool.cpp
LINK_LIBS PUBLIC
CIRCTRtgToolLib
MLIRCAPIIR
)

View File

@ -1,108 +0,0 @@
//===- 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 <string>
using namespace circt;
using namespace circt::rtg;
//===----------------------------------------------------------------------===//
// Tool Option API.
//===----------------------------------------------------------------------===//
DEFINE_C_API_PTR_METHODS(CirctRtgToolOptions, RtgToolOptions)
CirctRtgToolOptions circtRtgToolOptionsCreateDefault(unsigned seed) {
auto *options = new RtgToolOptions(seed);
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 circtRtgToolOptionsSetVerifyPasses(CirctRtgToolOptions options,
bool enable) {
unwrap(options)->setVerifyPasses(enable);
}
void circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options,
bool enable) {
unwrap(options)->setVerbosePassExecution(enable);
}
void circtRtgToolOptionsSetUnsupportedInstructions(
CirctRtgToolOptions options, unsigned numInstr,
const void **unsupportedInstructions) {
SmallVector<std::string> instr;
for (unsigned i = 0; i < numInstr; ++i)
instr.push_back(
reinterpret_cast<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));
}
void circtRtgToolOptionsSetSplitOutput(CirctRtgToolOptions options,
bool enable) {
unwrap(options)->setSplitOutput(enable);
}
void circtRtgToolOptionsSetOutputPath(CirctRtgToolOptions options,
const char *path) {
unwrap(options)->setOutputPath(std::string(path));
}
void circtRtgToolOptionsSetMemoriesAsImmediates(CirctRtgToolOptions options,
bool enable) {
unwrap(options)->setMemoriesAsImmediates(enable);
}
//===----------------------------------------------------------------------===//
// Pipeline Population API.
//===----------------------------------------------------------------------===//
void circtRtgToolRandomizerPipeline(MlirPassManager pm,
CirctRtgToolOptions options) {
populateRandomizerPipeline(*unwrap(pm), *unwrap(options));
}

View File

@ -1,6 +1,5 @@
add_subdirectory(circt-bmc)
add_subdirectory(circt-lec)
add_subdirectory(rtgtool)
if(CIRCT_SLANG_FRONTEND_ENABLED)
add_subdirectory(circt-verilog-lsp-server)

View File

@ -1,12 +0,0 @@
add_circt_library(CIRCTRtgToolLib
RtgToolOptions.cpp
LINK_LIBS PUBLIC
CIRCTRTGDialect
CIRCTRTGTransforms
CIRCTSupport
MLIRIR
MLIRPass
MLIRTransforms
)

View File

@ -1,63 +0,0 @@
//===- 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/IR/RTGOps.h"
#include "circt/Dialect/RTG/Transforms/RTGPassPipelines.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) {
if (options.getVerifyPasses())
pm.enableVerifier(options.getVerifyPasses());
if (options.getVerbosePassExecution())
pm.addInstrumentation(
std::make_unique<VerbosePassInstrumentation<mlir::ModuleOp>>(
"rtgtool"));
{
// Initial canonicalization of the input IR.
auto &anyPm = pm.nestAny();
anyPm.addPass(mlir::createCSEPass());
anyPm.addPass(createSimpleCanonicalizerPass());
}
if (options.getOutputFormat() == RtgToolOptions::OutputFormat::MLIR)
return;
{
rtg::RandomizationPipelineOptions pipelineOptions;
pipelineOptions.seed = options.getSeed();
pipelineOptions.memoriesAsImmediates = options.getMemoriesAsImmediates();
rtg::buildRandomizationPipeline(pm, pipelineOptions);
}
if (options.getOutputFormat() == RtgToolOptions::OutputFormat::ElaboratedMLIR)
return;
{
EmitRTGISAAssemblyPassOptions passOptions;
SmallVector<std::string> unsupported(options.getUnsupportedInstructions());
passOptions.unsupportedInstructions = unsupported;
passOptions.unsupportedInstructionsFile =
options.getUnsupportedInstructionsFile();
passOptions.splitOutput = options.getSplitOutput();
passOptions.path = options.getOutputPath();
pm.addPass(rtg::createEmitRTGISAAssemblyPass(passOptions));
}
}

View File

@ -70,20 +70,6 @@ target_link_libraries(circt-capi-arc-test
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

View File

@ -1,60 +0,0 @@
//===- 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 <stdio.h>
#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() {\n"
" %0 = rtg.get_sequence @seq : !rtg.sequence\n"
"}\n"
"rtg.target @target : !rtg.dict<> {\n"
" rtg.yield\n"
"}\n"));
if (mlirModuleIsNull(moduleOp)) {
printf("ERROR: Could not parse.\n");
mlirContextDestroy(ctx);
return 1;
}
MlirPassManager pm = mlirPassManagerCreate(ctx);
CirctRtgToolOptions options = circtRtgToolOptionsCreateDefault(/*seed=*/0);
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;
}

View File

@ -23,7 +23,6 @@ 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-capi-support-test

View File

@ -60,11 +60,10 @@ tool_dirs = [
tools = [
'arcilator', 'circt-as', 'circt-bmc', 'circt-capi-aig-test',
'circt-capi-ir-test', '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-capi-support-test',
'circt-dis', 'circt-lec', 'circt-reduce', 'circt-synth', 'circt-test',
'circt-translate', 'firld', 'firtool', 'hlstool', 'om-linker',
'kanagawatool'
'circt-capi-firtool-test', 'circt-capi-rtg-test', 'circt-capi-rtgtest-test',
'circt-capi-support-test', 'circt-dis', 'circt-lec', 'circt-reduce',
'circt-synth', 'circt-test', 'circt-translate', 'firld', 'firtool',
'hlstool', 'om-linker', 'kanagawatool'
]
if "CIRCT_OPT_CHECK_IR_ROUNDTRIP" in os.environ: