Skip to content

Commit cca45e4

Browse files
committed
Frontend: add a front-end option to specify module names for which we prefer to loading via interfaces
ABI checker imports Swift frameworks by using Swift interfaces for various reasons. The existing way of controlling preferred importing mechanism is by setting an environment variable (SWIFT_FORCE_MODULE_LOADING), which may lead to performance issues because the stdlib could also be loaded in this way. This patch adds a new front-end option to specify module names for which we prefer to importing via Swift interface. The option currently is only accessible via swift-api-digester. rdar://54559888
1 parent fe70904 commit cca45e4

File tree

9 files changed

+64
-7
lines changed

9 files changed

+64
-7
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class FrontendOptions {
7676
/// binary module has already been built for use by the compiler.
7777
std::string PrebuiltModuleCachePath;
7878

79+
/// For these modules, we should prefer using Swift interface when importing them.
80+
std::vector<std::string> PreferInterfaceForModules;
81+
7982
/// Emit index data for imported serialized swift system modules.
8083
bool IndexSystemModules = false;
8184

include/swift/Frontend/ParseableInterfaceModuleLoader.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
128128
explicit ParseableInterfaceModuleLoader(
129129
ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
130130
DependencyTracker *tracker, ModuleLoadingMode loadMode,
131+
ArrayRef<std::string> PreferInterfaceForModules,
131132
bool RemarkOnRebuildFromInterface)
132-
: SerializedModuleLoaderBase(ctx, tracker, loadMode),
133+
: SerializedModuleLoaderBase(ctx, tracker, loadMode, PreferInterfaceForModules),
133134
CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
134135
RemarkOnRebuildFromInterface(RemarkOnRebuildFromInterface)
135136
{}
@@ -150,10 +151,12 @@ class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
150151
static std::unique_ptr<ParseableInterfaceModuleLoader>
151152
create(ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
152153
DependencyTracker *tracker, ModuleLoadingMode loadMode,
154+
ArrayRef<std::string> PreferInterfaceForModules = {},
153155
bool RemarkOnRebuildFromInterface = false) {
154156
return std::unique_ptr<ParseableInterfaceModuleLoader>(
155157
new ParseableInterfaceModuleLoader(ctx, cacheDir, prebuiltCacheDir,
156158
tracker, loadMode,
159+
PreferInterfaceForModules,
157160
RemarkOnRebuildFromInterface));
158161
}
159162

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ class SerializedModuleLoaderBase : public ModuleLoader {
4141
protected:
4242
ASTContext &Ctx;
4343
ModuleLoadingMode LoadMode;
44+
ArrayRef<std::string> PreferInterfaceForModules;
4445
SerializedModuleLoaderBase(ASTContext &ctx, DependencyTracker *tracker,
45-
ModuleLoadingMode LoadMode);
46+
ModuleLoadingMode LoadMode,
47+
ArrayRef<std::string> PreferInterfaceForModules = {});
4648

4749
void collectVisibleTopLevelModuleNamesImpl(SmallVectorImpl<Identifier> &names,
4850
StringRef extension) const;

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,8 @@ bool CompilerInstance::setUpModuleLoaders() {
361361
StringRef PrebuiltModuleCachePath = FEOpts.PrebuiltModuleCachePath;
362362
auto PIML = ParseableInterfaceModuleLoader::create(
363363
*Context, ModuleCachePath, PrebuiltModuleCachePath,
364-
getDependencyTracker(), MLM, FEOpts.RemarkOnRebuildFromModuleInterface);
364+
getDependencyTracker(), MLM, FEOpts.PreferInterfaceForModules,
365+
FEOpts.RemarkOnRebuildFromModuleInterface);
365366
Context->addModuleLoader(std::move(PIML));
366367
}
367368
Context->addModuleLoader(std::move(SML));

lib/Frontend/ParseableInterfaceModuleLoader.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,11 +1425,14 @@ std::error_code ParseableInterfaceModuleLoader::findModuleFilesInDirectory(
14251425
}
14261426

14271427
// Create an instance of the Impl to do the heavy lifting.
1428+
auto ModuleName = ModuleID.first.str();
14281429
ParseableInterfaceModuleLoaderImpl Impl(
1429-
Ctx, ModPath, InPath, ModuleID.first.str(),
1430+
Ctx, ModPath, InPath, ModuleName,
14301431
CacheDir, PrebuiltCacheDir, ModuleID.second,
14311432
RemarkOnRebuildFromInterface, dependencyTracker,
1432-
LoadMode);
1433+
llvm::is_contained(PreferInterfaceForModules,
1434+
ModuleName)?
1435+
ModuleLoadingMode::PreferParseable : LoadMode);
14331436

