Skip to content

Commit d24cc31

Browse files
authored
Merge pull request #85514 from DougGregor/asmname-c-fixes-6.3
[6.3] SIL `asmname`, `@c` serialization, and calling-convention fixes
2 parents 323187a + 661f542 commit d24cc31

File tree

16 files changed

+218
-71
lines changed

16 files changed

+218
-71
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4766,8 +4766,10 @@ void ClangImporter::Implementation::getMangledName(
47664766
auto ctorGlobalDecl =
47674767
clang::GlobalDecl(ctor, clang::CXXCtorType::Ctor_Complete);
47684768
mangler->mangleCXXName(ctorGlobalDecl, os);
4769-
} else {
4769+
} else if (mangler->shouldMangleDeclName(clangDecl)) {
47704770
mangler->mangleName(clangDecl, os);
4771+
} else {
4772+
os << clangDecl->getName();
47714773
}
47724774
}
47734775

lib/LLVMPasses/LLVMARCContract.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,11 @@ void SwiftARCContract::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
403403
llvm::PreservedAnalyses
404404
SwiftARCContractPass::run(llvm::Function &F,
405405
llvm::FunctionAnalysisManager &AM) {
406+
// Don't touch those functions that implement reference counting in the
407+
// runtime.
408+
if (!allowArcOptimizations(F.getName()))
409+
return PreservedAnalyses::all();
410+
406411
bool changed = SwiftARCContractImpl(F).run();
407412
if (!changed)
408413
return PreservedAnalyses::all();

lib/LLVMPasses/LLVMARCOpts.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,12 @@ void SwiftARCOpt::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
10151015

10161016
static bool runSwiftARCOpts(Function &F, SwiftRCIdentity &RC) {
10171017
bool Changed = false;
1018+
1019+
// Don't touch those functions that implement reference counting in the
1020+
// runtime.
1021+
if (!allowArcOptimizations(F.getName()))
1022+
return Changed;
1023+
10181024
ARCEntryPointBuilder B(F);
10191025

10201026
// First thing: canonicalize swift_retain and similar calls so that nothing

lib/LLVMPasses/LLVMARCOpts.h

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,62 @@ enum RT_Kind {
2626
#include "LLVMSwift.def"
2727
};
2828

29+
inline RT_Kind classifyFunctionName(StringRef name) {
30+
return llvm::StringSwitch<RT_Kind>(name)
31+
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
32+
.Case("swift_" #TextualName, RT_ ## Name)
33+
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
34+
.Case("__swift_" #TextualName, RT_ ## Name)
35+
#include "LLVMSwift.def"
36+
37+
// Identify "Client" versions of reference counting entry points.
38+
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
39+
.Case("swift_" #TextualName "Client", RT_ ## Name)
40+
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
41+
.Case("__swift_" #TextualName "Client", RT_ ## Name)
42+
#include "LLVMSwift.def"
43+
44+
// Support non-atomic versions of reference counting entry points.
45+
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
46+
.Case("swift_nonatomic_" #TextualName, RT_ ## Name)
47+
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
48+
.Case("objc_nonatomic_" #TextualName, RT_ ## Name)
49+
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName)
50+
#include "LLVMSwift.def"
51+
52+
.Default(RT_Unknown);
53+
}
54+
55+
/// Whether to allow ARC optimizations for a function with the given name.
56+
inline bool allowArcOptimizations(StringRef name) {
57+
switch (classifyFunctionName(name)) {
58+
case RT_UnknownObjectRetainN:
59+
case RT_BridgeRetainN:
60+
case RT_RetainN:
61+
case RT_UnknownObjectReleaseN:
62+
case RT_BridgeReleaseN:
63+
case RT_ReleaseN:
64+
case RT_UnknownObjectRetain:
65+
case RT_UnknownObjectRelease:
66+
case RT_Retain:
67+
case RT_ObjCRetain:
68+
case RT_ObjCRelease:
69+
case RT_RetainUnowned:
70+
case RT_Release:
71+
case RT_BridgeRetain:
72+
case RT_BridgeRelease:
73+
return false;
74+
75+
case RT_Unknown:
76+
case RT_NoMemoryAccessed:
77+
case RT_CheckUnowned:
78+
case RT_AllocObject:
79+
case RT_FixLifetime:
80+
case RT_EndBorrow:
81+
return true;
82+
}
83+
}
84+
2985
/// Take a look at the specified instruction and classify it into what kind of
3086
/// runtime entrypoint it is, if any.
3187
inline RT_Kind classifyInstruction(const llvm::Instruction &I) {
@@ -57,29 +113,7 @@ inline RT_Kind classifyInstruction(const llvm::Instruction &I) {
57113
if (F == nullptr)
58114
return RT_Unknown;
59115

60-
return llvm::StringSwitch<RT_Kind>(F->getName())
61-
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
62-
.Case("swift_" #TextualName, RT_ ## Name)
63-
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
64-
.Case("__swift_" #TextualName, RT_ ## Name)
65-
#include "LLVMSwift.def"
66-
67-
// Identify "Client" versions of reference counting entry points.
68-
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
69-
.Case("swift_" #TextualName "Client", RT_ ## Name)
70-
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
71-
.Case("__swift_" #TextualName "Client", RT_ ## Name)
72-
#include "LLVMSwift.def"
73-
74-
// Support non-atomic versions of reference counting entry points.
75-
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
76-
.Case("swift_nonatomic_" #TextualName, RT_ ## Name)
77-
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
78-
.Case("objc_nonatomic_" #TextualName, RT_ ## Name)
79-
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName)
80-
#include "LLVMSwift.def"
81-
82-
.Default(RT_Unknown);
116+
return classifyFunctionName(F->getName());
83117
}
84118

85119
} // end namespace swift

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,8 @@ SerializedKind_t SILDeclRef::getSerializedKind() const {
10251025
// @objc thunks for top-level functions are serializable since they're
10261026
// referenced from @convention(c) conversions inside inlinable
10271027
// functions.
1028-
return IsSerialized;
1028+
if (isThunk())
1029+
return IsSerialized;
10291030
}
10301031

10311032
// Declarations imported from Clang modules are serialized if

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4424,12 +4424,29 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
44244424
if (!c.hasDecl())
44254425
return SILFunctionTypeRepresentation::CFunctionPointer;
44264426

4427-
if (auto method =
4428-
dyn_cast_or_null<clang::CXXMethodDecl>(c.getDecl()->getClangDecl()))
4429-
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
4430-
? SILFunctionTypeRepresentation::CFunctionPointer
4431-
: SILFunctionTypeRepresentation::CXXMethod;
4427+
if (auto clangDecl = c.getDecl()->getClangDecl()) {
4428+
if (auto method = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
4429+
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
4430+
? SILFunctionTypeRepresentation::CFunctionPointer
4431+
: SILFunctionTypeRepresentation::CXXMethod;
4432+
}
4433+
4434+
if (auto function = dyn_cast<clang::FunctionDecl>(clangDecl)) {
4435+
if (auto fnType = function->getType()->getAs<clang::FunctionType>()) {
4436+
switch (fnType->getCallConv()) {
4437+
case clang::CC_Swift:
4438+
return SILFunctionTypeRepresentation::Thin;
44324439

4440+
case clang::CC_C:
4441+
return SILFunctionTypeRepresentation::CFunctionPointer;
4442+
4443+
default:
4444+
// Fall back to heuristics below.
4445+
break;
4446+
}
4447+
}
4448+
}
4449+
}
44334450

44344451
// For example, if we have a function in a namespace:
44354452
if (c.getDecl()->isImportAsMember())

0 commit comments

Comments
 (0)