Skip to content

[CoroutineAccessors] Adopt swiftcoro param attr. #79824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,13 @@ void IRGenModule::addSwiftSelfAttributes(llvm::AttributeList &attrs,
attrs = attrs.addParamAttributes(this->getLLVMContext(), argIndex, b);
}

void IRGenModule::addSwiftCoroAttributes(llvm::AttributeList &attrs,
unsigned argIndex) {
llvm::AttrBuilder b(getLLVMContext());
b.addAttribute(llvm::Attribute::SwiftCoro);
attrs = attrs.addParamAttributes(this->getLLVMContext(), argIndex, b);
}

void IRGenModule::addSwiftErrorAttributes(llvm::AttributeList &attrs,
unsigned argIndex) {
llvm::AttrBuilder b(getLLVMContext());
Expand Down Expand Up @@ -892,6 +899,7 @@ void SignatureExpansion::expandCoroutineContinuationParameters() {
if (FnType->isCalleeAllocatedCoroutine()) {
// Whether this is an unwind resumption.
ParamIRTypes.push_back(IGM.CoroAllocatorPtrTy);
IGM.addSwiftCoroAttributes(Attrs, ParamIRTypes.size() - 1);
} else {
// Whether this is an unwind resumption.
ParamIRTypes.push_back(IGM.Int1Ty);
Expand Down Expand Up @@ -923,6 +931,7 @@ void SignatureExpansion::addCoroutineContextParameter() {

void SignatureExpansion::addCoroutineAllocatorParameter() {
ParamIRTypes.push_back(IGM.CoroAllocatorPtrTy);
IGM.addSwiftCoroAttributes(Attrs, ParamIRTypes.size() - 1);
}

NativeConventionSchema::NativeConventionSchema(IRGenModule &IGM,
Expand Down Expand Up @@ -5170,7 +5179,11 @@ static llvm::Constant *getCoroAllocFn(IRGenModule &IGM) {
/*setIsNoInline=*/true,
/*forPrologue=*/false,
/*isPerformanceConstraint=*/false,
/*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC);
/*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC,
/*transformAttributes=*/
[&IGM](llvm::AttributeList &attrs) {
IGM.addSwiftCoroAttributes(attrs, 0);
});
}

static llvm::Constant *getCoroDeallocFn(IRGenModule &IGM) {
Expand Down Expand Up @@ -5244,7 +5257,11 @@ static llvm::Constant *getCoroDeallocFn(IRGenModule &IGM) {
/*setIsNoInline=*/true,
/*forPrologue=*/false,
/*isPerformanceConstraint=*/false,
/*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC);
/*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC,
/*transformAttributes=*/
[&IGM](llvm::AttributeList &attrs) {
IGM.addSwiftCoroAttributes(attrs, 0);
});
}

void irgen::emitYieldOnce2CoroutineEntry(IRGenFunction &IGF,
Expand Down
21 changes: 15 additions & 6 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6283,10 +6283,11 @@ IRGenModule::getAddrOfContinuationPrototype(CanSILFunctionType fnType) {
}

/// Should we be defining the given helper function?
static llvm::Function *
shouldDefineHelper(IRGenModule &IGM, llvm::Constant *fn, bool setIsNoInline,
IRLinkage *linkage,
std::optional<llvm::CallingConv::ID> specialCallingConv) {
static llvm::Function *shouldDefineHelper(
IRGenModule &IGM, llvm::Constant *fn, bool setIsNoInline,
IRLinkage *linkage, std::optional<llvm::CallingConv::ID> specialCallingConv,
std::optional<llvm::function_ref<void(llvm::AttributeList &)>>
transformAttrs) {
auto *def = dyn_cast<llvm::Function>(fn);
if (!def) return nullptr;
if (!def->empty()) return nullptr;
Expand All @@ -6301,6 +6302,12 @@ shouldDefineHelper(IRGenModule &IGM, llvm::Constant *fn, bool setIsNoInline,
def->setCallingConv(specialCallingConv.value_or(IGM.DefaultCC));
if (setIsNoInline)
def->addFnAttr(llvm::Attribute::NoInline);

if (transformAttrs) {
auto attrs = def->getAttributes();
(*transformAttrs)(attrs);
def->setAttributes(attrs);
}
return def;
}

Expand All @@ -6317,7 +6324,9 @@ llvm::Constant *IRGenModule::getOrCreateHelperFunction(
llvm::function_ref<void(IRGenFunction &IGF)> generate, bool setIsNoInline,
bool forPrologue, bool isPerformanceConstraint,
IRLinkage *optionalLinkageOverride,
std::optional<llvm::CallingConv::ID> specialCallingConv) {
std::optional<llvm::CallingConv::ID> specialCallingConv,
std::optional<llvm::function_ref<void(llvm::AttributeList &)>>
transformAttrs) {
llvm::FunctionType *fnTy =
llvm::FunctionType::get(resultTy, paramTys, false);

Expand All @@ -6327,7 +6336,7 @@ llvm::Constant *IRGenModule::getOrCreateHelperFunction(

if (llvm::Function *def =
shouldDefineHelper(*this, fn, setIsNoInline, optionalLinkageOverride,
specialCallingConv)) {
specialCallingConv, transformAttrs)) {
IRGenFunction IGF(*this, def, isPerformanceConstraint);
if (DebugInfo && !forPrologue)
DebugInfo->emitArtificialFunction(IGF, def);
Expand Down
6 changes: 5 additions & 1 deletion lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,9 @@ class IRGenModule {
bool setIsNoInline = false, bool forPrologue = false,
bool isPerformanceConstraint = false,
IRLinkage *optionalLinkage = nullptr,
std::optional<llvm::CallingConv::ID> specialCallingConv = std::nullopt);
std::optional<llvm::CallingConv::ID> specialCallingConv = std::nullopt,
std::optional<llvm::function_ref<void(llvm::AttributeList &)>>
transformAttrs = std::nullopt);

llvm::Constant *getOrCreateRetainFunction(const TypeInfo &objectTI, SILType t,
llvm::Type *llvmType, Atomicity atomicity);
Expand Down Expand Up @@ -1947,6 +1949,8 @@ private: \
/// Add the swiftself attribute.
void addSwiftSelfAttributes(llvm::AttributeList &attrs, unsigned argIndex);

void addSwiftCoroAttributes(llvm::AttributeList &attrs, unsigned argIndex);

void addSwiftAsyncContextAttributes(llvm::AttributeList &attrs,
unsigned argIndex);

Expand Down
80 changes: 77 additions & 3 deletions test/IRGen/coroutine_accessors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@

// REQUIRES: swift_feature_CoroutineAccessors

// CHECK-LABEL: %T19coroutine_accessors1SV = type <{ %AnyObject, %TSi }>

// CHECK-LABEL: @"$s19coroutine_accessors1SV3irmSivyTwc" = {{.*}}global %swift.coro_func_pointer
// : sub (
// CHECK-SAME: $s19coroutine_accessors1SV3irmSivy
// : $s19coroutine_accessors1SV3irmSivyTwc
// : )
// CHECK-SAME: i32 0
// CHECK-SAME: }>
// CHECK-LABEL: @"$s19coroutine_accessors1SV3irmSivxTwc" = {{.*}}global{{.*}} %swift.coro_func_pointer <{
// : sub (
// CHECK-SAME: $s19coroutine_accessors1SV3irmSivx
Expand All @@ -25,7 +34,7 @@
// CHECK-SAME: }

// CHECK-LABEL: @_swift_coro_alloc(
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: [[INT]] [[SIZE:%[^)]+]]
// CHECK-SAME: )
// CHECK-SAME: {
Expand All @@ -40,7 +49,7 @@
// CHECK: }

// CHECK-LABEL: @_swift_coro_dealloc(
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: ptr [[ADDRESS:%[^)]+]]
// CHECK-SAME: )
// CHECK-SAME: {
Expand Down Expand Up @@ -73,16 +82,81 @@ public var o: any AnyObject
public var _i: Int = 0

public var irm: Int {
// CHECK-LABEL: declare{{.*}} swiftcc void @"$s19coroutine_accessors1SVSiIetMIlYl_TC"(ptr noalias, ptr swiftcoro)

// CHECK-LABEL: define{{.*}} { ptr, {{i64|i32}} } @"$s19coroutine_accessors1SV3irmSivy"(
// CHECK-SAME: ptr noalias [[FRAME:%[^,]+]],
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^,]+]],
// CHECK-SAME: ptr [[S_FIELD_O:%[^,]+]],
// CHECK-SAME: [[INT]] [[S_FIELD__I:%[^)]+]]
// CHECK-SAME: )
// CHECK-SAME: {
// CHECK: [[ID:%[^,]+]] = call token @llvm.coro.id.retcon.once.dynamic(
// CHECK-SAME: i32 -1,
// CHECK-SAME: i32 16,
// CHECK-SAME: ptr @"$s19coroutine_accessors1SV3irmSivyTwc",
// CHECK-SAME: ptr [[ALLOCATOR]],
// CHECK-SAME: ptr [[FRAME]],
// CHECK-SAME: ptr @"$s19coroutine_accessors1SVSiIetMIgYy_TC",
// CHECK-SAME: ptr @_swift_coro_alloc,
// CHECK-SAME: ptr @_swift_coro_dealloc
// CHECK-SAME: )
// CHECK: [[HANDLE:%[^,]+]] = call ptr @llvm.coro.begin(
// CHECK-SAME: token [[ID]],
// CHECK-SAME: ptr null
// CHECK-SAME: )
// CHECK: call ptr (...) @llvm.coro.suspend.retcon.p0([[INT]] [[S_FIELD__I]])
// CHECK: br i1 false, label %[[UNWIND:[^,]+]], label %[[NORMAL:[^,]+]]
// CHECK: [[NORMAL]]:
// CHECK: br label %coro.end
// CHECK: [[UNWIND]]:
// CHECK: br label %coro.end
// CHECK: coro.end:
// CHECK: call i1 @llvm.coro.end(
// CHECK-SAME: ptr [[HANDLE]],
// CHECK-SAME: i1 false,
// CHECK-SAME: token none
// CHECK-SAME: )
// CHECK: unreachable
// CHECK: }
read {
yield _i
}
// CHECK-LABEL: define{{.*}} { ptr, ptr } @"$s19coroutine_accessors1SV3irmSivx"(
// CHECK-SAME: ptr noalias [[FRAME:%[^,]+]],
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^,]+]],
// CHECK-SAME: ptr nocapture swiftself dereferenceable({{8|16}}) [[SELF:%[^)]+]]
// CHECK-SAME: )
// CHECK-SAME: {
// CHECK: [[ID:%[^,]+]] = call token @llvm.coro.id.retcon.once.dynamic(
// CHECK-SAME: i32 -1,
// CHECK-SAME: i32 16,
// CHECK-SAME: ptr @"$s19coroutine_accessors1SV3irmSivxTwc",
// CHECK-SAME: ptr [[ALLOCATOR]],
// CHECK-SAME: ptr [[FRAME]],
// CHECK-SAME: ptr @"$s19coroutine_accessors1SVSiIetMIlYl_TC",
// CHECK-SAME: ptr @_swift_coro_alloc,
// CHECK-SAME: ptr @_swift_coro_dealloc
// CHECK-SAME: )
// CHECK: [[HANDLE:%[^,]+]] = call ptr @llvm.coro.begin(
// CHECK-SAME: token [[ID]],
// CHECK-SAME: ptr null
// CHECK-SAME: )
// CHECK: [[S_FIELD__I:%[^,]+]] = getelementptr inbounds %T19coroutine_accessors1SV,
// CHECK-SAME: ptr [[SELF]],
// CHECK-SAME: i32 0,
// CHECK-SAME: i32 1
// CHECK: call ptr (...) @llvm.coro.suspend.retcon.p0(
// CHECK-SAME: ptr [[S_FIELD__I]]
// CHECK-SAME: )
// CHECK: br i1 false, label %[[UNWIND:[^,]+]], label %[[NORMAL:[^,]+]]
// CHECK: [[NORMAL]]:
// CHECK: br label %coro.end
// CHECK: [[UNWIND]]:
// CHECK: br label %coro.end
// CHECK: coro.end:
// CHECK: [[REGISTER_8:%[^,]+]] = call i1 @llvm.coro.end(ptr [[HANDLE]], i1 false, token none)
// CHECK: unreachable
// CHECK: }
modify {
yield &_i
Expand Down Expand Up @@ -217,7 +291,7 @@ public var force_yield_once_2_convention : () {
}
// CHECK-LABEL: define{{.*}} { ptr, ptr } @increment_irm_yield_once_2(
// ptr noalias %0
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^,]+]]
// ptr nocapture swiftself dereferenceable(16) %2
// CHECK-SAME: )
// CHECK-SAME: {
Expand Down
13 changes: 10 additions & 3 deletions test/IRGen/coroutine_accessors_popless.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
// REQUIRES: CPU=arm64 || CPU=arm64e || CPU=x86_64
// REQUIRES: swift_feature_CoroutineAccessors

