11 #include "mlir/Pass/Pass.h"
23 #include "mlir/Transforms/DialectConversion.h"
27 #define GEN_PASS_DEF_IBISPREPARESCHEDULING
28 #include "circt/Dialect/Ibis/IbisPasses.h.inc"
32 using namespace circt;
37 struct PrepareSchedulingPass
38 :
public circt::ibis::impl::IbisPrepareSchedulingBase<
39 PrepareSchedulingPass> {
40 void runOnOperation()
override;
44 pipeline::UnscheduledPipelineOp prepareSBlock(IsolatedStaticBlockOp sblock);
49 LogicalResult attachOperatorTypes(pipeline::UnscheduledPipelineOp pipeline);
53 pipeline::UnscheduledPipelineOp
54 PrepareSchedulingPass::prepareSBlock(IsolatedStaticBlockOp sblock) {
55 Location loc = sblock.getLoc();
56 Block *bodyBlock = sblock.getBodyBlock();
57 auto b = OpBuilder::atBlockBegin(bodyBlock);
58 auto ph = b.create<ibis::PipelineHeaderOp>(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 = b.create<pipeline::UnscheduledPipelineOp>(
73 loc, retTypes, bodyBlock->getArguments(), b.getArrayAttr(inNames),
74 b.getArrayAttr(outNames), ph.getClock(), ph.getReset(), ph.getGo(),
76 b.setInsertionPointToEnd(pipeline.getEntryStage());
84 auto pipelineRet = b.create<pipeline::ReturnOp>(loc, sblockRet.getOperands());
85 for (
size_t i = 0, e = retTypes.size(); i < e; ++i)
86 sblockRet.setOperand(i, pipeline.getResult(i));
90 for (
auto [sbArg, plArg] :
91 llvm::zip(bodyBlock->getArguments(),
92 pipeline.getEntryStage()->getArguments())) {
93 sbArg.replaceAllUsesExcept(plArg, pipeline);
100 llvm::SmallVector<Operation *> opsToMove;
101 llvm::transform(bodyBlock->getOperations(), std::back_inserter(opsToMove),
102 [&](Operation &op) { return &op; });
104 ArrayRef(opsToMove.begin(), opsToMove.end()).drop_front(2).drop_back())
105 op->moveBefore(pipelineRet);
110 LogicalResult PrepareSchedulingPass::attachOperatorTypes(
111 pipeline::UnscheduledPipelineOp pipeline) {
112 for (Operation &op : *pipeline.getEntryStage()) {
113 if (op.hasAttr(
"ssp.operator_type"))
117 if (isa<pipeline::ReturnOp>(op) || op.hasTrait<OpTrait::ConstantLike>())
135 void PrepareSchedulingPass::runOnOperation() {
136 pipeline::UnscheduledPipelineOp pipeline = prepareSBlock(getOperation());
137 if (failed(attachOperatorTypes(pipeline)))
138 return signalPassFailure();
142 return std::make_unique<PrepareSchedulingPass>();
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
static constexpr const char * kIbisOperatorLibName
std::unique_ptr< mlir::Pass > createPrepareSchedulingPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.