Skip to content

Commit

Permalink
[Verif] Add StripContracts pass
Browse files Browse the repository at this point in the history
Add a simple pass that removes all contracts from the IR, treating them
as passthroughs. Run the pass in firtool's HW-to-SV pipeline early on to
add additional optimization opportunities. ExportVerilog will eventually
ignore contracts anyway.
  • Loading branch information
fabianschuiki committed Jan 30, 2025
1 parent 0a111c7 commit cb6bd01
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 3 deletions.
8 changes: 8 additions & 0 deletions include/circt/Dialect/Verif/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,12 @@ def SimplifyAssumeEqPass : Pass<"simplify-assume-eq", "hw::HWModuleOp"> {
}];
}

def StripContractsPass : Pass<"strip-contracts"> {
let summary = "Remove contracts from the IR";
let description = [{
Replaces all `verif.contract` ops in the IR with their operands, making them
act as simple passthroughs.
}];
}

#endif // CIRCT_DIALECT_VERIF_PASSES_TD
7 changes: 4 additions & 3 deletions lib/Dialect/Verif/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
add_circt_dialect_library(CIRCTVerifTransforms
VerifyClockedAssertLike.cpp
PrepareForFormal.cpp
LowerFormalToHW.cpp
LowerContracts.cpp
LowerFormalToHW.cpp
PrepareForFormal.cpp
SimplifyAssumeEq.cpp
StripContracts.cpp
VerifyClockedAssertLike.cpp

DEPENDS
CIRCTVerifTransformsIncGen
Expand Down
44 changes: 44 additions & 0 deletions lib/Dialect/Verif/Transforms/StripContracts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===- StripContracts.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/Dialect/Verif/VerifOps.h"
#include "circt/Dialect/Verif/VerifPasses.h"
#include "mlir/Pass/Pass.h"

namespace circt {
namespace verif {
#define GEN_PASS_DEF_STRIPCONTRACTSPASS
#include "circt/Dialect/Verif/Passes.h.inc"
} // namespace verif
} // namespace circt

using namespace mlir;
using namespace circt;
using namespace verif;

namespace {
struct StripContractsPass
: public verif::impl::StripContractsPassBase<StripContractsPass> {
void runOnOperation() override {
getOperation()->walk([](ContractOp op) {
op->replaceUsesWithIf(op.getInputs(), [&](OpOperand &operand) {
return operand.getOwner() != op;
});
// Prevent removal of self-referential contracts that have other users.
// Removing them would result in invalid IR.
for (auto operand : op->getOperands())
if (operand.getDefiningOp() == op)
for (auto *user : operand.getUsers())
if (user != op)
return;
op->dropAllReferences();
op->erase();
});
}
};
} // namespace
1 change: 1 addition & 0 deletions lib/Firtool/Firtool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ LogicalResult firtool::populateLowFIRRTLToHW(mlir::PassManager &pm,

LogicalResult firtool::populateHWToSV(mlir::PassManager &pm,
const FirtoolOptions &opt) {
pm.nestAny().addPass(verif::createStripContractsPass());
pm.addPass(verif::createLowerFormalToHWPass());

if (opt.shouldExtractTestCode())
Expand Down
25 changes: 25 additions & 0 deletions test/Dialect/Verif/strip-contracts.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: circt-opt --strip-contracts %s | FileCheck %s

// CHECK-LABEL: func @foo
func.func @foo(%arg0: i42) -> i42 {
// CHECK-NOT: verif.contract
%0 = verif.contract %arg0 : i42 {}
// CHECK: return %arg0
return %0 : i42
}

// CHECK-LABEL: hw.module @bar
hw.module @bar() {
// CHECK-NOT: verif.contract
%0 = verif.contract %1 : i42 {}
%1 = verif.contract %0 : i42 {}
}

// CHECK-LABEL: hw.module @baz
hw.module @baz(out z: i42) {
// CHECK: [[TMP:%.+]] = verif.contract [[TMP]]
// CHECK: hw.output [[TMP]]
%2 = verif.contract %3 : i42 {}
%3 = verif.contract %2 : i42 {}
hw.output %3 : i42
}

0 comments on commit cb6bd01

Please sign in to comment.