// CHECK-LABEL: @"$s27coroutine_accessors_popless1iSivyTwc" = {{.*}}global{{.*}} %swift.coro_func_pointer <{
// : sub (
// CHECK-SAME: $s27coroutine_accessors_popless1iSivy
// : $s27coroutine_accessors_popless1iSivyTwc
// : ),
// CHECK-SAME: i32 0
// CHECK-SAME: }>
// CHECK-LABEL: @"$s27coroutine_accessors_popless1iSivxTwc" = {{.*}}global{{.*}} %swift.coro_func_pointer <{
// : sub (
// CHECK-SAME: $s27coroutine_accessors_popless1iSivx
Expand All @@ -29,7 +36,7 @@
// CHECK-SAME: }

// CHECK-LABEL: @_swift_coro_alloc(
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: i64 [[SIZE:%[^)]+]]
// CHECK-SAME: )
// CHECK-SAME: {
Expand All @@ -53,7 +60,7 @@
// CHECK: }

// CHECK-LABEL: @_swift_coro_dealloc(
// CHECK-SAME: ptr [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^,]+]]
// CHECK-SAME: ptr [[ADDRESS:%[^)]+]]
// CHECK-SAME: )
// CHECK-SAME: {
Expand Down Expand Up @@ -231,7 +238,7 @@ public var force_yield_once_2_convention : () {
}
// CHECK-LABEL: define{{.*}} { ptr, ptr } @increment_i_yield_once_2(
// ptr noalias %0
// CHECK-SAME: ptr [[ALLOCATOR:%[^)]+]]
// CHECK-SAME: ptr swiftcoro [[ALLOCATOR:%[^)]+]]
// CHECK-SAME: )
// CHECK-SAME: {
// : [[SIZE_32:%[^,]+]] = load i32
Expand Down