Skip to content

Commit 541c5d3

Browse files
authored
Merge pull request #65884 from slavapestov/parameter-packs-backward-deployment
Backward deployment shim for swift_allocate{Metadata,WitnessTable}Pack()
2 parents cae6746 + c2338aa commit 541c5d3

File tree

10 files changed

+257
-29
lines changed

10 files changed

+257
-29
lines changed

include/swift/Frontend/BackDeploymentLibs.def

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121
//===----------------------------------------------------------------------===//
2222

2323
#ifndef BACK_DEPLOYMENT_LIB
24-
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library)"
24+
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library, ForceLoad)"
2525
#endif
2626

27-
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50")
28-
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51")
29-
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements")
30-
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency")
31-
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56")
27+
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50", true)
28+
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51", true)
29+
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements", true)
30+
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency", true)
31+
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56", true)
32+
BACK_DEPLOYMENT_LIB((5, 8), all, "swiftCompatibilityPacks", false)
3233

3334
#undef BACK_DEPLOYMENT_LIB

lib/Basic/TargetInfo.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ using namespace swift;
2323
/// Print information about a
2424
static void printCompatibilityLibrary(
2525
llvm::VersionTuple runtimeVersion, llvm::VersionTuple maxVersion,
26-
StringRef filter, StringRef libraryName, bool &printedAny,
27-
llvm::raw_ostream &out) {
26+
StringRef filter, StringRef libraryName, bool forceLoad,
27+
bool &printedAny, llvm::raw_ostream &out) {
2828
if (runtimeVersion > maxVersion)
2929
return;
3030

@@ -33,16 +33,21 @@ static void printCompatibilityLibrary(
3333
}
3434

3535
out << "\n";
36-
out << " {\n";
36+
out << " {";
3737

38-
out << " \"libraryName\": \"";
38+
out << "\n \"libraryName\": \"";
3939
swift::writeEscaped(libraryName, out);
40-
out << "\",\n";
40+
out << "\",";
4141

42-
out << " \"filter\": \"";
42+
out << "\n \"filter\": \"";
4343
swift::writeEscaped(filter, out);
44-
out << "\"\n";
45-
out << " }";
44+
out << "\"";
45+
46+
if (!forceLoad) {
47+
out << ",\n \"forceLoad\": false";
48+
}
49+
50+
out << "\n }";
4651

4752
printedAny = true;
4853
}
@@ -132,10 +137,10 @@ void targetinfo::printTripleInfo(const llvm::Triple &triple,
132137
// Compatibility libraries that need to be linked.
133138
out << " \"compatibilityLibraries\": [";
134139
bool printedAnyCompatibilityLibrary = false;
135-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
136-
printCompatibilityLibrary( \
140+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
141+
printCompatibilityLibrary( \
137142
*runtimeVersion, llvm::VersionTuple Version, #Filter, LibraryName, \
138-
printedAnyCompatibilityLibrary, out);
143+
ForceLoad, printedAnyCompatibilityLibrary, out);
139144
#include "swift/Frontend/BackDeploymentLibs.def"
140145

141146
if (printedAnyCompatibilityLibrary) {

lib/Driver/DarwinToolChains.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
406406
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
407407
} else if (value.equals("5.6")) {
408408
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
409+
} else if (value.equals("5.8")) {
410+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
409411
} else if (value.equals("none")) {
410412
runtimeCompatibilityVersion = None;
411413
} else {
@@ -419,7 +421,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
419421
if (runtimeCompatibilityVersion) {
420422
auto addBackDeployLib = [&](llvm::VersionTuple version,
421423
BackDeployLibFilter filter,
422-
StringRef libraryName) {
424+
StringRef libraryName,
425+
bool forceLoad) {
423426
if (*runtimeCompatibilityVersion > version)
424427
return;
425428

@@ -431,14 +434,16 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
431434
llvm::sys::path::append(BackDeployLib, "lib" + libraryName + ".a");
432435

433436
if (llvm::sys::fs::exists(BackDeployLib)) {
434-
Arguments.push_back("-force_load");
437+
if (forceLoad)
438+
Arguments.push_back("-force_load");
435439
Arguments.push_back(context.Args.MakeArgString(BackDeployLib));
436440
}
437441
};
438442

439-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
440-
addBackDeployLib( \
441-
llvm::VersionTuple Version, BackDeployLibFilter::Filter, LibraryName);
443+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
444+
addBackDeployLib( \
445+
llvm::VersionTuple Version, BackDeployLibFilter::Filter, \
446+
LibraryName, ForceLoad);
442447
#include "swift/Frontend/BackDeploymentLibs.def"
443448
}
444449

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
26072607
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
26082608
} else if (version.equals("5.6")) {
26092609
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
2610+
} else if (version.equals("5.8")) {
2611+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
26102612
} else {
26112613
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
26122614
versionArg->getAsString(Args), version);

lib/IRGen/GenDecl.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
511511
// harmless aside from code size.
512512
if (!IRGen.Opts.UseJIT) {
513513
auto addBackDeployLib = [&](llvm::VersionTuple version,
514-
StringRef libraryName) {
514+
StringRef libraryName,
515+
bool forceLoad) {
515516
Optional<llvm::VersionTuple> compatibilityVersion;
516517
if (libraryName == "swiftCompatibilityDynamicReplacements") {
517518
compatibilityVersion = IRGen.Opts.
@@ -532,11 +533,11 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
532533

533534
this->addLinkLibrary(LinkLibrary(libraryName,
534535
LibraryKind::Library,
535-
/*forceLoad*/ true));
536+
forceLoad));
536537
};
537538

538-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
539-
addBackDeployLib(llvm::VersionTuple Version, LibraryName);
539+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
540+
addBackDeployLib(llvm::VersionTuple Version, LibraryName, ForceLoad);
540541
#include "swift/Frontend/BackDeploymentLibs.def"
541542
}
542543
}

