mirror of https://github.com/llvm/circt.git
[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:
parent
327def313c
commit
175e30d32f
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -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());
|
||||
});
|
||||
}
|
|
@ -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 *
|
|
@ -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)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
add_circt_public_c_api_library(CIRCTCAPIRtgTool
|
||||
RtgTool.cpp
|
||||
|
||||
LINK_LIBS PUBLIC
|
||||
CIRCTRtgToolLib
|
||||
MLIRCAPIIR
|
||||
)
|
|
@ -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));
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
add_circt_library(CIRCTRtgToolLib
|
||||
RtgToolOptions.cpp
|
||||
|
||||
LINK_LIBS PUBLIC
|
||||
CIRCTRTGDialect
|
||||
CIRCTRTGTransforms
|
||||
CIRCTSupport
|
||||
|
||||
MLIRIR
|
||||
MLIRPass
|
||||
MLIRTransforms
|
||||
)
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue