83 auto canModify = [&](func::FuncOp funcOp) {
84 return funcOp->getParentOp() ==
module.getOperation() &&
85 !funcOp.isExternal() &&
86 (!funcOp.isPublic() || options.modifyPublicFunctions);
91 module.walk([&](func::CallOp callOp) {
92 if (func::FuncOp calledFunc =
93 dyn_cast_or_null<func::FuncOp>(callOp.resolveCallable())) {
94 if (canModify(calledFunc))
95 callerMap[calledFunc].push_back(callOp);
106 for (
auto funcOp : module.getOps<
func::FuncOp>())
107 if (canModify(funcOp))
108 worklist.insert(funcOp);
110 while (!worklist.empty()) {
111 func::FuncOp funcOp = worklist.pop_back_val();
112 SmallVector<func::ReturnOp> returnOps = getReturnOps(funcOp);
113 if (returnOps.empty())
117 size_t numReturnOps = returnOps.size();
118 size_t numReturnValues = funcOp.getFunctionType().getNumResults();
119 SmallVector<SmallVector<Value>> newReturnValues(numReturnOps);
120 BitVector erasedResultIndices(numReturnValues);
121 DenseMap<int64_t, int64_t> resultToArgs;
122 for (size_t i = 0; i < numReturnValues; ++i) {
124 SmallVector<Value> returnOperands =
125 getReturnOpsOperandInPos(returnOps, i);
126 for (BlockArgument bbArg : funcOp.getArguments()) {
127 if (operandsEqualFuncArgument(returnOperands, bbArg)) {
128 resultToArgs[i] = bbArg.getArgNumber();
135 erasedResultIndices.set(i);
137 for (auto [newReturnValue, operand] :
138 llvm::zip(newReturnValues, returnOperands)) {
139 newReturnValue.push_back(operand);
144 if (erasedResultIndices.none())
148 if (failed(funcOp.eraseResults(erasedResultIndices)))
151 for (
auto [returnOp, newReturnValue] :
152 llvm::zip(returnOps, newReturnValues))
153 returnOp.getOperandsMutable().assign(newReturnValue);
157 callOps.swap(callerMap[funcOp]);
158 for (func::CallOp callOp : callOps) {
159 func::FuncOp caller = callOp->getParentOfType<func::FuncOp>();
160 rewriter.setInsertionPoint(callOp);
161 auto newCallOp = func::CallOp::create(rewriter, callOp.getLoc(), funcOp,
162 callOp.getOperands());
165 for (
int64_t i = 0; i < callOp.getNumResults(); ++i) {
166 if (!resultToArgs.count(i)) {
168 newResults.push_back(newCallOp.getResult(nextResult++));
174 Type expectedType = callOp.getResult(i).getType();
177 replacement = memref::CastOp::create(rewriter, callOp.getLoc(),
182 rewriter.replaceOp(callOp, newResults);
183 callerMap[funcOp].push_back(newCallOp);
184 if (caller && canModify(caller))
185 worklist.insert(caller);