17 #include "llvm/ADT/SmallVector.h"
21 FailureOr<func::FuncOp>
27 assert(funcOp.getNumArguments() == newArgsOrder.size() &&
28 "newArgsOrder must match the number of arguments in the function");
29 assert(funcOp.getNumResults() == newResultsOrder.size() &&
30 "newResultsOrder must match the number of results in the function");
32 if (!funcOp.getBody().hasOneBlock())
34 funcOp,
"expected function to have exactly one block");
36 ArrayRef<Type> origInputTypes = funcOp.getFunctionType().getInputs();
37 ArrayRef<Type> origOutputTypes = funcOp.getFunctionType().getResults();
40 for (
unsigned int idx : newArgsOrder) {
41 newInputTypes.push_back(origInputTypes[idx]);
42 locs.push_back(funcOp.getArgument(newArgsOrder[idx]).getLoc());
44 for (
unsigned int idx : newResultsOrder)
45 newOutputTypes.push_back(origOutputTypes[idx]);
47 auto newFuncOp = func::FuncOp::create(
48 rewriter, funcOp.getLoc(), funcOp.getName(),
51 Region &newRegion = newFuncOp.getBody();
53 newFuncOp.setVisibility(funcOp.getVisibility());
54 newFuncOp->setDiscardableAttrs(funcOp->getDiscardableAttrDictionary());
60 funcOp.getAllArgAttrs(argAttrs);
61 for (
unsigned int i = 0; i < newArgsOrder.size(); ++i) {
62 operandMapper.
map(funcOp.getArgument(newArgsOrder[i]),
63 newFuncOp.getArgument(i));
64 newFuncOp.setArgAttrs(i, argAttrs[newArgsOrder[i]]);
66 funcOp.getAllResultAttrs(resultAttrs);
67 for (
unsigned int i = 0; i < newResultsOrder.size(); ++i)
68 newFuncOp.setResultAttrs(i, resultAttrs[newResultsOrder[i]]);
73 rewriter.
clone(op, operandMapper);
76 auto returnOp = cast<func::ReturnOp>(
77 newFuncOp.getFunctionBody().begin()->getTerminator());
79 for (
unsigned int idx : newResultsOrder)
80 newReturnValues.push_back(returnOp.getOperand(idx));
83 func::ReturnOp::create(rewriter, newFuncOp.getLoc(), newReturnValues);
84 newReturnOp->setDiscardableAttrs(returnOp->getDiscardableAttrDictionary());
97 callOp.getNumOperands() == newArgsOrder.size() &&
98 "newArgsOrder must match the number of operands in the call operation");
100 callOp.getNumResults() == newResultsOrder.size() &&
101 "newResultsOrder must match the number of results in the call operation");
103 for (
unsigned int argIdx : newArgsOrder)
104 newArgsOrderValues.push_back(callOp.getOperand(argIdx));
106 for (
unsigned int resIdx : newResultsOrder)
107 newResultTypes.push_back(callOp.getResult(resIdx).getType());
113 func::CallOp::create(rewriter, callOp.getLoc(), callOp.getCallee(),
114 newResultTypes, newArgsOrderValues);
115 newCallOp.setNoInlineAttr(callOp.getNoInlineAttr());
118 newCallOp.getResult(newIndex));
FunctionType getFunctionType(TypeRange inputs, TypeRange results)
This is a utility class for mapping one set of IR entities to another.
void map(Value from, Value to)
Inserts a new mapping for 'from' to 'to'.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
Operation * clone(Operation &op, IRMapping &mapper)
Creates a deep copy of the specified operation, remapping any operands that use values outside of the...
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Operation is the basic unit of execution within MLIR.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the listener that the IR failed to be rewritten because of a match failure,...
void replaceAllUsesWith(Value from, Value to)
Find uses of from and replace them with to.
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
CallOp replaceCallOpWithNewOrder(RewriterBase &rewriter, CallOp callOp, llvm::ArrayRef< unsigned > newArgsOrder, llvm::ArrayRef< unsigned > newResultsOrder)
Creates a new call operation with the values as the original call operation, but with the arguments r...
FailureOr< FuncOp > replaceFuncWithNewOrder(RewriterBase &rewriter, FuncOp funcOp, llvm::ArrayRef< unsigned > newArgsOrder, llvm::ArrayRef< unsigned > newResultsOrder)
Creates a new function operation with the same name as the original function operation,...
Include the generated interface declarations.