Skip to content

Commit 6f0f9db

Browse files
committed
[SILOpt] Don't apply @_specialize attribute to ObjC methods
rdar://164200332 The specialization should only apply to the Swift version of the method, which gets called by the ObjC version anyway, so the specialization is still in effect.
1 parent a4ae171 commit 6f0f9db

File tree

3 files changed

+82
-39
lines changed

3 files changed

+82
-39
lines changed

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -66,46 +66,50 @@ void SILFunctionBuilder::addFunctionAttributes(
6666
M.getOptions().EnableGlobalAssemblyVision)
6767
F->addSemanticsAttr(semantics::FORCE_EMIT_OPT_REMARK_PREFIX);
6868

69-
// Propagate @_specialize.
70-
for (auto *A : Attrs.getAttributes<AbstractSpecializeAttr>()) {
71-
auto *SA = cast<AbstractSpecializeAttr>(A);
72-
auto kind =
73-
SA->getSpecializationKind() == SpecializeAttr::SpecializationKind::Full
74-
? SILSpecializeAttr::SpecializationKind::Full
75-
: SILSpecializeAttr::SpecializationKind::Partial;
76-
assert(!constant.isNull());
77-
SILFunction *targetFunction = nullptr;
78-
auto *attributedFuncDecl = constant.getAbstractFunctionDecl();
79-
auto *targetFunctionDecl = SA->getTargetFunctionDecl(attributedFuncDecl);
80-
// Filter out _spi.
81-
auto spiGroups = SA->getSPIGroups();
82-
bool hasSPI = !spiGroups.empty();
83-
if (hasSPI) {
84-
if (attributedFuncDecl->getModuleContext() != M.getSwiftModule() &&
85-
!M.getSwiftModule()->isImportedAsSPI(SA, attributedFuncDecl)) {
86-
continue;
69+
if (F->getRepresentation() != SILFunctionTypeRepresentation::ObjCMethod) {
70+
// Propagate @_specialize.
71+
for (auto *A : Attrs.getAttributes<AbstractSpecializeAttr>()) {
72+
auto *SA = cast<AbstractSpecializeAttr>(A);
73+
auto kind = SA->getSpecializationKind() ==
74+
SpecializeAttr::SpecializationKind::Full
75+
? SILSpecializeAttr::SpecializationKind::Full
76+
: SILSpecializeAttr::SpecializationKind::Partial;
77+
assert(!constant.isNull());
78+
SILFunction *targetFunction = nullptr;
79+
auto *attributedFuncDecl = constant.getAbstractFunctionDecl();
80+
auto *targetFunctionDecl = SA->getTargetFunctionDecl(attributedFuncDecl);
81+
// Filter out _spi.
82+
auto spiGroups = SA->getSPIGroups();
83+
bool hasSPI = !spiGroups.empty();
84+
if (hasSPI) {
85+
if (attributedFuncDecl->getModuleContext() != M.getSwiftModule() &&
86+
!M.getSwiftModule()->isImportedAsSPI(SA, attributedFuncDecl)) {
87+
continue;
88+
}
89+
}
90+
assert(spiGroups.size() <= 1 &&
91+
"SIL does not support multiple SPI groups");
92+
Identifier spiGroupIdent;
93+
if (hasSPI) {
94+
spiGroupIdent = spiGroups[0];
95+
}
96+
auto availability = AvailabilityInference::annotatedAvailableRangeForAttr(
97+
attributedFuncDecl, SA, M.getSwiftModule()->getASTContext());
98+
auto specializedSignature =
99+
SA->getSpecializedSignature(attributedFuncDecl);
100+
if (targetFunctionDecl) {
101+
SILDeclRef declRef(targetFunctionDecl, constant.kind, false);
102+
targetFunction = getOrCreateDeclaration(targetFunctionDecl, declRef);
103+
F->addSpecializeAttr(SILSpecializeAttr::create(
104+
M, specializedSignature, SA->getTypeErasedParams(),
105+
SA->isExported(), kind, targetFunction, spiGroupIdent,
106+
attributedFuncDecl->getModuleContext(), availability));
107+
} else {
108+
F->addSpecializeAttr(SILSpecializeAttr::create(
109+
M, specializedSignature, SA->getTypeErasedParams(),
110+
SA->isExported(), kind, nullptr, spiGroupIdent,
111+
attributedFuncDecl->getModuleContext(), availability));
87112
}
88-
}
89-
assert(spiGroups.size() <= 1 && "SIL does not support multiple SPI groups");
90-
Identifier spiGroupIdent;
91-
if (hasSPI) {
92-
spiGroupIdent = spiGroups[0];
93-
}
94-
auto availability = AvailabilityInference::annotatedAvailableRangeForAttr(
95-
attributedFuncDecl, SA, M.getSwiftModule()->getASTContext());
96-
auto specializedSignature = SA->getSpecializedSignature(attributedFuncDecl);
97-
if (targetFunctionDecl) {
98-
SILDeclRef declRef(targetFunctionDecl, constant.kind, false);
99-
targetFunction = getOrCreateDeclaration(targetFunctionDecl, declRef);
100-
F->addSpecializeAttr(SILSpecializeAttr::create(
101-
M, specializedSignature, SA->getTypeErasedParams(),
102-
SA->isExported(), kind, targetFunction, spiGroupIdent,
103-
attributedFuncDecl->getModuleContext(), availability));
104-
} else {
105-
F->addSpecializeAttr(SILSpecializeAttr::create(
106-
M, specializedSignature, SA->getTypeErasedParams(),
107-
SA->isExported(), kind, nullptr, spiGroupIdent,
108-
attributedFuncDecl->getModuleContext(), availability));
109113
}
110114
}
111115

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#import <Foundation/Foundation.h>
2+
3+
NS_ASSUME_NONNULL_BEGIN
4+
5+
extern __attribute__((visibility("default")))
6+
@protocol NoObjCSpecialization<NSObject>
7+
8+
- (BOOL)fooWithValue:(id)value
9+
andBool:(BOOL)boolValue
10+
error:(NSError *_Nullable *)error;
11+
12+
@end
13+
14+
NS_ASSUME_NONNULL_END
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-frontend -import-objc-header %S/Inputs/NoObjCSpecialization.h -O -emit-sil %s | %FileCheck %s
2+
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
7+
final class NoObjCSpecializationImpl<Value>: NSObject, NoObjCSpecialization {
8+
9+
// CHECK-NOT: @$s22no_objc_specialization24NoObjCSpecializationImplC3foo9withValue7andBoolyyp_SbtKFToyt_Tg5 : $@convention(objc_method)
10+
// CHECK-LABEL: sil private [thunk] @$s22no_objc_specialization24NoObjCSpecializationImplC3foo9withValue7andBoolyyp_SbtKFTo : $@convention(objc_method)
11+
// CHECK: [[FUNC:%.*]] = function_ref @$s22no_objc_specialization24NoObjCSpecializationImplC3foo9withValue7andBoolyyp_SbtKFTf4nnd_n : $@convention(thin) <τ_0_0> (@in_guaranteed Any, Bool) -> @error any Error
12+
// CHECK: try_apply [[FUNC]]<Value>({{%.*}}, {{%.*}}) : $@convention(thin) <τ_0_0> (@in_guaranteed Any, Bool) -> @error any Error
13+
// CHECK-LABEL: sil shared @$s22no_objc_specialization24NoObjCSpecializationImplC3foo9withValue7andBoolyyp_SbtKFyt_Tg5Tf4nnd_n : $@convention(thin) (@in_guaranteed Any, Bool) -> @error any Error {
14+
// CHECK-LABEL: sil shared @$s22no_objc_specialization24NoObjCSpecializationImplC3foo9withValue7andBoolyyp_SbtKFTf4nnd_n : $@convention(thin) <Value> (@in_guaranteed Any, Bool) -> @error any Error {
15+
// CHECK: [[FUNC:%.*]] = function_ref @$s22no_objc_specialization24NoObjCSpecializationImplC3foo9withValue7andBoolyyp_SbtKFyt_Tg5Tf4nnd_n : $@convention(thin) (@in_guaranteed Any, Bool) -> @error any Error
16+
// CHECK: apply [nothrow] [[FUNC]]({{%.*}}, {{%.*}}) : $@convention(thin) (@in_guaranteed Any, Bool) -> @error any Error
17+
@_specialize(where Value == Void)
18+
func foo(withValue value: Any, andBool bool: Bool) throws {
19+
if Value.self == Void.self {
20+
print("Is Void with \(bool)")
21+
} else {
22+
print("Is \(value) with \(bool)")
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)