19 for (
const auto &vals : values)
20 llvm::append_range(
result, vals);
27struct CallOpSignatureConversion :
public OpConversionPattern<CallOp> {
28 using OpConversionPattern<CallOp>::OpConversionPattern;
32 matchAndRewrite(CallOp callOp, OneToNOpAdaptor adaptor,
33 ConversionPatternRewriter &rewriter)
const override {
36 SmallVector<size_t> numResultsReplacments;
37 SmallVector<Type, 1> convertedResults;
38 size_t numFlattenedResults = 0;
39 for (
auto [idx, type] : llvm::enumerate(callOp.getResultTypes())) {
40 if (
failed(typeConverter->convertTypes(type, convertedResults)))
42 numResultsReplacments.push_back(convertedResults.size() -
44 numFlattenedResults = convertedResults.size();
50 CallOp::create(rewriter, callOp.getLoc(), callOp.getCallee(),
52 SmallVector<ValueRange> replacements;
54 for (
int i = 0, e = callOp->getNumResults(); i < e; ++i) {
55 replacements.push_back(
56 newCallOp->getResults().slice(offset, numResultsReplacments[i]));
57 offset += numResultsReplacments[i];
59 assert(offset == convertedResults.size() &&
60 "expected that all converted results are used");
61 rewriter.replaceOpWithMultiple(callOp, replacements);
78class BranchOpInterfaceTypeConversion
79 :
public OpInterfaceConversionPattern<BranchOpInterface> {
81 using OpInterfaceConversionPattern<
82 BranchOpInterface>::OpInterfaceConversionPattern;
84 BranchOpInterfaceTypeConversion(
86 function_ref<
bool(BranchOpInterface,
int)> shouldConvertBranchOperand,
88 : OpInterfaceConversionPattern(typeConverter, ctx, benefit),
89 shouldConvertBranchOperand(shouldConvertBranchOperand) {}
92 matchAndRewrite(BranchOpInterface op, ArrayRef<Value> operands,
93 ConversionPatternRewriter &rewriter)
const final {
96 SmallVector<Value, 4> newOperands(op->operand_begin(), op->operand_end());
97 for (
int succIdx = 0, succEnd = op->getBlock()->getNumSuccessors();
98 succIdx < succEnd; ++succIdx) {
99 OperandRange forwardedOperands =
100 op.getSuccessorOperands(succIdx).getForwardedOperands();
101 if (forwardedOperands.empty())
105 eidx = idx + forwardedOperands.size();
107 if (!shouldConvertBranchOperand || shouldConvertBranchOperand(op, idx))
108 newOperands[idx] = operands[idx];
111 rewriter.modifyOpInPlace(
112 op, [newOperands, op]() { op->setOperands(newOperands); });
117 function_ref<bool(BranchOpInterface,
int)> shouldConvertBranchOperand;
125class ReturnOpTypeConversion :
public OpConversionPattern<ReturnOp> {
127 using OpConversionPattern<ReturnOp>::OpConversionPattern;
130 matchAndRewrite(ReturnOp op, OneToNOpAdaptor adaptor,
131 ConversionPatternRewriter &rewriter)
const final {
132 rewriter.replaceOpWithNewOp<ReturnOp>(op,
141 function_ref<
bool(BranchOpInterface,
int)> shouldConvertBranchOperand,
143 patterns.add<BranchOpInterfaceTypeConversion>(
144 typeConverter,
patterns.getContext(), shouldConvertBranchOperand,
151 if (
auto branchOp = dyn_cast<BranchOpInterface>(op)) {
153 auto successorOperands = branchOp.getSuccessorOperands(p);
154 if (!converter.isLegal(
155 successorOperands.getForwardedOperands().getTypes()))
176 if (isa<ReturnOp>(op) && !returnOpAlwaysLegal)
177 return converter.isLegal(op);
192 if (!block || &block->
back() != op)
static SmallVector< Value > flattenValues(ArrayRef< ValueRange > values)
Flatten the given value ranges into a single vector of values.
Block represents an ordered list of Operations.
unsigned getNumSuccessors()
MLIRContext is the top-level object for a collection of MLIR operations.
This class provides the API for ops that are known to be terminators.
unsigned getBeginOperandIndex() const
Return the operand index of the first element of this range.
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Block * getBlock()
Returns the operation block that contains this operation.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
Include the generated interface declarations.
bool isLegalForReturnOpTypeConversionPattern(Operation *op, const TypeConverter &converter, bool returnOpAlwaysLegal=false)
For ReturnLike ops (except return), return True.
void populateReturnOpTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter, PatternBenefit benefit=1)
Add a pattern to the given pattern list to rewrite return ops to use operands that have been legalize...
void populateCallOpTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter, PatternBenefit benefit=1)
Add a pattern to the given pattern list to convert the operand and result types of a CallOp with the ...
bool isNotBranchOpInterfaceOrReturnLikeOp(Operation *op)
Return true if op is neither BranchOpInterface nor ReturnLike.
void populateBranchOpInterfaceTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter, function_ref< bool(BranchOpInterface branchOp, int idx)> shouldConvertBranchOperand=nullptr, PatternBenefit benefit=1)
Add a pattern to the given pattern list to rewrite branch operations to use operands that have been l...
const FrozenRewritePatternSet & patterns
llvm::function_ref< Fn > function_ref
bool isLegalForBranchOpInterfaceTypeConversionPattern(Operation *op, const TypeConverter &converter)
Return true if op is a BranchOpInterface op whose operands are all legal according to converter.
This trait indicates that a terminator operation is "return-like".