14 #ifndef CIRCT_CONVERSION_CFTOHANDSHAKE_H_
15 #define CIRCT_CONVERSION_CFTOHANDSHAKE_H_
21 #include "mlir/Transforms/DialectConversion.h"
39 llvm::function_ref<LogicalResult(Region &, ConversionPatternRewriter &)>;
43 MLIRContext *ctx, Region &r);
61 using BlockOps = DenseMap<Block *, std::vector<MergeOpInfo>>;
64 llvm::MapVector<Value, std::vector<Operation *>>;
68 LogicalResult
addMergeOps(ConversionPatternRewriter &rewriter);
69 LogicalResult
addBranchOps(ConversionPatternRewriter &rewriter);
72 template <
typename TSrcTerm,
typename TDstTerm>
75 assert(entryCtrl.getType().isa<NoneType>() &&
76 "Expected NoneType for entry control value");
78 Block *entryBlock = &
r.front();
83 for (
auto retOp : llvm::make_early_inc_range(
r.getOps<TSrcTerm>())) {
84 rewriter.setInsertionPoint(retOp);
85 SmallVector<Value, 8> operands(retOp->getOperands());
86 operands.push_back(entryCtrl);
87 rewriter.replaceOpWithNewOp<TDstTerm>(retOp, operands);
91 DenseMap<Block *, unsigned> numArgsPerBlock;
92 for (
auto &block :
r.getBlocks())
93 numArgsPerBlock[&block] = block.getNumArguments();
104 for (
auto &[block, numArgs] : numArgsPerBlock)
105 if (block->getNumArguments() != numArgs)
112 bool sourceConstants);
118 ConversionPatternRewriter &rewriter);
123 ConversionPatternRewriter &rewriter);
135 ArrayRef<Operation *> memOps, Operation *memOp,
136 int offset, ArrayRef<int> cntrlInd);
160 template <
typename T,
typename... TArgs,
typename... TArgs2>
163 LogicalResult (T::*memberFunc)(ConversionPatternRewriter &, TArgs2...),
166 [&](Region &, ConversionPatternRewriter &rewriter) -> LogicalResult {
167 return (instance.*memberFunc)(rewriter, args...);
169 instance.getContext(), instance.getRegion());
182 template <
typename TSrcTerm,
typename TDstTerm>
184 bool disableTaskPipelining, Value entryCtrl) {
193 hl, &HandshakeLowering::setControlOnlyPath<TSrcTerm, TDstTerm>,
206 if (!disableTaskPipelining) {
237 std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
240 std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
242 bool disableTaskPipelining =
false);
244 std::unique_ptr<mlir::OperationPass<handshake::FuncOp>>
247 std::unique_ptr<mlir::OperationPass<handshake::FuncOp>>
assert(baseType &&"element must be base type")
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
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)
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
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.
LogicalResult maximizeSSA(Value value, PatternRewriter &rewriter)
Converts a single value within a function into maximal SSA form.
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