20 #define GEN_PASS_DEF_SIMPLIFYPROCEDURES
21 #include "circt/Dialect/Moore/MoorePasses.h.inc"
25 using namespace circt;
26 using namespace moore;
29 struct SimplifyProceduresPass
30 :
public circt::moore::impl::SimplifyProceduresBase<
31 SimplifyProceduresPass> {
32 void runOnOperation()
override;
37 return std::make_unique<SimplifyProceduresPass>();
40 void SimplifyProceduresPass::runOnOperation() {
41 getOperation()->walk([&](ProcedureOp procedureOp) {
42 mlir::OpBuilder builder(&getContext());
46 procedureOp.walk([&](Operation *op) {
47 SmallVector<std::tuple<BlockingAssignOp, Value, Value>> assignOps;
51 if (isa<ReadOp>(nestedOp) &&
53 nestedOp.getOperand(0).getDefiningOp()->getParentOp())) {
55 DenseSet<Operation *> users;
56 for (auto *user : nestedOp.getOperand(0).getUsers())
58 if (procedureOp->isAncestor(user))
62 if (auto varOp = llvm::dyn_cast_or_null<VariableOp>(
63 nestedOp.getOperand(0).getDefiningOp())) {
64 auto resultType = varOp.getResult().getType();
65 builder.setInsertionPointToStart(&procedureOp.getBody().front());
66 auto readOp = builder.create<ReadOp>(
67 nestedOp.getLoc(), cast<RefType>(resultType).getNestedType(),
69 auto newVarOp = builder.create<VariableOp>(
70 nestedOp.getLoc(), resultType, StringAttr{}, Value{});
71 builder.create<BlockingAssignOp>(nestedOp.getLoc(), newVarOp, readOp);
72 builder.clearInsertionPoint();
76 for (auto *user : users) {
77 user->replaceUsesOfWith(user->getOperand(0), newVarOp);
78 if (auto assignOp = dyn_cast<BlockingAssignOp>(user))
79 assignOps.push_back({assignOp, newVarOp, varOp});
87 for (
auto [assignOp, localVar, var] : assignOps) {
88 builder.setInsertionPointAfter(assignOp);
89 auto readOp = builder.create<ReadOp>(assignOp.getLoc(), localVar);
90 builder.create<BlockingAssignOp>(assignOp.getLoc(), var, readOp);
91 builder.clearInsertionPoint();
std::unique_ptr< mlir::Pass > createSimplifyProceduresPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.