14341437
// Ask the impl to find us a module that we can load or give us an error
14351438
// telling us that we couldn't load it.

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,10 @@ Optional<bool> forEachModuleSearchPath(
104104

105105
// Defined out-of-line so that we can see ~ModuleFile.
106106
SerializedModuleLoaderBase::SerializedModuleLoaderBase(
107-
ASTContext &ctx, DependencyTracker *tracker, ModuleLoadingMode loadMode)
108-
: ModuleLoader(tracker), Ctx(ctx), LoadMode(loadMode) {}
107+
ASTContext &ctx, DependencyTracker *tracker, ModuleLoadingMode loadMode,
108+
ArrayRef<std::string> PreferInterfaceForModules)
109+
: ModuleLoader(tracker), Ctx(ctx), LoadMode(loadMode),
110+
PreferInterfaceForModules(PreferInterfaceForModules) {}
109111

110112
SerializedModuleLoaderBase::~SerializedModuleLoaderBase() = default;
111113
SerializedModuleLoader::~SerializedModuleLoader() = default;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
cake: Func FrozenKind.__derived_enum_equals(_:_:) has been removed
2+
cake: Accessor GlobalLetChangedToVar.Get() is a new API without @available attribute
3+
cake: Accessor GlobalVarChangedToLet.Get() is a new API without @available attribute
4+
cake: Accessor GlobalVarChangedToLet.Modify() is a new API without @available attribute
5+
cake: Accessor GlobalVarChangedToLet.Set() is a new API without @available attribute
6+
cake: Class C4 is now with @objc
7+
cake: Enum FrozenKind is now with @frozen
8+
cake: Enum IceKind is now with @frozen
9+
cake: Func FrozenKind.==(_:_:) is a new API without @available attribute
10+
cake: Var C1.CIIns1 is no longer a stored property
11+
cake: Var C1.CIIns2 is no longer a stored property
12+
cake: Var RemoveSetters.Value is no longer a stored property
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t.mod1)
2+
// RUN: %empty-directory(%t.mod2)
3+
// RUN: %empty-directory(%t.sdk)
4+
// RUN: %empty-directory(%t.module-cache)
5+
6+
// Generate .swiftinterface file for module cake
7+
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.mod1/cake.swiftinterface %S/Inputs/cake_baseline/cake.swift -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -parse-as-library -enable-library-evolution -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
8+
9+
// Generate .swiftmodule file for module cake
10+
// RUN: %target-swift-frontend -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake_baseline/cake.swift -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -parse-as-library -disable-objc-attr-requires-foundation-module -module-cache-path %t.module-cache
11+
12+
// Dump Json file for cake ABI via .swiftmodule file
13+
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft -abi > %t.dump1.json
14+
15+
// Dump Json file for cake ABI via .swiftinteface file
16+
// RUN: %api-digester -dump-sdk -module cake -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft -abi -use-interface-for-module cake > %t.dump2.json
17+
18+
// Compare two Json files and we should see some differences.
19+
// RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json -abi -o %t.result
20+
21+
// RUN: %clang -E -P -x c %S/Outputs/Cake-interface-vs-binary.txt -o - | sed '/^\s*$/d' > %t.expected
22+
// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
23+
// RUN: diff -u %t.expected %t.result.tmp

tools/swift-api-digester/swift-api-digester.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ static llvm::cl::opt<bool>
229229
Migrator("migrator",
230230
llvm::cl::desc("Dump Json suitable for generating migration script"),
231231
llvm::cl::cat(Category));
232+
233+
static llvm::cl::list<std::string>
234+
PreferInterfaceForModules("use-interface-for-module", llvm::cl::ZeroOrMore,
235+
llvm::cl::desc("Prefer loading these modules via interface"),
236+
llvm::cl::cat(Category));
232237
} // namespace options
233238

234239
namespace {
@@ -2431,6 +2436,9 @@ static int prepareForDump(const char *Main,
24312436
for (auto M : options::ModuleNames) {
24322437
Modules.insert(M);
24332438
}
2439+
for (auto M: options::PreferInterfaceForModules) {
2440+
InitInvok.getFrontendOptions().PreferInterfaceForModules.push_back(M);
2441+
}
24342442
if (Modules.empty()) {
24352443
llvm::errs() << "Need to specify -include-all or -module <name>\n";
24362444
exit(1);

0 commit comments

Comments
 (0)