Skip to content
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
4 changes: 3 additions & 1 deletion lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4766,8 +4766,10 @@ void ClangImporter::Implementation::getMangledName(
auto ctorGlobalDecl =
clang::GlobalDecl(ctor, clang::CXXCtorType::Ctor_Complete);
mangler->mangleCXXName(ctorGlobalDecl, os);
} else {
} else if (mangler->shouldMangleDeclName(clangDecl)) {
mangler->mangleName(clangDecl, os);
} else {
os << clangDecl->getName();
}
}

Expand Down
5 changes: 5 additions & 0 deletions lib/LLVMPasses/LLVMARCContract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ void SwiftARCContract::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
llvm::PreservedAnalyses
SwiftARCContractPass::run(llvm::Function &F,
llvm::FunctionAnalysisManager &AM) {
// Don't touch those functions that implement reference counting in the
// runtime.
if (!allowArcOptimizations(F.getName()))
return PreservedAnalyses::all();

bool changed = SwiftARCContractImpl(F).run();
if (!changed)
return PreservedAnalyses::all();
Expand Down
6 changes: 6 additions & 0 deletions lib/LLVMPasses/LLVMARCOpts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,12 @@ void SwiftARCOpt::getAnalysisUsage(llvm::AnalysisUsage &AU) const {

static bool runSwiftARCOpts(Function &F, SwiftRCIdentity &RC) {
bool Changed = false;

// Don't touch those functions that implement reference counting in the
// runtime.
if (!allowArcOptimizations(F.getName()))
return Changed;

ARCEntryPointBuilder B(F);

// First thing: canonicalize swift_retain and similar calls so that nothing
Expand Down
80 changes: 57 additions & 23 deletions lib/LLVMPasses/LLVMARCOpts.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,62 @@ enum RT_Kind {
#include "LLVMSwift.def"
};

inline RT_Kind classifyFunctionName(StringRef name) {
return llvm::StringSwitch<RT_Kind>(name)
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
.Case("swift_" #TextualName, RT_ ## Name)
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
.Case("__swift_" #TextualName, RT_ ## Name)
#include "LLVMSwift.def"

// Identify "Client" versions of reference counting entry points.
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
.Case("swift_" #TextualName "Client", RT_ ## Name)
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
.Case("__swift_" #TextualName "Client", RT_ ## Name)
#include "LLVMSwift.def"

// Support non-atomic versions of reference counting entry points.
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
.Case("swift_nonatomic_" #TextualName, RT_ ## Name)
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
.Case("objc_nonatomic_" #TextualName, RT_ ## Name)
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName)
#include "LLVMSwift.def"

.Default(RT_Unknown);
}

/// Whether to allow ARC optimizations for a function with the given name.
inline bool allowArcOptimizations(StringRef name) {
switch (classifyFunctionName(name)) {
case RT_UnknownObjectRetainN:
case RT_BridgeRetainN:
case RT_RetainN:
case RT_UnknownObjectReleaseN:
case RT_BridgeReleaseN:
case RT_ReleaseN:
case RT_UnknownObjectRetain:
case RT_UnknownObjectRelease:
case RT_Retain:
case RT_ObjCRetain:
case RT_ObjCRelease:
case RT_RetainUnowned:
case RT_Release:
case RT_BridgeRetain:
case RT_BridgeRelease:
return false;

case RT_Unknown:
case RT_NoMemoryAccessed:
case RT_CheckUnowned:
case RT_AllocObject:
case RT_FixLifetime:
case RT_EndBorrow:
return true;
}
}

/// Take a look at the specified instruction and classify it into what kind of
/// runtime entrypoint it is, if any.
inline RT_Kind classifyInstruction(const llvm::Instruction &I) {
Expand Down Expand Up @@ -57,29 +113,7 @@ inline RT_Kind classifyInstruction(const llvm::Instruction &I) {
if (F == nullptr)
return RT_Unknown;

return llvm::StringSwitch<RT_Kind>(F->getName())
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
.Case("swift_" #TextualName, RT_ ## Name)
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
.Case("__swift_" #TextualName, RT_ ## Name)
#include "LLVMSwift.def"

// Identify "Client" versions of reference counting entry points.
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
.Case("swift_" #TextualName "Client", RT_ ## Name)
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
.Case("__swift_" #TextualName "Client", RT_ ## Name)
#include "LLVMSwift.def"

// Support non-atomic versions of reference counting entry points.
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
.Case("swift_nonatomic_" #TextualName, RT_ ## Name)
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
.Case("objc_nonatomic_" #TextualName, RT_ ## Name)
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName)
#include "LLVMSwift.def"

.Default(RT_Unknown);
return classifyFunctionName(F->getName());
}

} // end namespace swift
Expand Down
3 changes: 2 additions & 1 deletion lib/SIL/IR/SILDeclRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,8 @@ SerializedKind_t SILDeclRef::getSerializedKind() const {
// @objc thunks for top-level functions are serializable since they're
// referenced from @convention(c) conversions inside inlinable
// functions.
return IsSerialized;
if (isThunk())
return IsSerialized;
}

// Declarations imported from Clang modules are serialized if
Expand Down
27 changes: 22 additions & 5 deletions lib/SIL/IR/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4424,12 +4424,29 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
if (!c.hasDecl())
return SILFunctionTypeRepresentation::CFunctionPointer;

if (auto method =
dyn_cast_or_null<clang::CXXMethodDecl>(c.getDecl()->getClangDecl()))
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
? SILFunctionTypeRepresentation::CFunctionPointer
: SILFunctionTypeRepresentation::CXXMethod;
if (auto clangDecl = c.getDecl()->getClangDecl()) {
if (auto method = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
return isa<clang::CXXConstructorDecl>(method) || method->isStatic()
? SILFunctionTypeRepresentation::CFunctionPointer
: SILFunctionTypeRepresentation::CXXMethod;
}

if (auto function = dyn_cast<clang::FunctionDecl>(clangDecl)) {
if (auto fnType = function->getType()->getAs<clang::FunctionType>()) {
switch (fnType->getCallConv()) {
case clang::CC_Swift:
return SILFunctionTypeRepresentation::Thin;

case clang::CC_C:
return SILFunctionTypeRepresentation::CFunctionPointer;

default:
// Fall back to heuristics below.
break;
}
}
}
}

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