11#include "mlir/Pass/Pass.h"
23#include "mlir/Transforms/DialectConversion.h"
27#define GEN_PASS_DEF_KANAGAWAPREPARESCHEDULING
28#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc"
33using namespace kanagawa;
37struct PrepareSchedulingPass
38 :
public circt::kanagawa::impl::KanagawaPrepareSchedulingBase<
39 PrepareSchedulingPass> {
40 void runOnOperation()
override;
44 pipeline::UnscheduledPipelineOp prepareSBlock(IsolatedStaticBlockOp sblock);
49 LogicalResult attachOperatorTypes(pipeline::UnscheduledPipelineOp pipeline);
53pipeline::UnscheduledPipelineOp
54PrepareSchedulingPass::prepareSBlock(IsolatedStaticBlockOp sblock) {
55 Location loc = sblock.getLoc();
56 Block *bodyBlock = sblock.getBodyBlock();
57 auto b = OpBuilder::atBlockBegin(bodyBlock);
58 auto ph = kanagawa::PipelineHeaderOp::create(b, loc);
62 auto sblockRet = cast<BlockReturnOp>(bodyBlock->getTerminator());
63 auto retTypes = sblockRet.getOperandTypes();
66 SmallVector<Attribute> inNames, outNames;
67 for (
size_t i = 0, e = bodyBlock->getNumArguments(); i < e; ++i)
68 inNames.push_back(b.getStringAttr(
"in" + std::to_string(i)));
69 for (
size_t i = 0, e = retTypes.size(); i < e; ++i)
70 outNames.push_back(b.getStringAttr(
"out" + std::to_string(i)));
72 auto pipeline = pipeline::UnscheduledPipelineOp::create(
73 b, loc, retTypes, bodyBlock->getArguments(), b.getArrayAttr(inNames),
74 b.getArrayAttr(outNames), ph.getClock(), ph.getGo(), ph.getReset(),
76 b.setInsertionPointToEnd(pipeline.getEntryStage());
85 pipeline::ReturnOp::create(b, loc, sblockRet.getOperands());
86 for (
size_t i = 0, e = retTypes.size(); i < e; ++i)
87 sblockRet.setOperand(i, pipeline.getResult(i));
91 for (
auto [sbArg, plArg] :
92 llvm::zip(bodyBlock->getArguments(),
93 pipeline.getEntryStage()->getArguments())) {
94 sbArg.replaceAllUsesExcept(plArg, pipeline);
101 llvm::SmallVector<Operation *> opsToMove;
102 llvm::transform(bodyBlock->getOperations(), std::back_inserter(opsToMove),
103 [&](Operation &op) { return &op; });
105 ArrayRef(opsToMove.begin(), opsToMove.
end()).drop_front(2).drop_back())
106 op->moveBefore(pipelineRet);
111LogicalResult PrepareSchedulingPass::attachOperatorTypes(
112 pipeline::UnscheduledPipelineOp pipeline) {
113 for (Operation &op : *pipeline.getEntryStage()) {
114 if (op.hasAttr(
"ssp.operator_type"))
118 if (isa<pipeline::ReturnOp>(op) || op.hasTrait<OpTrait::ConstantLike>())
125 FlatSymbolRefAttr::get(op.getContext(), op.getName().getStringRef()));
136void PrepareSchedulingPass::runOnOperation() {
137 pipeline::UnscheduledPipelineOp pipeline = prepareSBlock(getOperation());
138 if (failed(attachOperatorTypes(pipeline)))
139 return signalPassFailure();
143 return std::make_unique<PrepareSchedulingPass>();
static constexpr const char * kKanagawaOperatorLibName
std::unique_ptr< mlir::Pass > createPrepareSchedulingPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.