================ @@ -1455,6 +1462,74 @@ struct SwitchCoroutineSplitter { setCoroInfo(F, Shape, Clones); } + // Create a variant of ramp function that does not perform heap allocation + // for a switch ABI coroutine. + // + // The newly split `.noalloc` ramp function has the following differences: + // - Has one additional frame pointer parameter in lieu of dynamic + // allocation. + // - Suppressed allocations by replacing coro.alloc and coro.free. + static Function *createNoAllocVariant(Function &F, coro::Shape &Shape, + SmallVectorImpl<Function *> &Clones) { + auto *OrigFnTy = F.getFunctionType(); + auto OldParams = OrigFnTy->params(); + + SmallVector<Type *> NewParams; + NewParams.reserve(OldParams.size() + 1); + NewParams.append(OldParams.begin(), OldParams.end()); + NewParams.push_back(PointerType::getUnqual(Shape.FrameTy)); + + auto *NewFnTy = FunctionType::get(OrigFnTy->getReturnType(), NewParams, + OrigFnTy->isVarArg()); + Function *NoAllocF = + Function::Create(NewFnTy, F.getLinkage(), F.getName() + ".noalloc"); + + ValueToValueMapTy VMap; + unsigned int Idx = 0; + for (const auto &I : F.args()) { + VMap[&I] = NoAllocF->getArg(Idx++); + } + SmallVector<ReturnInst *, 4> Returns; + CloneFunctionInto(NoAllocF, &F, VMap, + CloneFunctionChangeType::LocalChangesOnly, Returns); + + if (Shape.CoroBegin) { + auto *NewCoroBegin = + cast_if_present<CoroBeginInst>(VMap[Shape.CoroBegin]); + auto *NewCoroId = cast<CoroIdInst>(NewCoroBegin->getId()); + coro::replaceCoroFree(NewCoroId, /*Elide=*/true); + coro::suppressCoroAllocs(NewCoroId); + NewCoroBegin->replaceAllUsesWith(NoAllocF->getArg(Idx)); ---------------- ChuanqiXu9 wrote:
nit: it looks better to use `FrameIdx` below instead of using the induction variable across code sections. https://github.com/llvm/llvm-project/pull/99283 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits