14 #ifndef CIRCT_CONVERSION_CFTOHANDSHAKE_H_
15 #define CIRCT_CONVERSION_CFTOHANDSHAKE_H_
20 #include "mlir/Transforms/DialectConversion.h"
32 #define GEN_PASS_DECL_CFTOHANDSHAKE
33 #define GEN_PASS_DECL_HANDSHAKEREMOVEBLOCK
34 #include "circt/Conversion/Passes.h.inc"
43 llvm::function_ref<LogicalResult(Region &, ConversionPatternRewriter &)>;
47 MLIRContext *ctx, Region &r);
65 using BlockOps = DenseMap<Block *, std::vector<MergeOpInfo>>;
68 llvm::MapVector<Value, std::vector<Operation *>>;
72 LogicalResult
addMergeOps(ConversionPatternRewriter &rewriter);
73 LogicalResult
addBranchOps(ConversionPatternRewriter &rewriter);
76 template <
typename TSrcTerm,
typename TDstTerm>
79 assert(isa<NoneType>(entryCtrl.getType()) &&
80 "Expected NoneType for entry control value");
82 Block *entryBlock = &
r.front();
87 for (
auto retOp : llvm::make_early_inc_range(
r.getOps<TSrcTerm>())) {
88 rewriter.setInsertionPoint(retOp);
89 SmallVector<Value, 8> operands(retOp->getOperands());
90 operands.push_back(entryCtrl);
91 rewriter.replaceOpWithNewOp<TDstTerm>(retOp, operands);
95 DenseMap<Block *, unsigned> numArgsPerBlock;
96 for (
auto &block :
r.getBlocks())
97 numArgsPerBlock[&block] = block.getNumArguments();
108 for (
auto &[block, numArgs] : numArgsPerBlock)
109 if (block->getNumArguments() != numArgs)
116 bool sourceConstants);
122 ConversionPatternRewriter &rewriter);
127 ConversionPatternRewriter &rewriter);
139 ArrayRef<Operation *> memOps, Operation *memOp,
140 int offset, ArrayRef<int> cntrlInd);
170 template <
typename T,
typename... TArgs,
typename... TArgs2>
173 LogicalResult (T::*memberFunc)(ConversionPatternRewriter &, TArgs2...),
176 [&](Region &, ConversionPatternRewriter &rewriter) -> LogicalResult {
177 return (instance.*memberFunc)(rewriter, args...);
179 instance.getContext(), instance.getRegion());
192 template <
typename TSrcTerm,
typename TDstTerm>
194 bool disableTaskPipelining, Value entryCtrl) {
203 hl, &HandshakeLowering::setControlOnlyPath<TSrcTerm, TDstTerm>,
216 if (!disableTaskPipelining) {
247 std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
250 std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
252 bool disableTaskPipelining =
false);
254 std::unique_ptr<mlir::OperationPass<handshake::FuncOp>>
257 std::unique_ptr<mlir::OperationPass<handshake::FuncOp>>
assert(baseType &&"element must be base type")
llvm::ScopedHashTable< mlir::Value, std::string > ValueMap
Instantiate one of these and use it to build typed backedges.
BlockOps insertMergeOps(ValueMap &mergePairs, BackedgeBuilder &edgeBuilder, ConversionPatternRewriter &rewriter)
MergeOpInfo insertMerge(Block *block, Value val, BackedgeBuilder &edgeBuilder, ConversionPatternRewriter &rewriter)
LogicalResult loopNetworkRewriting(ConversionPatternRewriter &rewriter)
BlockArgument startCtrl
Start point of the control-only network.
DenseMap< Block *, std::vector< MergeOpInfo > > BlockOps
LogicalResult feedForwardRewriting(ConversionPatternRewriter &rewriter)
LogicalResult replaceCallOps(ConversionPatternRewriter &rewriter)
void setMemOpControlInputs(ConversionPatternRewriter &rewriter, ArrayRef< Operation * > memOps, Operation *memOp, int offset, ArrayRef< int > cntrlInd)
MLIRContext * getContext()
LogicalResult addMergeOps(ConversionPatternRewriter &rewriter)
LogicalResult replaceMemoryOps(ConversionPatternRewriter &rewriter, MemRefToMemoryAccessOp &memRefOps)
DenseMap< Block *, std::vector< Value > > BlockValues
LogicalResult connectConstantsToControl(ConversionPatternRewriter &rewriter, bool sourceConstants)
llvm::MapVector< Value, std::vector< Operation * > > MemRefToMemoryAccessOp
LogicalResult runSSAMaximization(ConversionPatternRewriter &rewriter, Value entryCtrl)
DenseMap< Block *, Value > blockEntryControlMap
LogicalResult setControlOnlyPath(ConversionPatternRewriter &rewriter, Value entryCtrl)
DenseMap< Value, Value > ValueMap
HandshakeLowering(Region &r)
Value getBlockEntryControl(Block *block) const
void setBlockEntryControl(Block *block, Value v)
LogicalResult connectToMemory(ConversionPatternRewriter &rewriter, MemRefToMemoryAccessOp memRefOps, bool lsq)
LogicalResult addBranchOps(ConversionPatternRewriter &rewriter)
LogicalResult runPartialLowering(T &instance, LogicalResult(T::*memberFunc)(ConversionPatternRewriter &, TArgs2...), TArgs &...args)
LogicalResult postDataflowConvert(Operation *op)
Lowers the mlir operations into handshake that are not part of the dataflow conversion.
LogicalResult lowerRegion(HandshakeLowering &hl, bool sourceConstants, bool disableTaskPipelining, Value entryCtrl)
llvm::function_ref< LogicalResult(Region &, ConversionPatternRewriter &)> RegionLoweringFunc
void removeBasicBlocks(Region &r)
Remove basic blocks inside the given region.
LogicalResult partiallyLowerRegion(const RegionLoweringFunc &loweringFunc, MLIRContext *ctx, Region &r)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< mlir::Pass > createInsertMergeBlocksPass()
mlir::LogicalResult insertMergeBlocks(mlir::Region &r, mlir::ConversionPatternRewriter &rewriter)
Insert additional blocks that serve as counterparts to the blocks that diverged the control flow.
std::unique_ptr< mlir::OperationPass< mlir::ModuleOp > > createCFToHandshakePass(bool sourceConstants=false, bool disableTaskPipelining=false)
std::unique_ptr< mlir::OperationPass< mlir::ModuleOp > > createHandshakeAnalysisPass()
std::unique_ptr< mlir::OperationPass< handshake::FuncOp > > createHandshakeRemoveBlockPass()
std::unique_ptr< mlir::OperationPass< handshake::FuncOp > > createHandshakeCanonicalizePass()
SmallVector< Backedge > dataEdges
std::optional< Backedge > indexEdge