From 86473ee07e61e2682472df190d7c5ff38f7bf5ec Mon Sep 17 00:00:00 2001 From: Yuri Iozzelli Date: Wed, 18 Dec 2024 10:36:11 +0100 Subject: [PATCH] feat: Handle address spaces in the createCheerp*llocate family of intrinsics For now we just add an AS argument to createCheerpAllocate, with default 0, and we type-erase the first argument for the original function. With proper address spaces it's impractical to keep this type consistent. --- clang/lib/CodeGen/CGBuiltin.cpp | 36 +++++++++++--------- clang/lib/CodeGen/CGException.cpp | 4 +-- clang/lib/CodeGen/CGExprCXX.cpp | 10 +++--- clang/lib/CodeGen/ItaniumCXXABI.cpp | 4 +-- llvm/include/llvm/Cheerp/Utility.h | 7 ++-- llvm/include/llvm/IR/IntrinsicsCheerp.td | 8 ++--- llvm/lib/CheerpUtils/GlobalDepsAnalyzer.cpp | 2 +- llvm/lib/CheerpUtils/PointerPasses.cpp | 2 +- llvm/lib/CheerpUtils/TypeOptimizer.cpp | 22 ++++++------ llvm/lib/CheerpUtils/Utility.cpp | 34 ++++++++++-------- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 4 +-- 11 files changed, 72 insertions(+), 61 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9fa2f1903ead..a8f022bb9eaf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3427,7 +3427,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, QualType returnType=retCE->getType(); Tys[0] = ConvertType(returnType); elementType = ConvertType(returnType->getPointeeType()); - CallBase* CB = cheerp::createCheerpAllocate(Builder, nullptr, elementType, Size); + unsigned AS = getContext().getTargetAddressSpace(returnType->getPointeeType().getAddressSpace()); + CallBase* CB = cheerp::createCheerpAllocate(Builder, nullptr, elementType, Size, AS); return RValue::get(CB); } } @@ -12549,9 +12550,7 @@ Value *CodeGenFunction::EmitCheerpBuiltinExpr(unsigned BuiltinID, else if (BuiltinID == Cheerp::BI__builtin_cheerp_deallocate) { // This is only used in SemaCoroutine, so we just care for the genericjs // case, and for now only void* argument - llvm::Type *Tys[] = { VoidPtrTy, Ops[0]->getType() }; - Function *F = CGM.getIntrinsic(Intrinsic::cheerp_deallocate, Tys); - return EmitCallOrInvoke(F, {ConstantPointerNull::get(VoidPtrTy), Ops[0]}); + return cheerp::createCheerpDeallocate(Builder, nullptr, nullptr, Ops[0]); } else if (BuiltinID == Cheerp::BI__builtin_cheerp_throw) { llvm::Type *Tys[] = { Ops[0]->getType() }; @@ -12684,24 +12683,25 @@ Value *CodeGenFunction::EmitCheerpBuiltinExpr(unsigned BuiltinID, ParentMap PM(FD ? FD->getBody() : const_cast(VD->getInit())); const Stmt* parent=PM.getParent(E); // We need an explicit cast after the call, void* can't be used - llvm::Type *Tys[] = { VoidPtrTy, VoidPtrTy }; const CastExpr* retCE=dyn_cast_or_null(parent); llvm::Type* elementType = nullptr; + unsigned AS = 0; if (!retCE || retCE->getType()->isVoidPointerType()) { if (!asmjs) { CGM.getDiags().Report(E->getBeginLoc(), diag::err_cheerp_alloc_requires_cast); return 0; } + AS = getContext().getTargetAddressSpace(E->getType()->getPointeeType().getAddressSpace()); } else { elementType = ConvertTypeForMem(retCE->getType()->getPointeeType()); - Tys[0] = ConvertType(retCE->getType()); + AS = getContext().getTargetAddressSpace(retCE->getType()->getPointeeType().getAddressSpace()); } - llvm::Function* Malloc = nullptr; + llvm::Constant* Malloc = nullptr; // in Wasm, we pass the original allocation function as argument 0 if (asmjs || (elementType->isStructTy() && cast(elementType)->hasAsmJS())) { - Malloc = dyn_cast(CGM.getModule().getOrInsertFunction("malloc", Int8PtrTy, Int32Ty).getCallee()); + Malloc = cast(CGM.getModule().getOrInsertFunction("malloc", Int8PtrTy, Int32Ty).getCallee()); } - llvm::CallBase* CB = cheerp::createCheerpAllocate(Builder, Malloc, elementType, Ops[0]); + llvm::CallBase* CB = cheerp::createCheerpAllocate(Builder, Malloc, elementType, Ops[0], AS); return CB; } else if (BuiltinID == Builtin::BIcalloc) { @@ -12714,23 +12714,26 @@ Value *CodeGenFunction::EmitCheerpBuiltinExpr(unsigned BuiltinID, // We need an explicit cast after the call, void* can't be used const CastExpr* retCE=dyn_cast_or_null(parent); llvm::Type* elementType = nullptr; + unsigned AS = 0; if (!retCE || retCE->getType()->isVoidPointerType()) { if (!asmjs) { CGM.getDiags().Report(E->getBeginLoc(), diag::err_cheerp_alloc_requires_cast); return 0; } + AS = getContext().getTargetAddressSpace(E->getType()->getPointeeType().getAddressSpace()); } else { elementType = ConvertTypeForMem(retCE->getType()->getPointeeType()); + AS = getContext().getTargetAddressSpace(retCE->getType()->getPointeeType().getAddressSpace()); } - llvm::Function* Malloc = nullptr; + llvm::Constant* Malloc = nullptr; // in Wasm, we pass the original allocation function as argument 0 // in this case malloc and not calloc since we explicitly memset after if (asmjs || (elementType->isStructTy() && cast(elementType)->hasAsmJS())) { - Malloc = dyn_cast(CGM.getModule().getOrInsertFunction("malloc", Int8PtrTy, Int32Ty).getCallee()); + Malloc = cast(CGM.getModule().getOrInsertFunction("malloc", Int8PtrTy, Int32Ty).getCallee()); } // Compute the size in bytes llvm::Value* sizeInBytes = Builder.CreateMul(Ops[0], Ops[1]); - llvm::CallBase* CB = cheerp::createCheerpAllocate(Builder, Malloc, elementType, sizeInBytes); + llvm::CallBase* CB = cheerp::createCheerpAllocate(Builder, Malloc, elementType, sizeInBytes, AS); Builder.CreateMemSet(CB, ConstantInt::get(Int8Ty, 0), sizeInBytes, MaybeAlign(1), false, NULL, NULL, NULL, CGBuilderTy::CheerpTypeInfo::get(getTarget().isByteAddressable(), elementType)); return CB; @@ -12785,7 +12788,7 @@ Value *CodeGenFunction::EmitCheerpBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = Builder.getInt8PtrTy(); llvm::Type *Arg0Ty = Builder.getInt8PtrTy(); llvm::Type *Arg1Ty = Builder.getInt32Ty(); - llvm::Function* origReallocFunc = dyn_cast(CGM.getModule().getOrInsertFunction("realloc", RetTy, Arg0Ty, Arg1Ty).getCallee()); + llvm::Constant* origReallocFunc = cast(CGM.getModule().getOrInsertFunction("realloc", RetTy, Arg0Ty, Arg1Ty).getCallee()); CallBase* CB = cheerp::createCheerpReallocate(Builder, origReallocFunc, elementType, Ops[0], Ops[1]); return CB; } else { @@ -12797,7 +12800,8 @@ Value *CodeGenFunction::EmitCheerpBuiltinExpr(unsigned BuiltinID, Builder.CreateCondBr(opIsNull, mallocBlock, reallocBlock); Builder.SetInsertPoint(mallocBlock); - CallBase* mallocRet = cheerp::createCheerpAllocate(Builder, nullptr, elementType, Ops[1]); + unsigned AS = getContext().getTargetAddressSpace(reallocType->getPointeeType().getAddressSpace()); + CallBase* mallocRet = cheerp::createCheerpAllocate(Builder, nullptr, elementType, Ops[1], AS); Builder.CreateBr(endBlock); Builder.SetInsertPoint(reallocBlock); CallBase* reallocRet = cheerp::createCheerpReallocate(Builder, nullptr, elementType, Ops[0], Ops[1]); @@ -12819,12 +12823,12 @@ Value *CodeGenFunction::EmitCheerpBuiltinExpr(unsigned BuiltinID, Ops[0]=EmitScalarExpr(argCE->getSubExpr()); } } - llvm::Function* Free = nullptr; + llvm::Constant* Free = nullptr; // in Wasm, we pass the original deallocation function as argument 0 // For free, we always pass this argument unless the element type is a genericjs struct, // because the pointer may have come from Wasm originally if (asmjs || (elementType && elementType->isStructTy() && !cast(elementType)->hasAsmJS())) { - Free = dyn_cast(CGM.getModule().getOrInsertFunction("free", VoidTy, Int8PtrTy).getCallee()); + Free = cast(CGM.getModule().getOrInsertFunction("free", VoidTy, Int8PtrTy).getCallee()); } llvm::CallBase* CB = cheerp::createCheerpDeallocate(Builder, Free, elementType, Ops[0]); return CB; diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index cd50b78fe3fd..66107c8d2a47 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -393,12 +393,12 @@ namespace { FreeException(llvm::Value *exn) : exn(exn) {} void Emit(CodeGenFunction &CGF, Flags flags) override { if (CGF.getLangOpts().Cheerp) { - llvm::Function* origFunc = nullptr; + llvm::Constant* origFunc = nullptr; if (CGF.getTarget().getTriple().isCheerpWasm()) { llvm::FunctionType *FreeTy = llvm::FunctionType::get(CGF.VoidTy, CGF.VoidPtrTy, /*isVarArg=*/false); - origFunc = cast(CGF.CGM.CreateRuntimeFunction(FreeTy, "free").getCallee()); + origFunc = cast(CGF.CGM.CreateRuntimeFunction(FreeTy, "free").getCallee()); } cheerp::createCheerpDeallocate(CGF.Builder, origFunc, nullptr, exn); } else { diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index cc643c7c8659..d74048521e48 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1374,19 +1374,19 @@ static RValue EmitNewDeleteCall(CodeGenFunction &CGF, { // Forge a call to a special type safe allocator intrinsic QualType retType = CGF.getContext().getPointerType(allocType); - llvm::Function* origFunc = nullptr; + llvm::Constant* origFunc = nullptr; if (asmjs || (allocType->getAsTagDecl() && allocType->getAsTagDecl()->hasAttr())) { - origFunc = cast(CalleePtr); + origFunc = CalleePtr; } llvm::Type* elementType = CGF.ConvertTypeForMem(retType->getPointeeType()); - CallOrInvoke = cheerp::createCheerpAllocate(CGF.Builder, origFunc, elementType, Args[0].getKnownRValue().getScalarVal(), use_array); + CallOrInvoke = cheerp::createCheerpAllocate(CGF.Builder, origFunc, elementType, Args[0].getKnownRValue().getScalarVal(), 0, use_array); RV = RValue::get(CallOrInvoke); } else if(IsDelete && cheerp && !(asmjs && (user_defined_new || fancy_new))) { - llvm::Function* origFunc = nullptr; + llvm::Constant* origFunc = nullptr; if (asmjs || !(allocType->getAsTagDecl() && allocType->getAsTagDecl()->hasAttr())) { - origFunc = cast(CalleePtr); + origFunc = CalleePtr; } QualType argType = CGF.getContext().getPointerType(allocType); llvm::Type* elementType = CGF.ConvertTypeForMem(argType->getPointeeType()); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index b69bbc0d6ef6..81db06fbf558 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1412,7 +1412,7 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { llvm::CallInst* ExceptionPtr = nullptr; llvm::Value* Size = llvm::ConstantInt::get(SizeTy, TypeSize); if (CGM.getLangOpts().Cheerp) { - llvm::Function* origFunc = nullptr; + llvm::Constant* origFunc = nullptr; // We want to know if this exception is supposed to be allocated as a wasm // or js object // TODO: do it better when we have address spaces @@ -1430,7 +1430,7 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { llvm::FunctionType *MallocTy = llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int32Ty, /*isVarArg=*/false); - origFunc = cast(CGF.CGM.CreateRuntimeFunction(MallocTy, "malloc").getCallee()); + origFunc = cast(CGF.CGM.CreateRuntimeFunction(MallocTy, "malloc").getCallee()); } ExceptionPtr = cheerp::createCheerpAllocate(CGF.Builder, origFunc, elemTy, Size); } else { diff --git a/llvm/include/llvm/Cheerp/Utility.h b/llvm/include/llvm/Cheerp/Utility.h index 22654f79803e..e5e187e11b5a 100644 --- a/llvm/include/llvm/Cheerp/Utility.h +++ b/llvm/include/llvm/Cheerp/Utility.h @@ -280,19 +280,20 @@ inline bool isGEP(const llvm::Value* v) } llvm::CallInst* createCheerpAllocate(llvm::IRBuilderBase& Builder, - llvm::Function* origFunc, + llvm::Constant* origFunc, llvm::Type* elementType, llvm::Value* sizeArg, + unsigned AS = 0, bool use_array = false); llvm::CallInst* createCheerpReallocate(llvm::IRBuilderBase& Builder, - llvm::Function* origFunc, + llvm::Constant* origFunc, llvm::Type* elementType, llvm::Value* ptrArg, llvm::Value* sizeArg); llvm::CallInst* createCheerpDeallocate(llvm::IRBuilderBase& Builder, - llvm::Function* origFunc, + llvm::Constant* origFunc, llvm::Type* elementType, llvm::Value* ptrArg); diff --git a/llvm/include/llvm/IR/IntrinsicsCheerp.td b/llvm/include/llvm/IR/IntrinsicsCheerp.td index 127997440fae..d2735f787504 100644 --- a/llvm/include/llvm/IR/IntrinsicsCheerp.td +++ b/llvm/include/llvm/IR/IntrinsicsCheerp.td @@ -39,15 +39,15 @@ def int_cheerp_cast_user : Intrinsic<[llvm_anyptr_ty], // Type safe memory allocation def int_cheerp_allocate : Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty,llvm_i32_ty]>; + [llvm_ptr_ty,llvm_i32_ty]>; def int_cheerp_allocate_array : Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty,llvm_i32_ty]>; + [llvm_ptr_ty,llvm_i32_ty]>; def int_cheerp_get_array_len : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty]>; def int_cheerp_reallocate : Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty,llvm_anyptr_ty, llvm_i32_ty]>; + [llvm_ptr_ty,llvm_anyptr_ty, llvm_i32_ty]>; def int_cheerp_deallocate : Intrinsic<[], - [llvm_anyptr_ty, llvm_anyptr_ty]>; + [llvm_ptr_ty, llvm_anyptr_ty]>; def int_cheerp_coro_alloc : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>; diff --git a/llvm/lib/CheerpUtils/GlobalDepsAnalyzer.cpp b/llvm/lib/CheerpUtils/GlobalDepsAnalyzer.cpp index c0dbf22ea2a2..78899e41f093 100644 --- a/llvm/lib/CheerpUtils/GlobalDepsAnalyzer.cpp +++ b/llvm/lib/CheerpUtils/GlobalDepsAnalyzer.cpp @@ -265,7 +265,7 @@ bool GlobalDepsAnalyzer::runOnModule( llvm::Module & module ) II == Intrinsic::cheerp_deallocate ) && !isa(ci->getArgOperand(0))) { - Function* OrigFunc = dyn_cast(ci->getOperand(0)); + Function* OrigFunc = dyn_cast(ci->getOperand(0)->stripPointerCastsSafe()); assert(OrigFunc); if (llcPass) { diff --git a/llvm/lib/CheerpUtils/PointerPasses.cpp b/llvm/lib/CheerpUtils/PointerPasses.cpp index 9af39cb57250..6026472c6ba9 100644 --- a/llvm/lib/CheerpUtils/PointerPasses.cpp +++ b/llvm/lib/CheerpUtils/PointerPasses.cpp @@ -628,7 +628,7 @@ bool FreeAndDeleteRemoval::runOnModule(Module& M) } else if (!elemTy || !cheerp::TypeSupport::isAsmJSPointed(elemTy)) { - Function* origF = cast(call->getArgOperand(0)); + Function* origF = cast(call->getArgOperand(0)->stripPointerCastsSafe()); call->setArgOperand(0, getOrCreateGenericJSFree(M, origF)); } } diff --git a/llvm/lib/CheerpUtils/TypeOptimizer.cpp b/llvm/lib/CheerpUtils/TypeOptimizer.cpp index c4ba2f08315e..d5668de73630 100644 --- a/llvm/lib/CheerpUtils/TypeOptimizer.cpp +++ b/llvm/lib/CheerpUtils/TypeOptimizer.cpp @@ -1117,16 +1117,11 @@ Function* TypeOptimizer::rewriteIntrinsic(Function* F, FunctionType* FT) SmallVector newTys; switch(F->getIntrinsicID()) { - case Intrinsic::cheerp_reallocate: - { - Type* localTys[] = { FT->getReturnType(), FT->getParamType(0), FT->getParamType(1)}; - newTys.insert(newTys.end(),localTys,localTys+3); - break; - } - case Intrinsic::cheerp_deallocate: + case Intrinsic::cheerp_allocate: + case Intrinsic::cheerp_allocate_array: { - Type* localTys[] = { FT->getParamType(0), FT->getParamType(1)}; - newTys.insert(newTys.end(),localTys,localTys+2); + Type* localTys[] = { FT->getReturnType()}; + newTys.insert(newTys.end(),localTys,localTys+1); break; } case Intrinsic::cheerp_upcast_collapsed: @@ -1135,13 +1130,17 @@ Function* TypeOptimizer::rewriteIntrinsic(Function* F, FunctionType* FT) case Intrinsic::cheerp_virtualcast: case Intrinsic::cheerp_make_complete_object: case Intrinsic::cheerp_make_regular: - case Intrinsic::cheerp_allocate: - case Intrinsic::cheerp_allocate_array: { Type* localTys[] = { FT->getReturnType(), FT->getParamType(0)}; newTys.insert(newTys.end(),localTys,localTys+2); break; } + case Intrinsic::cheerp_reallocate: + { + Type* localTys[] = { FT->getReturnType(), FT->getParamType(1)}; + newTys.insert(newTys.end(),localTys,localTys+2); + break; + } case Intrinsic::cheerp_downcast_current: case Intrinsic::cheerp_get_array_len: case Intrinsic::cheerp_pointer_kind: @@ -1154,6 +1153,7 @@ Function* TypeOptimizer::rewriteIntrinsic(Function* F, FunctionType* FT) } case Intrinsic::invariant_start: case Intrinsic::invariant_end: + case Intrinsic::cheerp_deallocate: { Type* localTys[] = { FT->getParamType(1) }; newTys.insert(newTys.end(),localTys,localTys+1); diff --git a/llvm/lib/CheerpUtils/Utility.cpp b/llvm/lib/CheerpUtils/Utility.cpp index 33b9e0386b1d..06ed80b137a7 100644 --- a/llvm/lib/CheerpUtils/Utility.cpp +++ b/llvm/lib/CheerpUtils/Utility.cpp @@ -611,17 +611,19 @@ uint32_t getIntFromValue(const Value* v) CallInst* createCheerpAllocate(IRBuilderBase& Builder, - Function* origFunc, + Constant* origFunc, Type* elementType, Value* sizeArg, + unsigned AS, bool use_array) { - unsigned AS = 0; + PointerType* PtrTy = Builder.getInt8PtrTy(); auto Intr = use_array? Intrinsic::cheerp_allocate_array : Intrinsic::cheerp_allocate; - PointerType* origFuncTy = origFunc? origFunc->getFunctionType()->getPointerTo(origFunc->getAddressSpace()) : Builder.getInt8PtrTy(); Type* retTy = elementType? elementType->getPointerTo(AS) : Builder.getInt8PtrTy(AS); - Type* Tys[] = { retTy, origFuncTy }; - Constant* origFuncArg = origFunc? (Constant*)origFunc : (Constant*)ConstantPointerNull::get(origFuncTy); + Type* Tys[] = { retTy }; + Constant* origFuncArg = origFunc? + (Constant*)Builder.CreatePointerBitCastOrAddrSpaceCast(origFunc, PtrTy) : + (Constant*)ConstantPointerNull::get(PtrTy); CallInst* Call = Builder.CreateIntrinsic(Intr, Tys, {origFuncArg, sizeArg}); if (elementType) { @@ -630,16 +632,18 @@ CallInst* createCheerpAllocate(IRBuilderBase& Builder, return Call; } llvm::CallInst* createCheerpReallocate(llvm::IRBuilderBase& Builder, - llvm::Function* origFunc, + llvm::Constant* origFunc, llvm::Type* elementType, llvm::Value* ptrArg, llvm::Value* sizeArg) { - unsigned AS = 0; - PointerType* origFuncTy = origFunc? origFunc->getFunctionType()->getPointerTo(origFunc->getAddressSpace()) : Builder.getInt8PtrTy(); + PointerType* PtrTy = Builder.getInt8PtrTy(); + unsigned AS = cast(ptrArg->getType())->getAddressSpace(); Type* retTy = elementType? elementType->getPointerTo(AS) : Builder.getInt8PtrTy(AS); - Type* Tys[] = { retTy, origFuncTy, ptrArg->getType() }; - Constant* origFuncArg = origFunc? (Constant*)origFunc : (Constant*)ConstantPointerNull::get(origFuncTy); + Type* Tys[] = { retTy, ptrArg->getType() }; + Constant* origFuncArg = origFunc? + (Constant*)Builder.CreatePointerBitCastOrAddrSpaceCast(origFunc, PtrTy) : + (Constant*)ConstantPointerNull::get(PtrTy); CallInst* Call = Builder.CreateIntrinsic(Intrinsic::cheerp_reallocate, Tys, {origFuncArg, ptrArg, sizeArg}); if (elementType) { @@ -650,13 +654,15 @@ llvm::CallInst* createCheerpReallocate(llvm::IRBuilderBase& Builder, } llvm::CallInst* createCheerpDeallocate(llvm::IRBuilderBase& Builder, - llvm::Function* origFunc, + llvm::Constant* origFunc, llvm::Type* elementType, llvm::Value* ptrArg) { - PointerType* origFuncTy = origFunc? origFunc->getFunctionType()->getPointerTo(origFunc->getAddressSpace()) : Builder.getInt8PtrTy(); - Type* Tys[] = { origFuncTy, ptrArg->getType() }; - Constant* origFuncArg = origFunc? (Constant*)origFunc : (Constant*)ConstantPointerNull::get(origFuncTy); + PointerType* PtrTy = Builder.getInt8PtrTy(); + Type* Tys[] = { ptrArg->getType() }; + Constant* origFuncArg = origFunc? + (Constant*)Builder.CreatePointerBitCastOrAddrSpaceCast(origFunc, PtrTy) : + (Constant*)ConstantPointerNull::get(PtrTy); CallInst* Call = Builder.CreateIntrinsic(Intrinsic::cheerp_deallocate, Tys, {origFuncArg, ptrArg}); if (elementType) { diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index a7cdf483595e..db7314f6352c 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1565,9 +1565,9 @@ static void createFramePtr(coro::Shape &Shape) { if (Shape.CheerpCoroAlloc) { // CHEERP: Replace cheerp_coro_alloc with cheerp_allocate, now that we know the // final frame type - Function* Malloc = nullptr; + Constant* Malloc = nullptr; if (FrameTy->hasAsmJS()) { - Malloc = cast(M->getOrInsertFunction("malloc", Builder.getInt8PtrTy(), Builder.getInt32Ty()).getCallee()); + Malloc = cast(M->getOrInsertFunction("malloc", Builder.getInt8PtrTy(), Builder.getInt32Ty()).getCallee()); } Builder.SetInsertPoint(Shape.CheerpCoroAlloc); CallBase* Alloc = cheerp::createCheerpAllocate(Builder, Malloc, FrameTy, Shape.CheerpCoroAlloc->getOperand(0));