Skip to content

Commit c8effd2

Browse files
authored
Merge pull request swiftlang#22408 from slavapestov/always-use-legacy-layouts
Always use legacy layouts
2 parents 75b5824 + b64db71 commit c8effd2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+4474
-147
lines changed

cmake/modules/SwiftSource.cmake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,16 @@ function(_compile_swift_files
434434
string(REPLACE ";" "'\n'" source_files_quoted "${source_files}")
435435
file(WRITE "${file_path}" "'${source_files_quoted}'")
436436

437+
# If this platform/architecture combo supports backward deployment to old
438+
# Objective-C runtimes, we need to copy a YAML file with legacy type layout
439+
# information to the build directory so that the compiler can find it.
440+
#
441+
# See stdlib/CMakeLists.txt and TypeConverter::TypeConverter() in
442+
# lib/IRGen/GenType.cpp.
443+
set(SWIFTFILE_PLATFORM "${SWIFT_SDK_${SWIFTFILE_SDK}_LIB_SUBDIR}")
444+
set(copy_legacy_layouts_dep
445+
"copy-legacy-layouts-${SWIFTFILE_PLATFORM}-${SWIFTFILE_ARCHITECTURE}")
446+
437447
add_custom_command_target(
438448
dependency_target
439449
COMMAND
@@ -447,6 +457,7 @@ function(_compile_swift_files
447457
${file_path} ${source_files} ${SWIFTFILE_DEPENDS}
448458
${swift_ide_test_dependency}
449459
${obj_dirs_dependency_target}
460+
${copy_legacy_layouts_dep}
450461
COMMENT "Compiling ${first_output}")
451462
set("${dependency_target_out_var_name}" "${dependency_target}" PARENT_SCOPE)
452463

include/swift/AST/IRGenOptions.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,18 +168,20 @@ class IRGenOptions {
168168
/// Emit mangled names of anonymous context descriptors.
169169
unsigned EnableAnonymousContextMangledNames : 1;
170170

171-
/// Enables resilient class layout.
172-
unsigned EnableClassResilience : 1;
173-
174171
/// Bypass resilience when accessing resilient frameworks.
175172
unsigned EnableResilienceBypass : 1;
176173

177174
/// Force lazy initialization of class metadata
178175
/// Used on Windows to avoid cross-module references.
179176
unsigned LazyInitializeClassMetadata : 1;
180177

178+
/// Normally if the -read-legacy-type-info flag is not specified, we look for
179+
/// a file named "legacy-<arch>.yaml" in SearchPathOpts.RuntimeLibraryPath.
180+
/// Passing this flag completely disables this behavior.
181+
unsigned DisableLegacyTypeInfo : 1;
182+
181183
/// The path to load legacy type layouts from.
182-
StringRef ReadTypeInfoPath;
184+
StringRef ReadLegacyTypeInfoPath;
183185

184186
/// Should we try to build incrementally by not emitting an object file if it
185187
/// has the same IR hash as the module that we are preparing to emit?
@@ -231,8 +233,8 @@ class IRGenOptions {
231233
EmbedMode(IRGenEmbedMode::None), HasValueNamesSetting(false),
232234
ValueNames(false), EnableReflectionMetadata(true),
233235
EnableReflectionNames(true), EnableAnonymousContextMangledNames(false),
234-
EnableClassResilience(false),
235236
EnableResilienceBypass(false), LazyInitializeClassMetadata(false),
237+
DisableLegacyTypeInfo(false),
236238
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
237239
GenerateProfile(false), EnableDynamicReplacementChaining(false),
238240
DisableRoundTripDebugTypes(false),

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,11 @@ def enable_resilience : Flag<["-"], "enable-resilience">,
174174
HelpText<"Compile the module to export resilient interfaces for all "
175175
"public declarations by default">;
176176

177-
def enable_class_resilience : Flag<["-"], "enable-class-resilience">,
178-
HelpText<"Enable resilient layout for classes containing resilient value types">;
177+
def disable_legacy_type_info : Flag<["-"], "disable-legacy-type-info">,
178+
HelpText<"Completely disable legacy type layout">;
179179

180-
def read_type_info_path_EQ : Joined<["-"], "read-type-info-path=">,
181-
HelpText<"Read legacy type layout from the given path">;
180+
def read_legacy_type_info_path_EQ : Joined<["-"], "read-legacy-type-info-path=">,
181+
HelpText<"Read legacy type layout from the given path instead of default path">;
182182
}
183183

184184

lib/Frontend/CompilerInvocation.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,10 +1067,6 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
10671067
Opts.EnableReflectionNames = false;
10681068
}
10691069

1070-
if (Args.hasArg(OPT_enable_class_resilience)) {
1071-
Opts.EnableClassResilience = true;
1072-
}
1073-
10741070
if (Args.hasArg(OPT_enable_resilience_bypass)) {
10751071
Opts.EnableResilienceBypass = true;
10761072
}
@@ -1079,8 +1075,12 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
10791075
// (e.g. NativeObject). Force the lazy initialization of the VWT always.
10801076
Opts.LazyInitializeClassMetadata = Triple.isOSBinFormatCOFF();
10811077

1082-
if (const Arg *A = Args.getLastArg(OPT_read_type_info_path_EQ)) {
1083-
Opts.ReadTypeInfoPath = A->getValue();
1078+
if (Args.hasArg(OPT_disable_legacy_type_info)) {
1079+
Opts.DisableLegacyTypeInfo = true;
1080+
}
1081+
1082+
if (const Arg *A = Args.getLastArg(OPT_read_legacy_type_info_path_EQ)) {
1083+
Opts.ReadLegacyTypeInfoPath = A->getValue();
10841084
}
10851085

10861086
for (const auto &Lib : Args.getAllArgValues(options::OPT_autolink_library))

lib/IRGen/GenClass.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,7 @@ namespace {
376376
// Lower the field type.
377377
auto *eltType = &IGM.getTypeInfo(type);
378378
if (CompletelyFragileLayout && !eltType->isFixedSize()) {
379-
// For staging purposes, only do the new thing if the path flag
380-
// is provided.
381-
auto mode = (IGM.IRGen.Opts.ReadTypeInfoPath.empty()
382-
? TypeConverter::Mode::CompletelyFragile
383-
: TypeConverter::Mode::Legacy);
384-
LoweringModeScope scope(IGM, mode);
379+
LoweringModeScope scope(IGM, TypeConverter::Mode::Legacy);
385380
eltType = &IGM.getTypeInfo(type);
386381
}
387382

@@ -533,12 +528,8 @@ const ClassLayout &
533528
ClassTypeInfo::getClassLayout(IRGenModule &IGM, SILType classType,
534529
bool forBackwardDeployment) const {
535530
// Perform fragile layout only if Objective-C interop is enabled.
536-
//
537-
// FIXME: EnableClassResilience staging flag will go away once we can do
538-
// in-place re-initialization of class metadata.
539531
bool completelyFragileLayout = (forBackwardDeployment &&
540-
IGM.Context.LangOpts.EnableObjCInterop &&
541-
!IGM.IRGen.Opts.EnableClassResilience);
532+
IGM.Context.LangOpts.EnableObjCInterop);
542533

543534
// Return the cached layout if available.
544535
auto &Layout = completelyFragileLayout ? FragileLayout : ResilientLayout;

lib/IRGen/GenType.cpp

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
#include "swift/AST/IRGenOptions.h"
2222
#include "swift/AST/PrettyStackTrace.h"
2323
#include "swift/AST/Types.h"
24+
#include "swift/Basic/Platform.h"
2425
#include "swift/IRGen/Linking.h"
2526
#include "swift/SIL/SILModule.h"
2627
#include "llvm/IR/DerivedTypes.h"
2728
#include "llvm/ADT/SmallString.h"
2829
#include "llvm/Support/ErrorHandling.h"
30+
#include "llvm/Support/Path.h"
2931
#include "clang/CodeGen/SwiftCallingConv.h"
3032

3133
#include "EnumPayload.h"
@@ -1114,6 +1116,30 @@ TypeConverter::getLegacyTypeInfo(NominalTypeDecl *decl) const {
11141116
return found->second;
11151117
}
11161118

1119+
static llvm::StringLiteral platformsWithLegacyLayouts[][2] = {
1120+
{"appletvos", "arm64"},
1121+
{"appletvsimulator", "x86_64"},
1122+
{"iphoneos", "armv7"},
1123+
{"iphoneos", "armv7s"},
1124+
{"iphoneos", "arm64"},
1125+
{"iphonesimulator", "i386"},
1126+
{"iphonesimulator", "x86_64"},
1127+
{"macosx", "x86_64"},
1128+
{"watchos", "armv7k"},
1129+
{"watchsimulator", "i386"}
1130+
};
1131+
1132+
static bool doesPlatformUseLegacyLayouts(StringRef platformName,
1133+
StringRef archName) {
1134+
for (auto platformArchPair : platformsWithLegacyLayouts) {
1135+
if (platformName == platformArchPair[0] &&
1136+
archName == platformArchPair[1]) {
1137+
return true;
1138+
}
1139+
}
1140+
1141+
return false;
1142+
}
11171143
TypeConverter::TypeConverter(IRGenModule &IGM)
11181144
: IGM(IGM),
11191145
FirstType(invalidTypeInfo()) {
@@ -1125,13 +1151,34 @@ TypeConverter::TypeConverter(IRGenModule &IGM)
11251151
if (IGM.IRGen.Opts.EnableResilienceBypass)
11261152
LoweringMode = Mode::CompletelyFragile;
11271153

1128-
StringRef path = IGM.IRGen.Opts.ReadTypeInfoPath;
1129-
if (!path.empty()) {
1130-
bool error = readLegacyTypeInfo(path);
1131-
if (error) {
1132-
llvm::report_fatal_error("Cannot read '" + path + "'");
1133-
}
1154+
// We have a bunch of -parse-stdlib tests that pass a -target in the test
1155+
// suite. To prevent these from failing when the user hasn't build the
1156+
// standard library for that target, we pass -disable-legacy-type-info to
1157+
// disable trying to load the legacy type info.
1158+
if (IGM.IRGen.Opts.DisableLegacyTypeInfo)
1159+
return;
1160+
1161+
auto platformName = getPlatformNameForTriple(IGM.Triple);
1162+
auto archName = getMajorArchitectureName(IGM.Triple);
1163+
1164+
if (!doesPlatformUseLegacyLayouts(platformName, archName))
1165+
return;
1166+
1167+
llvm::SmallString<128> defaultPath;
1168+
1169+
StringRef path = IGM.IRGen.Opts.ReadLegacyTypeInfoPath;
1170+
if (path.empty()) {
1171+
defaultPath.append(IGM.Context.SearchPathOpts.RuntimeLibraryPath);
1172+
llvm::sys::path::append(defaultPath, "layouts-");
1173+
defaultPath.append(archName);
1174+
defaultPath.append(".yaml");
1175+
1176+
path = defaultPath;
11341177
}
1178+
1179+
bool error = readLegacyTypeInfo(path);
1180+
if (error)
1181+
llvm::report_fatal_error("Cannot read '" + path + "'");
11351182
}
11361183

11371184
TypeConverter::~TypeConverter() {

stdlib/CMakeLists.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,48 @@ swift_create_stdlib_targets("swift-stdlib" "sibopt" TRUE)
107107
swift_create_stdlib_targets("swift-stdlib" "sibgen" TRUE)
108108
swift_create_stdlib_targets("swift-test-stdlib" "" FALSE)
109109

110+
foreach(sdk ${SWIFT_SDKS})
111+
foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES})
112+
set(platform "${SWIFT_SDK_${sdk}_LIB_SUBDIR}")
113+
set(input "${SWIFT_SOURCE_DIR}/stdlib/public/legacy_layouts/${platform}/layouts-${arch}.yaml")
114+
set(output "${SWIFTLIB_DIR}/${platform}/layouts-${arch}.yaml")
115+
116+
if(EXISTS "${input}")
117+
# Copy the input file to the build directory.
118+
add_custom_command(
119+
OUTPUT "${output}"
120+
DEPENDS "${input}"
121+
COMMAND
122+
"${CMAKE_COMMAND}" -E copy
123+
"${input}"
124+
"${output}")
125+
126+
# Define a target for this so that we can depend on it when
127+
# building Swift sources.
128+
add_custom_target(
129+
"copy-legacy-layouts-${platform}-${arch}"
130+
DEPENDS "${output}"
131+
SOURCES "${input}")
132+
133+
# Make sure we ultimately always do this as part of building the
134+
# standard library. In practice we'll do this earlier if at least
135+
# one Swift source file has changed.
136+
add_dependencies(
137+
"swift-stdlib-${platform}-${arch}"
138+
"copy-legacy-layouts-${platform}-${arch}")
139+
140+
swift_install_in_component(stdlib
141+
FILES ${input}
142+
DESTINATION "lib/swift/${platform}/")
143+
else()
144+
# Add a dummy target that does nothing so we can still depend on it
145+
# later without checking if the input files exist.
146+
add_custom_target(
147+
"copy-legacy-layouts-${platform}-${arch}")
148+
endif()
149+
endforeach()
150+
endforeach()
151+
110152
add_subdirectory(public)
111153
add_subdirectory(private)
112154
add_subdirectory(tools)

0 commit comments

Comments
 (0)