26#define GEN_PASS_DEF_COMBINEASSERTLIKEPASS
27#include "circt/Dialect/Verif/Passes.h.inc"
57struct CombineAssertLikePass
58 : verif::impl::CombineAssertLikePassBase<CombineAssertLikePass> {
61 bool canScheduleOn(RegisteredOperationName opInfo)
const override {
62 return opInfo.getStringRef() == hw::HWModuleOp::getOperationName() ||
63 opInfo.getStringRef() == verif::FormalOp::getOperationName();
65 void runOnOperation()
override;
74 llvm::SmallDenseMap<Block *, llvm::SmallVector<Value>> assertConditions;
75 llvm::SmallDenseMap<Block *, llvm::SmallVector<Value>> assumeConditions;
78 llvm::SmallDenseMap<Block *, llvm::SmallVector<Operation *>> assertsToErase;
79 llvm::SmallDenseMap<Block *, llvm::SmallVector<Operation *>> assumesToErase;
85 LogicalResult accumulateCondition(
86 T &op, llvm::SmallDenseMap<Block *, llvm::SmallVector<Value>> &conds,
87 llvm::SmallDenseMap<Block *, llvm::SmallVector<Operation *>> &opsToErase,
90 auto condition = op.getProperty();
91 auto defop = op.getOperation();
92 Block *parent = defop->getBlock();
95 if (!isa<ltl::PropertyType, ltl::SequenceType>(condition.getType())) {
98 auto enable = op.getEnable();
104 builder.setInsertionPoint(defop);
109 comb::createOrFoldNot(builder, defop->getLoc(), enable);
111 comb::OrOp::create(builder, defop->getLoc(), notEnable, condition);
114 conds[parent].push_back(orop);
117 conds[parent].push_back(condition);
121 opsToErase[parent].push_back(defop);
128 template <
typename AT>
129 LogicalResult conjoinConditions(Operation *assertlike,
130 llvm::SmallVectorImpl<Value> &conds,
131 OpBuilder &builder) {
138 builder.setInsertionPointAfter(assertlike);
141 auto andop = comb::AndOp::create(builder, assertlike->getLoc(), conds,
145 AT::create(builder, andop.getLoc(), andop,
nullptr,
153 template <
typename AT>
154 LogicalResult conjoinAndErase(
155 llvm::SmallDenseMap<Block *, llvm::SmallVector<Value>> &conds,
156 llvm::SmallDenseMap<Block *, llvm::SmallVector<Operation *>> &opsToErase,
157 OpBuilder &builder) {
159 for (
auto [parent, ops] : opsToErase) {
161 if (ops.size() > 1) {
163 if (
auto it = conds.find(parent); it != conds.end())
165 if (failed(conjoinConditions<AT>(ops.back(), conds[parent], builder)))
178void CombineAssertLikePass::runOnOperation() {
179 Operation *module = getOperation();
180 OpBuilder builder(module);
185 module->walk([&](Operation *op) {
187 if (auto aop = dyn_cast<verif::AssertOp>(op))
188 if (failed(accumulateCondition(aop, assertConditions, assertsToErase,
190 return signalPassFailure();
191 if (
auto aop = dyn_cast<verif::AssumeOp>(op))
192 if (failed(accumulateCondition(aop, assumeConditions, assumesToErase,
194 return signalPassFailure();
199 if (failed(conjoinAndErase<verif::AssertOp>(assertConditions, assertsToErase,
201 return signalPassFailure();
204 if (failed(conjoinAndErase<verif::AssumeOp>(assumeConditions, assumesToErase,
206 return signalPassFailure();
209 assertConditions.clear();
210 assumeConditions.clear();
211 assertsToErase.clear();
212 assumesToErase.clear();
false return failure()
Parse an optional keyword or string and set instance into 'result'.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.