16 #include "mlir/IR/PatternMatch.h"
17 #include "mlir/Pass/Pass.h"
18 #include "mlir/Rewrite/FrozenRewritePatternSet.h"
19 #include "mlir/Transforms/DialectConversion.h"
23 #define GEN_PASS_DEF_HANDSHAKELOCKFUNCTIONS
24 #include "circt/Dialect/Handshake/HandshakePasses.h.inc"
28 using namespace circt;
29 using namespace handshake;
33 static LogicalResult
lockRegion(Region &r, OpBuilder &rewriter) {
34 Block *entry = &r.front();
35 Location loc = r.getLoc();
37 if (entry->getNumArguments() == 0)
38 return r.getParentOp()->emitError(
"cannot lock a region without arguments");
40 auto *ret = r.front().getTerminator();
41 if (ret->getNumOperands() == 0)
42 return r.getParentOp()->emitError(
"cannot lock a region without results");
44 rewriter.setInsertionPointToStart(entry);
46 auto backEdge = bebuilder.
get(rewriter.getNoneType());
48 auto buff = rewriter.create<handshake::BufferOp>(loc, backEdge, 1,
53 buff->setAttr(
"initValues", rewriter.getI64ArrayAttr({0}));
55 SmallVector<Value> inSyncOperands =
56 llvm::to_vector_of<Value>(entry->getArguments());
57 inSyncOperands.push_back(buff);
58 auto sync = rewriter.create<SyncOp>(loc, inSyncOperands);
62 for (
auto &&[arg, synced] :
63 llvm::drop_end(llvm::zip(inSyncOperands, sync.getResults())))
64 arg.replaceAllUsesExcept(synced, sync);
66 rewriter.setInsertionPoint(ret);
67 SmallVector<Value> endJoinOperands = llvm::to_vector(ret->getOperands());
69 endJoinOperands.push_back(sync.getResults().back());
70 auto endJoin = rewriter.create<JoinOp>(loc, endJoinOperands);
72 backEdge.setValue(endJoin);
78 struct HandshakeLockFunctionsPass
79 :
public circt::handshake::impl::HandshakeLockFunctionsBase<
80 HandshakeLockFunctionsPass> {
81 void runOnOperation()
override {
82 handshake::FuncOp op = getOperation();
86 OpBuilder builder(op);
87 if (failed(
lockRegion(op.getRegion(), builder)))
93 std::unique_ptr<mlir::Pass>
95 return std::make_unique<HandshakeLockFunctionsPass>();
static LogicalResult lockRegion(Region &r, OpBuilder &rewriter)
Adds a locking mechanism around the region.
Instantiate one of these and use it to build typed backedges.
Backedge get(mlir::Type resultType, mlir::LocationAttr optionalLoc={})
Create a typed backedge.
std::unique_ptr< mlir::Pass > createHandshakeLockFunctionsPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.