19 for (
const auto &vals : values)
20 llvm::append_range(result, vals);
32 matchAndRewrite(CallOp callOp, OneToNOpAdaptor adaptor,
38 size_t numFlattenedResults = 0;
40 if (failed(typeConverter->convertTypes(type, convertedResults)))
42 numResultsReplacments.push_back(convertedResults.size() -
44 numFlattenedResults = convertedResults.size();
49 auto newCallOp = rewriter.
create<CallOp>(
50 callOp.getLoc(), callOp.getCallee(), convertedResults,
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");
76 class BranchOpInterfaceTypeConversion
82 BranchOpInterfaceTypeConversion(
84 function_ref<
bool(BranchOpInterface,
int)> shouldConvertBranchOperand)
86 shouldConvertBranchOperand(shouldConvertBranchOperand) {}
94 for (
int succIdx = 0, succEnd = op->getBlock()->getNumSuccessors();
95 succIdx < succEnd; ++succIdx) {
97 op.getSuccessorOperands(succIdx).getForwardedOperands();
98 if (forwardedOperands.empty())
102 eidx = idx + forwardedOperands.size();
104 if (!shouldConvertBranchOperand || shouldConvertBranchOperand(op, idx))
105 newOperands[idx] = operands[idx];
109 op, [newOperands, op]() { op->setOperands(newOperands); });
114 function_ref<bool(BranchOpInterface,
int)> shouldConvertBranchOperand;
127 matchAndRewrite(ReturnOp op, OneToNOpAdaptor adaptor,
138 function_ref<
bool(BranchOpInterface,
int)> shouldConvertBranchOperand) {
139 patterns.add<BranchOpInterfaceTypeConversion>(
140 typeConverter,
patterns.getContext(), shouldConvertBranchOperand);
146 if (
auto branchOp = dyn_cast<BranchOpInterface>(op)) {
148 auto successorOperands = branchOp.getSuccessorOperands(p);
150 successorOperands.getForwardedOperands().getTypes()))
169 if (isa<ReturnOp>(op) && !returnOpAlwaysLegal)
185 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()
This class implements a pattern rewriter for use with ConversionPatterns.
void replaceOpWithMultiple(Operation *op, ArrayRef< ValueRange > newValues)
Replace the given operation with the new value ranges.
MLIRContext is the top-level object for a collection of MLIR operations.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
OpConversionPattern is a wrapper around ConversionPattern that allows for matching and rewriting agai...
OpInterfaceConversionPattern is a wrapper around ConversionPattern that allows for matching and rewri...
This class provides the API for ops that are known to be terminators.
This class implements the operand iterators for the Operation class.
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.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Block * getBlock()
Returns the operation block that contains this operation.
void modifyOpInPlace(Operation *root, CallableT &&callable)
This method is a utility wrapper around an in-place modification of an operation.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
bool isLegal(Type type) const
Return true if the given type is legal for this type converter, i.e.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
bool isLegalForReturnOpTypeConversionPattern(Operation *op, const TypeConverter &converter, bool returnOpAlwaysLegal=false)
For ReturnLike ops (except return), return True.
bool isNotBranchOpInterfaceOrReturnLikeOp(Operation *op)
Return true if op is neither BranchOpInterface nor ReturnLike.
const FrozenRewritePatternSet & patterns
void populateBranchOpInterfaceTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter, function_ref< bool(BranchOpInterface branchOp, int idx)> shouldConvertBranchOperand=nullptr)
Add a pattern to the given pattern list to rewrite branch operations to use operands that have been l...
void populateCallOpTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter)
Add a pattern to the given pattern list to convert the operand and result types of a CallOp with the ...
void populateReturnOpTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter)
Add a pattern to the given pattern list to rewrite return ops to use operands that have been legalize...
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".