Skip to content

Commit 1e65666

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 e9d22f2 commit 1e65666

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
@@ -132,8 +132,9 @@ class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
132132
explicit ParseableInterfaceModuleLoader(
133133
ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
134134
DependencyTracker *tracker, ModuleLoadingMode loadMode,
135+
ArrayRef<std::string> PreferInterfaceForModules,
135136
bool RemarkOnRebuildFromInterface)
136-
: SerializedModuleLoaderBase(ctx, tracker, loadMode),
137+
: SerializedModuleLoaderBase(ctx, tracker, loadMode, PreferInterfaceForModules),
137138
CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
138139
RemarkOnRebuildFromInterface(RemarkOnRebuildFromInterface)
139140
{}
@@ -154,10 +155,12 @@ class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
154155
static std::unique_ptr<ParseableInterfaceModuleLoader>
155156
create(ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
156157
DependencyTracker *tracker, ModuleLoadingMode loadMode,
158+
ArrayRef<std::string> PreferInterfaceForModules = {},
157159
bool RemarkOnRebuildFromInterface = false) {
158160
return std::unique_ptr<ParseableInterfaceModuleLoader>(
159161
new ParseableInterfaceModuleLoader(ctx, cacheDir, prebuiltCacheDir,
160162
tracker, loadMode,
163+
PreferInterfaceForModules,
161164
RemarkOnRebuildFromInterface));
162165
}
163166

include/swift/Serialization/SerializedModuleLoader.h

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

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

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ bool CompilerInstance::setUpModuleLoaders() {
373373
StringRef PrebuiltModuleCachePath = FEOpts.PrebuiltModuleCachePath;
374374
auto PIML = ParseableInterfaceModuleLoader::create(
375375
*Context, ModuleCachePath, PrebuiltModuleCachePath,
376-
getDependencyTracker(), MLM, FEOpts.RemarkOnRebuildFromModuleInterface);
376+
getDependencyTracker(), MLM, FEOpts.PreferInterfaceForModules,
377+
FEOpts.RemarkOnRebuildFromModuleInterface);
377378
Context->addModuleLoader(std::move(PIML));
378379
}
379380
Context->addModuleLoader(std::move(SML));

lib/Frontend/ParseableInterfaceModuleLoader.cpp

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

14371437
// Create an instance of the Impl to do the heavy lifting.
1438+
auto ModuleName = ModuleID.first.str();
14381439
ParseableInterfaceModuleLoaderImpl Impl(
1439-
Ctx, ModPath, InPath, ModuleID.first.str(),
1440+
Ctx, ModPath, InPath, ModuleName,
14401441
CacheDir, PrebuiltCacheDir, ModuleID.second,
14411442
RemarkOnRebuildFromInterface, dependencyTracker,
1442-
LoadMode);
1443+
llvm::is_contained(PreferInterfaceForModules,
1444+
ModuleName)?
1445+
ModuleLoadingMode::PreferParseable : LoadMode);
14431446

14441447
// Ask the impl to find us a module that we can load or give us an error
14451448
// 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)