[RTG] Add Randomization Pipeline (#8675)

This commit is contained in:
Martin Erhart 2025-07-10 14:14:24 +01:00 committed by GitHub
parent 436ed621bd
commit 56625bf811
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 128 additions and 18 deletions

View File

@ -0,0 +1,42 @@
//===----------------------------------------------------------------------===//
//
// 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_DIALECT_RTG_TRANSFORMS_RTGPASSPIPELINES_H
#define CIRCT_DIALECT_RTG_TRANSFORMS_RTGPASSPIPELINES_H
#include "mlir/Pass/PassOptions.h"
namespace circt {
namespace rtg {
/// Options for the RTG randomization pipeline.
struct RandomizationPipelineOptions
: public mlir::PassPipelineOptions<RandomizationPipelineOptions> {
PassOptions::Option<unsigned> seed{*this, "seed",
llvm::cl::desc("Seed for the RNG.")};
PassOptions::Option<bool> memoriesAsImmediates{
*this, "memories-as-immediates",
llvm::cl::desc("Lower memories to immediates instead of labels."),
llvm::cl::init(true)};
};
//===----------------------------------------------------------------------===//
// Building and Registering.
//===----------------------------------------------------------------------===//
/// Adds the randomization pipeline to the `OpPassManager`.
void buildRandomizationPipeline(mlir::OpPassManager &pm,
const RandomizationPipelineOptions &options);
/// Registers all pipelines for the `rtg` dialect.
void registerPipelines();
} // namespace rtg
} // namespace circt
#endif // CIRCT_DIALECT_RTG_TRANSFORMS_RTGPASSPIPELINES_H

View File

@ -33,6 +33,7 @@
#include "circt/Dialect/Moore/MoorePasses.h"
#include "circt/Dialect/OM/OMPasses.h"
#include "circt/Dialect/Pipeline/PipelinePasses.h"
#include "circt/Dialect/RTG/Transforms/RTGPassPipelines.h"
#include "circt/Dialect/RTG/Transforms/RTGPasses.h"
#include "circt/Dialect/SSP/SSPPasses.h"
#include "circt/Dialect/SV/SVPasses.h"
@ -84,6 +85,9 @@ inline void registerAllPasses() {
sv::registerPasses();
systemc::registerPasses();
verif::registerPasses();
// Register pass pipelines
rtg::registerPipelines();
}
} // namespace circt

View File

@ -10,6 +10,7 @@
#include "circt/Dialect/RTG/IR/RTGAttributes.h"
#include "circt/Dialect/RTG/IR/RTGDialect.h"
#include "circt/Dialect/RTG/IR/RTGTypes.h"
#include "circt/Dialect/RTG/Transforms/RTGPassPipelines.h"
#include "circt/Dialect/RTG/Transforms/RTGPasses.h"
#include "mlir/CAPI/Registration.h"
@ -23,7 +24,10 @@ using namespace circt::rtg;
MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(RTG, rtg, RTGDialect)
void registerRTGPasses() { circt::rtg::registerPasses(); }
void registerRTGPasses() {
circt::rtg::registerPasses();
circt::rtg::registerPipelines();
}
//===----------------------------------------------------------------------===//
// Type API.

View File

