[RTG] Populate pipeline with new passes (#8139)

Add the new passes to the pipeline and pass their options through to the frontend
This commit is contained in:
Martin Erhart 2025-02-03 07:56:45 +00:00 committed by GitHub
parent d47a9d2f7a
commit 82dcb9f36b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 133 additions and 14 deletions

View File

@ -56,7 +56,7 @@ circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options,
MLIR_CAPI_EXPORTED void circtRtgToolOptionsSetUnsupportedInstructions(
CirctRtgToolOptions options, unsigned numInstr,
const char **unsupportedInstructions);
const void **unsupportedInstructions);
MLIR_CAPI_EXPORTED void circtRtgToolOptionsAddUnsupportedInstruction(
CirctRtgToolOptions options, const char *unsupportedInstruction);
@ -65,6 +65,12 @@ 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);
//===----------------------------------------------------------------------===//
// Pipeline Population API.
//===----------------------------------------------------------------------===//

View File

@ -73,6 +73,18 @@ public:
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; }
private:
OutputFormat outputFormat = OutputFormat::ElaboratedMLIR;
unsigned seed;
@ -80,6 +92,8 @@ private:
bool verbosePassExecution = false;
SmallVector<std::string> unsupportedInstructions;
std::string unsupportedInstructionsFile;
bool splitOutput = false;
std::string outputPath;
};
/// Populates the passes necessary to lower IR with RTG randomization operations

View File

@ -0,0 +1,41 @@
# REQUIRES: bindings_python
# RUN: %PYTHON% %s %T && FileCheck %s --input-file=%T/test0.s --check-prefix=TEST0 && FileCheck %s --input-file=%T/test1.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', TypeAttr.get(rtg.DictType.get()))
block = Block.create_at_start(test.bodyRegion, [])
with InsertionPoint(block):
rtgtest.rv32i_ebreak()
test = rtg.TestOp('test1', TypeAttr.get(rtg.DictType.get()))
block = Block.create_at_start(test.bodyRegion, [])
with InsertionPoint(block):
rtgtest.rv32i_ecall()
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

@ -23,14 +23,17 @@ class PyRtgToolOptions {
public:
PyRtgToolOptions(unsigned seed, CirctRtgToolOutputFormat outputFormat,
bool verifyPasses, bool verbosePassExecution,
const std::vector<const char *> &unsupportedInstructions,
const std::string &unsupportedInstructionsFile)
const std::vector<std::string> &unsupportedInstructions,
const std::string &unsupportedInstructionsFile,
bool splitOutput, const std::string &outputPath)
: options(circtRtgToolOptionsCreateDefault(seed)) {
setOutputFormat(outputFormat);
setVerifyPasses(verifyPasses);
setVerbosePassExecution(verbosePassExecution);
setUnsupportedInstructions(unsupportedInstructions);
setUnsupportedInstructionsFile(unsupportedInstructionsFile);
setSplitOutput(splitOutput);
setOutputPath(outputPath);
}
~PyRtgToolOptions() { circtRtgToolOptionsDestroy(options); }
@ -52,10 +55,11 @@ public:
}
void
setUnsupportedInstructions(const std::vector<const char *> &instructions) {
setUnsupportedInstructions(const std::vector<std::string> &instructions) {
circtRtgToolOptionsSetUnsupportedInstructions(
options, instructions.size(),
const_cast<const char **>(instructions.data()));
reinterpret_cast<const void **>(
const_cast<std::string *>(instructions.data())));
}
void addUnsupportedInstruction(const std::string &instruction) {
@ -67,6 +71,14 @@ public:
filename.c_str());
}
void setSplitOutput(bool enable) {
circtRtgToolOptionsSetSplitOutput(options, enable);
}
void setOutputPath(const std::string &path) {
circtRtgToolOptionsSetOutputPath(options, path.c_str());
}
private:
CirctRtgToolOptions options;
};
@ -83,13 +95,15 @@ void circt::python::populateDialectRTGToolSubmodule(nb::module_ &m) {
nb::class_<PyRtgToolOptions>(m, "Options")
.def(nb::init<unsigned, CirctRtgToolOutputFormat, bool, bool,
const std::vector<const char *> &, const std::string &>(),
const std::vector<std::string> &, const std::string &, bool,
const std::string &>(),
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("unsupported_instructions_file") = "",
nb::arg("split_output") = false, nb::arg("output_path") = "")
.def("set_output_format", &PyRtgToolOptions::setOutputFormat,
"Specify the output format of the tool", nb::arg("format"))
.def("set_seed", &PyRtgToolOptions::setSeed,
@ -114,6 +128,13 @@ void circt::python::populateDialectRTGToolSubmodule(nb::module_ &m) {
&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("filename"))
.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"));
m.def("populate_randomizer_pipeline",

View File

@ -64,10 +64,11 @@ void circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options,
void circtRtgToolOptionsSetUnsupportedInstructions(
CirctRtgToolOptions options, unsigned numInstr,
const char **unsupportedInstructions) {
const void **unsupportedInstructions) {
SmallVector<std::string> instr;
for (unsigned i = 0; i < numInstr; ++i)
instr.push_back(std::string(unsupportedInstructions[i]));
instr.push_back(
reinterpret_cast<std::string *>(unsupportedInstructions)[i]);
unwrap(options)->setUnsupportedInstructions(std::move(instr));
}
@ -82,6 +83,16 @@ void circtRtgToolOptionsSetUnsupportedInstructionsFile(
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));
}
//===----------------------------------------------------------------------===//
// Pipeline Population API.
//===----------------------------------------------------------------------===//

View File

@ -2,6 +2,8 @@ add_circt_library(CIRCTRtgToolLib
RtgToolOptions.cpp
LINK_LIBS PUBLIC
CIRCTRTGDialect
CIRCTRTGTransforms
CIRCTSupport
MLIRIR

View File

@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "circt/Tools/rtgtool/RtgToolOptions.h"
#include "circt/Dialect/RTG/IR/RTGOps.h"
#include "circt/Dialect/RTG/Transforms/RTGPasses.h"
#include "circt/Support/Passes.h"
#include "mlir/Transforms/Passes.h"
@ -19,7 +21,8 @@ using namespace circt::rtg;
void rtg::populateRandomizerPipeline(mlir::PassManager &pm,
const RtgToolOptions &options) {
pm.enableVerifier(options.getVerifyPasses());
if (options.getVerifyPasses())
pm.enableVerifier(options.getVerifyPasses());
if (options.getVerbosePassExecution())
pm.addInstrumentation(
@ -27,9 +30,30 @@ void rtg::populateRandomizerPipeline(mlir::PassManager &pm,
"rtgtool"));
pm.addPass(createSimpleCanonicalizerPass());
if (options.getOutputFormat() != RtgToolOptions::OutputFormat::MLIR) {
// TODO: add elaboration pass here
pm.addPass(mlir::createCSEPass());
pm.addPass(createSimpleCanonicalizerPass());
if (options.getOutputFormat() == RtgToolOptions::OutputFormat::MLIR)
return;
{
ElaborationPassOptions passOptions;
passOptions.seed = options.getSeed();
pm.addPass(rtg::createElaborationPass(passOptions));
}
pm.addNestedPass<rtg::TestOp>(rtg::createLinearScanRegisterAllocationPass());
pm.addPass(mlir::createCSEPass());
pm.addPass(createSimpleCanonicalizerPass());
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));
}
}