mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CoroutineAccessors] Open code alloc fn.
Replace the runtime function with an open-coded version.
This commit is contained in:
@@ -22,9 +22,6 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
SWIFT_RUNTIME_EXPORT
|
|
||||||
SWIFT_CC(swift) void *swift_coro_alloc(CoroAllocator *allocator, size_t size);
|
|
||||||
|
|
||||||
SWIFT_RUNTIME_EXPORT
|
SWIFT_RUNTIME_EXPORT
|
||||||
SWIFT_CC(swift) void swift_coro_dealloc(CoroAllocator *allocator, void *ptr);
|
SWIFT_CC(swift) void swift_coro_dealloc(CoroAllocator *allocator, void *ptr);
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|||||||
@@ -3008,16 +3008,6 @@ FUNCTION(MemsetS, c, memset_s, C_CC, AlwaysAvailable,
|
|||||||
EFFECT(RuntimeEffect::NoEffect),
|
EFFECT(RuntimeEffect::NoEffect),
|
||||||
UNKNOWN_MEMEFFECTS)
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
// void *swift_coro_alloc(CoroAllocator *, size_t size);
|
|
||||||
FUNCTION(CoroAlloc,
|
|
||||||
Swift, swift_coro_alloc, SwiftCC,
|
|
||||||
CoroutineAccessorsAvailability,
|
|
||||||
RETURNS(Int8PtrTy),
|
|
||||||
ARGS(CoroAllocatorPtrTy, SizeTy),
|
|
||||||
NO_ATTRS,
|
|
||||||
EFFECT(RuntimeEffect::Allocating, RuntimeEffect::Concurrency),
|
|
||||||
UNKNOWN_MEMEFFECTS)
|
|
||||||
|
|
||||||
// void swift_coro_dealloc(CoroAllocator *, void *ptr);
|
// void swift_coro_dealloc(CoroAllocator *, void *ptr);
|
||||||
FUNCTION(CoroDealloc,
|
FUNCTION(CoroDealloc,
|
||||||
Swift, swift_coro_dealloc, SwiftCC,
|
Swift, swift_coro_dealloc, SwiftCC,
|
||||||
|
|||||||
@@ -5118,39 +5118,59 @@ void irgen::emitYieldManyCoroutineEntry(
|
|||||||
allocFn, deallocFn, {});
|
allocFn, deallocFn, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
static llvm::Constant *getCoroAllocWrapperFn(IRGenModule &IGM) {
|
static llvm::Constant *getCoroAllocFn(IRGenModule &IGM) {
|
||||||
|
auto isSwiftCoroCCAvailable = IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro;
|
||||||
return IGM.getOrCreateHelperFunction(
|
return IGM.getOrCreateHelperFunction(
|
||||||
"__swift_coro_alloc_", IGM.Int8PtrTy,
|
"_swift_coro_alloc", IGM.Int8PtrTy, {IGM.CoroAllocatorPtrTy, IGM.SizeTy},
|
||||||
{IGM.CoroAllocatorPtrTy, IGM.SizeTy},
|
[isSwiftCoroCCAvailable](IRGenFunction &IGF) {
|
||||||
[](IRGenFunction &IGF) {
|
|
||||||
auto parameters = IGF.collectParameters();
|
auto parameters = IGF.collectParameters();
|
||||||
auto *allocator = parameters.claimNext();
|
auto *allocator = parameters.claimNext();
|
||||||
auto *size = parameters.claimNext();
|
auto *size = parameters.claimNext();
|
||||||
auto *nullAllocator = IGF.Builder.CreateCmp(
|
if (isSwiftCoroCCAvailable) {
|
||||||
llvm::CmpInst::Predicate::ICMP_EQ, allocator,
|
// swiftcorocc is available, so if there's no allocator pointer,
|
||||||
llvm::ConstantPointerNull::get(
|
// allocate storage on the stack and return a pointer to it without
|
||||||
cast<llvm::PointerType>(allocator->getType())));
|
// popping the stack.
|
||||||
auto *poplessReturn = IGF.createBasicBlock("coro.return.popless");
|
auto *nullAllocator = IGF.Builder.CreateCmp(
|
||||||
auto *normalReturn = IGF.createBasicBlock("coro.return.normal");
|
llvm::CmpInst::Predicate::ICMP_EQ, allocator,
|
||||||
IGF.Builder.CreateCondBr(nullAllocator, poplessReturn, normalReturn);
|
llvm::ConstantPointerNull::get(
|
||||||
IGF.Builder.emitBlock(poplessReturn);
|
cast<llvm::PointerType>(allocator->getType())));
|
||||||
// Emit the dynamic alloca.
|
auto *poplessReturn = IGF.createBasicBlock("popless");
|
||||||
auto *alloca =
|
auto *normalReturn = IGF.createBasicBlock("normal");
|
||||||
IGF.Builder.IRBuilderBase::CreateAlloca(IGF.IGM.Int8Ty, size);
|
IGF.Builder.CreateCondBr(nullAllocator, poplessReturn, normalReturn);
|
||||||
alloca->setAlignment(llvm::Align(MaximumAlignment));
|
IGF.Builder.emitBlock(poplessReturn);
|
||||||
auto *retPopless = IGF.Builder.CreateIntrinsic(
|
// Emit the dynamic alloca.
|
||||||
IGF.IGM.VoidTy, llvm::Intrinsic::ret_popless, {});
|
auto *alloca =
|
||||||
retPopless->setTailCallKind(llvm::CallInst::TailCallKind::TCK_MustTail);
|
IGF.Builder.IRBuilderBase::CreateAlloca(IGF.IGM.Int8Ty, size);
|
||||||
IGF.Builder.CreateRet(alloca);
|
alloca->setAlignment(llvm::Align(MaximumAlignment));
|
||||||
IGF.Builder.emitBlock(normalReturn);
|
auto *retPopless = IGF.Builder.CreateIntrinsic(
|
||||||
auto *call = IGF.Builder.CreateCall(
|
IGF.IGM.VoidTy, llvm::Intrinsic::ret_popless, {});
|
||||||
IGF.IGM.getCoroAllocFunctionPointer(), {allocator, size});
|
retPopless->setTailCallKind(
|
||||||
|
llvm::CallInst::TailCallKind::TCK_MustTail);
|
||||||
|
IGF.Builder.CreateRet(alloca);
|
||||||
|
// Start emitting the "normal" block.
|
||||||
|
IGF.Builder.emitBlock(normalReturn);
|
||||||
|
}
|
||||||
|
auto *calleePtr = IGF.Builder.CreateInBoundsGEP(
|
||||||
|
IGF.IGM.CoroAllocatorTy, allocator,
|
||||||
|
{llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0),
|
||||||
|
llvm::ConstantInt::get(IGF.IGM.Int32Ty, 1)});
|
||||||
|
auto *callee = IGF.Builder.CreateLoad(
|
||||||
|
Address(calleePtr, IGF.IGM.CoroAllocateFnTy->getPointerTo(),
|
||||||
|
IGF.IGM.getPointerAlignment()),
|
||||||
|
"allocate_fn");
|
||||||
|
auto fnPtr = FunctionPointer::createUnsigned(
|
||||||
|
FunctionPointer::Kind::Function, callee,
|
||||||
|
Signature(cast<llvm::FunctionType>(IGF.IGM.CoroAllocateFnTy), {},
|
||||||
|
IGF.IGM.SwiftCC));
|
||||||
|
auto *call = IGF.Builder.CreateCall(fnPtr, {size});
|
||||||
|
call->setDoesNotThrow();
|
||||||
|
call->setCallingConv(IGF.IGM.SwiftCC);
|
||||||
IGF.Builder.CreateRet(call);
|
IGF.Builder.CreateRet(call);
|
||||||
},
|
},
|
||||||
/*setIsNoInline=*/false,
|
/*setIsNoInline=*/true,
|
||||||
/*forPrologue=*/false,
|
/*forPrologue=*/false,
|
||||||
/*isPerformanceConstraint=*/false,
|
/*isPerformanceConstraint=*/false,
|
||||||
/*optionalLinkageOverride=*/nullptr, llvm::CallingConv::SwiftCoro);
|
/*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static llvm::Constant *getCoroDeallocWrapperFn(IRGenModule &IGM) {
|
static llvm::Constant *getCoroDeallocWrapperFn(IRGenModule &IGM) {
|
||||||
@@ -5190,9 +5210,7 @@ void irgen::emitYieldOnce2CoroutineEntry(IRGenFunction &IGF,
|
|||||||
IGF.setCoroutineAllocator(allocator);
|
IGF.setCoroutineAllocator(allocator);
|
||||||
auto isSwiftCoroCCAvailable =
|
auto isSwiftCoroCCAvailable =
|
||||||
IGF.IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro;
|
IGF.IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro;
|
||||||
auto allocFn = IGF.IGM.getOpaquePtr(isSwiftCoroCCAvailable
|
auto allocFn = IGF.IGM.getOpaquePtr(getCoroAllocFn(IGF.IGM));
|
||||||
? getCoroAllocWrapperFn(IGF.IGM)
|
|
||||||
: IGF.IGM.getCoroAllocFn());
|
|
||||||
auto deallocFn = IGF.IGM.getOpaquePtr(isSwiftCoroCCAvailable
|
auto deallocFn = IGF.IGM.getOpaquePtr(isSwiftCoroCCAvailable
|
||||||
? getCoroDeallocWrapperFn(IGF.IGM)
|
? getCoroDeallocWrapperFn(IGF.IGM)
|
||||||
: IGF.IGM.getCoroDeallocFn());
|
: IGF.IGM.getCoroDeallocFn());
|
||||||
|
|||||||
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
void *swift::swift_coro_alloc(CoroAllocator *allocator, size_t size) {
|
|
||||||
return allocator->allocate(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swift::swift_coro_dealloc(CoroAllocator *allocator, void *ptr) {
|
void swift::swift_coro_dealloc(CoroAllocator *allocator, void *ptr) {
|
||||||
assert(allocator);
|
assert(allocator);
|
||||||
// Calls to swift_coro_dealloc are emitted in resume funclets for every
|
// Calls to swift_coro_dealloc are emitted in resume funclets for every
|
||||||
|
|||||||
@@ -24,6 +24,21 @@
|
|||||||
// CHECK-SAME: swift_task_dealloc
|
// CHECK-SAME: swift_task_dealloc
|
||||||
// CHECK-SAME: }
|
// CHECK-SAME: }
|
||||||
|
|
||||||
|
// CHECK-LABEL: @_swift_coro_alloc(
|
||||||
|
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
|
||||||
|
// CHECK-SAME: [[INT]] [[SIZE:%[^)]+]]
|
||||||
|
// CHECK-SAME: )
|
||||||
|
// CHECK-SAME: {
|
||||||
|
// CHECK: entry:
|
||||||
|
// CHECK: [[ALLOCATE_FN_PTR:%[^,]+]] = getelementptr inbounds %swift.coro_allocator
|
||||||
|
// CHECK-SAME: ptr [[ALLOCATOR]]
|
||||||
|
// CHECK-SAME: i32 0
|
||||||
|
// CHECK-SAME: i32 1
|
||||||
|
// CHECK: [[ALLOCATE_FN:%[^,]+]] = load ptr, ptr [[ALLOCATE_FN_PTR]]
|
||||||
|
// CHECK: [[ALLOCATION:%[^,]+]] = call swiftcc ptr [[ALLOCATE_FN]]([[INT]] [[SIZE]])
|
||||||
|
// CHECK: ret ptr [[ALLOCATION]]
|
||||||
|
// CHECK: }
|
||||||
|
|
||||||
@frozen
|
@frozen
|
||||||
public struct S {
|
public struct S {
|
||||||
public var o: any AnyObject
|
public var o: any AnyObject
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
// CHECK-SAME: free
|
// CHECK-SAME: free
|
||||||
// CHECK-SAME: }
|
// CHECK-SAME: }
|
||||||
|
|
||||||
// CHECK-LABEL: @__swift_coro_alloc_(
|
// CHECK-LABEL: @_swift_coro_alloc(
|
||||||
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
|
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
|
||||||
// CHECK-SAME: i64 [[SIZE:%[^)]+]]
|
// CHECK-SAME: i64 [[SIZE:%[^)]+]]
|
||||||
// CHECK-SAME: )
|
// CHECK-SAME: )
|
||||||
@@ -36,18 +36,20 @@
|
|||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: [[USE_POPLESS:%[^,]+]] = icmp eq ptr [[ALLOCATOR]], null
|
// CHECK: [[USE_POPLESS:%[^,]+]] = icmp eq ptr [[ALLOCATOR]], null
|
||||||
// CHECK: br i1 [[USE_POPLESS]],
|
// CHECK: br i1 [[USE_POPLESS]],
|
||||||
// CHECK-SAME: label %coro.return.popless
|
// CHECK-SAME: label %popless
|
||||||
// CHECK-SAME: label %coro.return.normal
|
// CHECK-SAME: label %normal
|
||||||
// CHECK: coro.return.popless:
|
// CHECK: popless:
|
||||||
// CHECK: [[STACK_ALLOCATION:%[^,]+]] = alloca i8, i64 [[SIZE]]
|
// CHECK: [[STACK_ALLOCATION:%[^,]+]] = alloca i8, i64 [[SIZE]]
|
||||||
// CHECK: musttail call void @llvm.ret.popless()
|
// CHECK: musttail call void @llvm.ret.popless()
|
||||||
// CHECK: ret ptr [[STACK_ALLOCATION]]
|
// CHECK: ret ptr [[STACK_ALLOCATION]]
|
||||||
// CHECK: coro.return.normal:
|
// CHECK: normal:
|
||||||
// CHECK: [[OTHER_ALLOCATION:%[^,]+]] = call swiftcc ptr @swift_coro_alloc(
|
// CHECK: [[ALLOCATE_FN_PTR:%[^,]+]] = getelementptr inbounds %swift.coro_allocator
|
||||||
// CHECK-SAME: ptr [[ALLOCATOR]]
|
// CHECK-SAME: ptr [[ALLOCATOR]]
|
||||||
// CHECK-SAME: i64 [[SIZE]]
|
// CHECK-SAME: i32 0
|
||||||
// CHECK-SAME: )
|
// CHECK-SAME: i32 1
|
||||||
// CHECK: ret ptr [[OTHER_ALLOCATION]]
|
// CHECK: [[ALLOCATE_FN:%[^,]+]] = load ptr, ptr [[ALLOCATE_FN_PTR]]
|
||||||
|
// CHECK: [[ALLOCATION:%[^,]+]] = call swiftcc ptr [[ALLOCATE_FN]](i64 [[SIZE]])
|
||||||
|
// CHECK: ret ptr [[ALLOCATION]]
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: @__swift_coro_dealloc_(
|
// CHECK-LABEL: @__swift_coro_dealloc_(
|
||||||
|
|||||||
Reference in New Issue
Block a user