stdlib/toolchain/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ if(SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT)
5454
add_subdirectory(CompatibilityDynamicReplacements)
5555
add_subdirectory(CompatibilityConcurrency)
5656
add_subdirectory(CompatibilityThreading)
57+
add_subdirectory(CompatibilityPacks)
5758

5859
# This is a convenience target to have the list
5960
# of all the compatibility libraries needed to build
@@ -63,6 +64,7 @@ if(SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT)
6364
target_link_libraries(HostCompatibilityLibs INTERFACE
6465
swiftCompatibilityConcurrency${vsuffix}
6566
swiftCompatibilityDynamicReplacements${vsuffix}
67+
swiftCompatibilityPacks${vsuffix}
6668
swiftCompatibility50${vsuffix}
6769
swiftCompatibility51${vsuffix}
6870
swiftCompatibility56${vsuffix})
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
set(library_name "swiftCompatibilityPacks")
2+
3+
include_directories("include/" "${SWIFT_STDLIB_SOURCE_DIR}")
4+
5+
set(CMAKE_C_VISIBILITY_PRESET hidden)
6+
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
7+
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
8+
9+
add_compile_definitions(SWIFT_COMPATIBILITY_PACKS)
10+
add_swift_target_library("${library_name}" STATIC
11+
Metadata.cpp
12+
13+
TARGET_SDKS ${SWIFT_DARWIN_PLATFORMS}
14+
15+
C_COMPILE_FLAGS
16+
${CXX_COMPILE_FLAGS}
17+
"-D__STDC_WANT_LIB_EXT1__=1"
18+
LINK_FLAGS ${CXX_LINK_FLAGS}
19+
INCORPORATE_OBJECT_LIBRARIES swiftCompatibilityThreading
20+
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
21+
DEPLOYMENT_VERSION_OSX ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_OSX}
22+
DEPLOYMENT_VERSION_IOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_IOS}
23+
DEPLOYMENT_VERSION_TVOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_TVOS}
24+
DEPLOYMENT_VERSION_WATCHOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_WATCHOS}
25+
26+
MACCATALYST_BUILD_FLAVOR "zippered"
27+
28+
INSTALL_IN_COMPONENT compiler
29+
INSTALL_WITH_SHARED)
30+
31+
32+
# FIXME: We need a more flexible mechanism to add lipo targets generated by
33+
# add_swift_target_library to the ALL target. Until then this hack is necessary
34+
# to ensure these libraries build.
35+
foreach(sdk ${SWIFT_SDKS})
36+
set(target_name "${library_name}-${SWIFT_SDK_${sdk}_LIB_SUBDIR}")
37+
if(NOT TARGET "${target_name}")
38+
continue()
39+
endif()
40+
41+
set_target_properties("${target_name}"
42+
PROPERTIES
43+
EXCLUDE_FROM_ALL FALSE)
44+
endforeach()
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
//===--- Metadata.cpp -----------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Backward deployment of swift_allocateMetadataPack() and
14+
// swift_allocateWitnessTablePack() runtime entry points.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#include "../../public/runtime/MetadataCache.h"
19+
20+
using namespace swift;
21+
22+
/// Copy and paste a symbol that needs to exist.
23+
void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
24+
return malloc(size);
25+
}
26+
27+
/// Avoid depending on non-inline parts of llvm::hashing.
28+
inline llvm::hash_code our_hash_integer_value(uint64_t value) {
29+
const char *s = reinterpret_cast<const char *>(&value);
30+
const uint64_t a = llvm::hashing::detail::fetch32(s);
31+
return llvm::hashing::detail::hash_16_bytes(
32+
(a << 3), llvm::hashing::detail::fetch32(s + 4));
33+
}
34+
35+
static inline llvm::hash_code our_hash_combine(llvm::hash_code seed, llvm::hash_code v) {
36+
return seed ^ (v + 0x9e3779b9 + (seed<<6) + (seed>>2));
37+
}
38+
39+
/// Copy and paste from Metadata.cpp.
40+
41+
namespace {
42+
43+
template<typename PackType>
44+
class PackCacheEntry {
45+
public:
46+
size_t Count;
47+
48+
const PackType * const * getElements() const {
49+
return reinterpret_cast<const PackType * const *>(this + 1);
50+
}
51+
52+
const PackType ** getElements() {
53+
return reinterpret_cast<const PackType **>(this + 1);
54+
}
55+
56+
struct Key {
57+
const PackType *const *Data;
58+
const size_t Count;
59+
60+
size_t getCount() const {
61+
return Count;
62+
}
63+
64+
const PackType *getElement(size_t index) const {
65+
assert(index < Count);
66+
return Data[index];
67+
}
68+
69+
friend llvm::hash_code hash_value(const Key &key) {
70+
llvm::hash_code hash = 0;
71+
for (size_t i = 0; i != key.getCount(); ++i) {
72+
hash = our_hash_combine(hash, our_hash_integer_value(
73+
reinterpret_cast<uint64_t>(key.getElement(i))));
74+
}
75+
return hash;
76+
}
77+
};
78+
79+
PackCacheEntry(const Key &key);
80+
81+
intptr_t getKeyIntValueForDump() {
82+
return 0; // No single meaningful value here.
83+
}
84+
85+
bool matchesKey(const Key &key) const {
86+
if (key.getCount() != Count)
87+
return false;
88+
for (unsigned i = 0; i != Count; ++i) {
89+
if (key.getElement(i) != getElements()[i])
90+
return false;
91+
}
92+
return true;
93+
}
94+
95+
friend llvm::hash_code hash_value(const PackCacheEntry<PackType> &value) {
96+
llvm::hash_code hash = 0;
97+
for (size_t i = 0; i != value.Count; ++i) {
98+
hash = our_hash_combine(hash, our_hash_integer_value(
99+
reinterpret_cast<uint64_t>(value.getElements()[i])));
100+
}
101+
return hash;
102+
}
103+
104+
static size_t getExtraAllocationSize(const Key &key) {
105+
return getExtraAllocationSize(key.Count);
106+
}
107+
108+
size_t getExtraAllocationSize() const {
109+
return getExtraAllocationSize(Count);
110+
}
111+
112+
static size_t getExtraAllocationSize(unsigned count) {
113+
return count * sizeof(const Metadata * const *);
114+
}
115+
};
116+
117+
template<typename PackType>
118+
PackCacheEntry<PackType>::PackCacheEntry(
119+
const typename PackCacheEntry<PackType>::Key &key) {
120+
Count = key.getCount();
121+
122+
for (unsigned i = 0; i < Count; ++i)
123+
getElements()[i] = key.getElement(i);
124+
}
125+
126+
} // end anonymous namespace
127+
128+
/// The uniquing structure for metadata packs.
129+
static SimpleGlobalCache<PackCacheEntry<Metadata>,
130+
MetadataPackTag> MetadataPacks;
131+
132+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
133+
const Metadata * const *
134+
swift_allocateMetadataPack(const Metadata * const *ptr, size_t count) {
135+
if (MetadataPackPointer(reinterpret_cast<uintptr_t>(ptr)).getLifetime()
136+
== PackLifetime::OnHeap)
137+
return ptr;
138+
139+
PackCacheEntry<Metadata>::Key key{ptr, count};
140+
auto bytes = MetadataPacks.getOrInsert(key).first->getElements();
141+
142+
MetadataPackPointer pack(bytes, PackLifetime::OnHeap);
143+
assert(pack.getNumElements() == count);
144+
return pack.getPointer();
145+
}
146+
147+
/// The uniquing structure for witness table packs.
148+
static SimpleGlobalCache<PackCacheEntry<WitnessTable>,
149+
WitnessTablePackTag> WitnessTablePacks;
150+
151+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
152+
const WitnessTable * const *
153+
swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count) {
154+
if (WitnessTablePackPointer(reinterpret_cast<uintptr_t>(ptr)).getLifetime()
155+
== PackLifetime::OnHeap)
156+
return ptr;
157+
158+
PackCacheEntry<WitnessTable>::Key key{ptr, count};
159+
auto bytes = WitnessTablePacks.getOrInsert(key).first->getElements();
160+
161+
WitnessTablePackPointer pack(bytes, PackLifetime::OnHeap);
162+
assert(pack.getNumElements() == count);
163+
return pack.getPointer();
164+
}

test/Driver/compatibility_packs.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-swift-frontend -print-target-info -runtime-compatibility-version 5.8 | %FileCheck %s
2+
3+
// REQUIRES: OS=macosx
4+
5+
// CHECK: "libraryName": "swiftCompatibilityPacks",
6+
// CHECK-NEXT: "filter": "all",
7+
// CHECK-NEXT: "forceLoad": false

test/Interpreter/variadic_generic_captures.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
// REQUIRES: executable_test
55

6-
// UNSUPPORTED: use_os_stdlib
7-
// UNSUPPORTED: back_deployment_runtime
8-
96
import StdlibUnittest
107

118
var types = TestSuite("VariadicGenericCaptures")

0 commit comments

Comments
 (0)