@ -7,6 +7,7 @@ add_circt_dialect_library(CIRCTRTGTransforms
LowerUniqueLabelsPass.cpp
LowerValidateToLabelsPass.cpp
MemoryAllocationPass.cpp
RTGPassPipelines.cpp
UniqueValidateOpsPass.cpp
DEPENDS

View File

@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// 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/Dialect/RTG/Transforms/RTGPassPipelines.h"
#include "circt/Dialect/RTG/IR/RTGOps.h"
#include "circt/Dialect/RTG/Transforms/RTGPasses.h"
#include "circt/Support/Passes.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/Passes.h"
using namespace mlir;
//===----------------------------------------------------------------------===//
// Pipeline implementation.
//===----------------------------------------------------------------------===//
void circt::rtg::buildRandomizationPipeline(
OpPassManager &pm, const RandomizationPipelineOptions &options) {
{
ElaborationPassOptions passOptions;
passOptions.seed = options.seed;
pm.addPass(rtg::createElaborationPass(passOptions));
}
pm.addPass(rtg::createInlineSequencesPass());
{
MemoryAllocationPassOptions passOptions;
passOptions.useImmediates = options.memoriesAsImmediates;
pm.addNestedPass<rtg::TestOp>(rtg::createMemoryAllocationPass());
}
pm.addPass(rtg::createLowerUniqueLabelsPass());
pm.addNestedPass<rtg::TestOp>(rtg::createLinearScanRegisterAllocationPass());
{
auto &anyPm = pm.nestAny();
anyPm.addPass(mlir::createCSEPass());
anyPm.addPass(createSimpleCanonicalizerPass());
}
pm.addPass(rtg::createUniqueValidateOpsPass());
}
//===----------------------------------------------------------------------===//
// Pipeline registration.
//===----------------------------------------------------------------------===//
void circt::rtg::registerPipelines() {
PassPipelineRegistration<RandomizationPipelineOptions>(
"rtg-randomization-pipeline",
"The default pipeline for randomizing RTG tests.",
buildRandomizationPipeline);
}

View File

@ -8,6 +8,7 @@
#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"
@ -40,24 +41,11 @@ void rtg::populateRandomizerPipeline(mlir::PassManager &pm,
return;
{
ElaborationPassOptions passOptions;
passOptions.seed = options.getSeed();
pm.addPass(rtg::createElaborationPass(passOptions));
rtg::RandomizationPipelineOptions pipelineOptions;
pipelineOptions.seed = options.getSeed();
pipelineOptions.memoriesAsImmediates = options.getMemoriesAsImmediates();
rtg::buildRandomizationPipeline(pm, pipelineOptions);
}
pm.addPass(rtg::createInlineSequencesPass());
{
MemoryAllocationPassOptions passOptions;
passOptions.useImmediates = options.getMemoriesAsImmediates();
pm.addNestedPass<rtg::TestOp>(rtg::createMemoryAllocationPass());
}
pm.addPass(rtg::createLowerUniqueLabelsPass());
pm.addNestedPass<rtg::TestOp>(rtg::createLinearScanRegisterAllocationPass());
{
auto &anyPm = pm.nestAny();
anyPm.addPass(mlir::createCSEPass());
anyPm.addPass(createSimpleCanonicalizerPass());
}
pm.addPass(rtg::createUniqueValidateOpsPass());
if (options.getOutputFormat() == RtgToolOptions::OutputFormat::ElaboratedMLIR)
return;

View File

@ -0,0 +1,17 @@
// RUN: circt-opt %s --rtg-randomization-pipeline=seed=0 | FileCheck %s
rtg.target @target : !rtg.dict<mem_blk: !rtg.isa.memory_block<32>> {
%0 = rtg.isa.memory_block_declare [0 - 31] : !rtg.isa.memory_block<32>
rtg.yield %0 : !rtg.isa.memory_block<32>
}
// CHECK-LABEL: rtg.test @test_target
rtg.test @test(mem_blk = %mem_blk: !rtg.isa.memory_block<32>) {
// CHECK-NEXT: [[REG:%.+]] = rtg.fixed_reg
// CHECK-NEXT: [[IMM:%.+]] = rtg.constant #rtg.isa.immediate
// CHECK-NEXT: rtgtest.rv32i.la [[REG]], [[IMM]] :
%idx4 = index.constant 4
%0 = rtg.isa.memory_alloc %mem_blk, %idx4, %idx4 : !rtg.isa.memory_block<32>
%reg = rtg.virtual_reg [#rtgtest.t0, #rtgtest.t1, #rtgtest.t2]
rtgtest.rv32i.la %reg, %0 : !rtg.isa.memory<32>
}