Skip to content

Commit e483ac9

Browse files
[BrdigingHeader] Auto bridging header chaining
Add ability to automatically chaining the bridging headers discovered from all dependencies module when doing swift caching build. This will eliminate all implicit bridging header imports from the build and make the bridging header importing behavior much more reliable, while keep the compatibility at maximum. For example, if the current module A depends on module B and C, and both B and C are binary modules that uses bridging header, when building module A, dependency scanner will construct a new header that chains three bridging headers together with the option to build a PCH from it. This will make all importing errors more obvious while improving the performance. This is currently only enabled for swift caching since the new chained header is written into CAS directly without the need to serialization.
1 parent 6b2fb2e commit e483ac9

35 files changed

+607
-230
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -786,11 +786,11 @@ class ModuleDependencyInfo {
786786
setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
787787
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
788788
}
789-
789+
790790
const ArrayRef<std::string> getAuxiliaryFiles() const {
791791
return storage->auxiliaryFiles;
792792
}
793-
793+
794794
void
795795
setAuxiliaryFiles(const ArrayRef<std::string> auxiliaryFiles) {
796796
storage->auxiliaryFiles.assign(auxiliaryFiles.begin(), auxiliaryFiles.end());
@@ -978,7 +978,7 @@ class ModuleDependencyInfo {
978978
void addSourceFile(StringRef sourceFile);
979979

980980
/// Add source files that the header input depends on.
981-
void addHeaderSourceFile(StringRef bridgingSourceFile);
981+
void addHeaderSourceFiles(const std::vector<std::string> &sourceFiles);
982982

983983
/// Add bridging header include tree.
984984
void addBridgingHeaderIncludeTree(StringRef ID);
@@ -1196,11 +1196,11 @@ class ModuleDependenciesCache {
11961196
/// Query all dependencies
11971197
ModuleDependencyIDSetVector
11981198
getAllDependencies(const ModuleDependencyID &moduleID) const;
1199-
1199+
12001200
/// Query all Clang module dependencies.
12011201
ModuleDependencyIDSetVector
12021202
getClangDependencies(const ModuleDependencyID &moduleID) const;
1203-
1203+
12041204
/// Query all directly-imported Swift dependencies
12051205
llvm::ArrayRef<ModuleDependencyID>
12061206
getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const;

include/swift/AST/SearchPathOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,9 @@ class SearchPathOptions {
580580
/// "in-package", must not require package-only module dependencies.
581581
bool ResolveInPackageModuleDependencies = false;
582582

583+
/// Enable auto bridging header chaining.
584+
bool BridgingHeaderChaining = false;
585+
583586
/// Return all module search paths that (non-recursively) contain a file whose
584587
/// name is in \p Filenames.
585588
SmallVector<const ModuleSearchPath *, 4>

include/swift/Basic/LangOptions.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ namespace swift {
201201
/// Maximum number of typo corrections we are allowed to perform.
202202
/// This is disabled by default until we can get typo-correction working within acceptable performance bounds.
203203
unsigned TypoCorrectionLimit = 0;
204-
204+
205205
/// Should access control be respected?
206206
bool EnableAccessControl = true;
207207

@@ -260,7 +260,7 @@ namespace swift {
260260

261261
/// Emit a remark when indexing a system module.
262262
bool EnableIndexingSystemModuleRemarks = false;
263-
263+
264264
/// Emit a remark on early exit in explicit interface build
265265
bool EnableSkipExplicitInterfaceModuleBuildRemarks = false;
266266

@@ -691,7 +691,7 @@ namespace swift {
691691
void clearAllPlatformConditionValues() {
692692
PlatformConditionValues.clear();
693693
}
694-
694+
695695
/// Returns the value for the given platform condition or an empty string.
696696
StringRef getPlatformConditionValue(PlatformConditionKind Kind) const;
697697

@@ -871,7 +871,7 @@ namespace swift {
871871
/// 4.2 GHz Intel Core i7.
872872
/// (It's arbitrary, but will keep the compiler from taking too much time.)
873873
unsigned SwitchCheckingInvocationThreshold = 200000;
874-
874+
875875
/// If true, the time it takes to type-check each function will be dumped
876876
/// to llvm::errs().
877877
bool DebugTimeFunctionBodies = false;
@@ -915,7 +915,7 @@ namespace swift {
915915

916916
/// Enable experimental operator designated types feature.
917917
bool EnableOperatorDesignatedTypes = false;
918-
918+
919919
/// Disable constraint system performance hacks.
920920
bool DisableConstraintSolverPerformanceHacks = false;
921921

@@ -963,6 +963,9 @@ namespace swift {
963963
/// The bridging header or PCH that will be imported.
964964
std::string BridgingHeader;
965965

966+
/// The bridging header PCH file.
967+
std::string BridgingHeaderPCH;
968+
966969
/// When automatically generating a precompiled header from the bridging
967970
/// header, place it in this directory.
968971
std::string PrecompiledHeaderOutputDir;
@@ -1084,6 +1087,9 @@ namespace swift {
10841087
/// compilation source targets.
10851088
std::vector<std::string>
10861089
getReducedExtraArgsForSwiftModuleDependency() const;
1090+
1091+
/// Get PCH input path. Return empty string if there is no PCH input.
1092+
std::string getPCHInputPath() const;
10871093
};
10881094

10891095
} // end namespace swift

include/swift/ClangImporter/ClangImporter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,14 +506,16 @@ class ClangImporter final : public ClangModuleLoader {
506506
/// information will be augmented with information about the given
507507
/// textual header inputs.
508508
///
509+
/// \param headerPath the path to the header to be scanned.
510+
///
509511
/// \param clangScanningTool The clang dependency scanner.
510512
///
511513
/// \param cache The module dependencies cache to update, with information
512514
/// about new Clang modules discovered along the way.
513515
///
514516
/// \returns \c true if an error occurred, \c false otherwise
515517
bool getHeaderDependencies(
516-
ModuleDependencyID moduleID,
518+
ModuleDependencyID moduleID, StringRef headerPath,
517519
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
518520
ModuleDependenciesCache &cache,
519521
ModuleDependencyIDSetVector &headerClangModuleDependencies,

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ class ModuleDependencyScanner {
116116
resolveAllClangModuleDependencies(ArrayRef<ModuleDependencyID> swiftModules,
117117
ModuleDependenciesCache &cache,
118118
ModuleDependencyIDSetVector &discoveredClangModules);
119-
void
120-
resolveHeaderDependencies(ArrayRef<ModuleDependencyID> swiftModules,
121-
ModuleDependenciesCache &cache,
122-
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
119+
void resolveHeaderDependencies(
120+
const ModuleDependencyID &rootModuleID,
121+
ArrayRef<ModuleDependencyID> swiftModules, ModuleDependenciesCache &cache,
122+
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
123123
void
124124
resolveSwiftOverlayDependencies(ArrayRef<ModuleDependencyID> swiftModules,
125125
ModuleDependenciesCache &cache,
@@ -151,13 +151,22 @@ class ModuleDependencyScanner {
151151
ModuleDependenciesCache &cache,
152152
llvm::function_ref<void(ModuleDependencyID)> action);
153153

154+
/// Performance BridgingHeader Chaining.
155+
llvm::Error
156+
performBridgingHeaderChaining(const ModuleDependencyID &rootModuleID,
157+
ModuleDependenciesCache &cache,
158+
ModuleDependencyIDSetVector &allModules);
159+
154160
/// Perform an operation utilizing one of the Scanning workers
155161
/// available to this scanner.
156162
template <typename Function, typename... Args>
157163
auto withDependencyScanningWorker(Function &&F, Args &&...ArgList);
158164

159165
Identifier getModuleImportIdentifier(StringRef moduleName);
160166

167+
/// Get scanner output file names.
168+
std::string getOutputFilename(StringRef suffix);
169+
161170
private:
162171
const CompilerInvocation &ScanCompilerInvocation;
163172
ASTContext &ScanASTContext;

include/swift/Frontend/FrontendOptions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ class FrontendOptions {
5454
/// An Objective-C header to import and make implicitly visible.
5555
std::string ImplicitObjCHeaderPath;
5656

57+
/// An Objective-C pch to import and make implicitly visible.
58+
std::string ImplicitObjCPCHPath;
59+
60+
/// The path to embedded bridging header.
61+
std::string EmbedBridgingHeader;
62+
5763
/// The map of aliases and real names of imported or referenced modules.
5864
llvm::StringMap<StringRef> ModuleAliasMap;
5965

@@ -369,6 +375,9 @@ class FrontendOptions {
369375
/// Emit remarks indicating use of the serialized module dependency scanning cache.
370376
bool EmitDependencyScannerCacheRemarks = false;
371377

378+
/// The patch at which the dependency scanner can write generated files.
379+
std::string ScannerOutputDir;
380+
372381
/// Whether the dependency scanner invocation should resolve imports
373382
/// to filesystem modules in parallel.
374383
bool ParallelDependencyScan = true;

include/swift/Option/FrontendOptions.td

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,12 @@ def verify_generic_signatures : Separate<["-"], "verify-generic-signatures">,
161161

162162
def show_diagnostics_after_fatal : Flag<["-"], "show-diagnostics-after-fatal">,
163163
HelpText<"Keep emitting subsequent diagnostics after a fatal error">;
164-
164+
165165
def enable_cross_import_overlays : Flag<["-"], "enable-cross-import-overlays">,
166166
HelpText<"Automatically import declared cross-import overlays.">;
167167
def disable_cross_import_overlays : Flag<["-"], "disable-cross-import-overlays">,
168168
HelpText<"Do not automatically import declared cross-import overlays.">;
169-
169+
170170
def enable_testable_attr_requires_testable_module :
171171
Flag<["-"], "enable-testable-attr-requires-testable-module">,
172172
HelpText<"Enable checking of @testable">;
@@ -186,7 +186,7 @@ def enable_target_os_checking :
186186
def disable_target_os_checking :
187187
Flag<["-"], "disable-target-os-checking">,
188188
HelpText<"Disable checking the target OS of serialized modules">;
189-
189+
190190
def crosscheck_unqualified_lookup : Flag<["-"], "crosscheck-unqualified-lookup">,
191191
HelpText<"Compare legacy DeclContext- to ASTScope-based unqualified name lookup (for debugging)">;
192192

@@ -378,9 +378,9 @@ def public_autolink_library :
378378
// HIDDEN FLAGS
379379
let Flags = [FrontendOption, NoDriverOption, HelpHidden] in {
380380

381-
def enable_experimental_swift_based_closure_specialization :
381+
def enable_experimental_swift_based_closure_specialization :
382382
Flag<["-"], "experimental-swift-based-closure-specialization">,
383-
HelpText<"Use the experimental Swift based closure-specialization optimization pass instead of the existing C++ one">;
383+
HelpText<"Use the experimental Swift based closure-specialization optimization pass instead of the existing C++ one">;
384384

385385
def checked_async_objc_bridging : Joined<["-"], "checked-async-objc-bridging=">,
386386
HelpText<"Control whether checked continuations are used when bridging "
@@ -900,7 +900,7 @@ def disable_concrete_type_metadata_mangled_name_accessors : Flag<["-"], "disable
900900
def disable_standard_substitutions_in_reflection_mangling : Flag<["-"], "disable-standard-substitutions-in-reflection-mangling">,
901901
HelpText<"Disable referencing stdlib symbols via mangled names in reflection mangling">,
902902
Flags<[FrontendOption, HelpHidden]>;
903-
903+
904904
def playground : Flag<["-"], "playground">,
905905
HelpText<"Apply the playground semantics and transformation">;
906906

@@ -940,13 +940,13 @@ def sil_unroll_threshold : Separate<["-"], "sil-unroll-threshold">,
940940

941941
def sil_verify_all : Flag<["-"], "sil-verify-all">,
942942
HelpText<"Verify SIL after each transform">;
943-
943+
944944
def sil_verify_none : Flag<["-"], "sil-verify-none">,
945945
HelpText<"Completely disable SIL verification">;
946946

947947
def sil_ownership_verify_all : Flag<["-"], "sil-ownership-verify-all">,
948948
HelpText<"Verify ownership after each transform">;
949-
949+
950950
def verify_all_substitution_maps : Flag<["-"], "verify-all-substitution-maps">,
951951
HelpText<"Verify all SubstitutionMaps on construction">;
952952

@@ -1165,7 +1165,7 @@ def disable_interface_lockfile : Flag<["-"], "disable-interface-lock">,
11651165
def bridging_header_directory_for_print: Separate<["-"], "bridging-header-directory-for-print">, MetaVarName<"<path>">,
11661166
HelpText<"Directory for bridging header to be printed in compatibility header">;
11671167

1168-
def entry_point_function_name: Separate<["-"], "entry-point-function-name">, MetaVarName<"<string>">,
1168+
def entry_point_function_name: Separate<["-"], "entry-point-function-name">, MetaVarName<"<string>">,
11691169
HelpText<"Name of the entry point function">;
11701170

11711171
def target_sdk_version : Separate<["-"], "target-sdk-version">,
@@ -1452,6 +1452,9 @@ def module_load_mode: Separate<["-"], "module-load-mode">,
14521452
MetaVarName<"only-interface|prefer-interface|prefer-serialized|only-serialized">,
14531453
HelpText<"Module loading mode">;
14541454

1455+
def embed_bridging_header: Separate<["-"], "embed-bridging-header">,
1456+
HelpText<"Path to the preprocessed bridging header to be embedded">;
1457+
14551458
def platform_availability_inheritance_map_path
14561459
: Separate<["-"], "platform-availability-inheritance-map-path">, MetaVarName<"<path>">,
14571460
HelpText<"Path of the platform inheritance platform map">;

include/swift/Option/Options.td

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,12 @@ def verify_incremental_dependencies :
173173
Flag<["-"], "verify-incremental-dependencies">,
174174
Flags<[FrontendOption, HelpHidden]>,
175175
HelpText<"Enable the dependency verifier for each frontend job">;
176-
176+
177177
def strict_implicit_module_context :
178178
Flag<["-"], "strict-implicit-module-context">,
179179
Flags<[FrontendOption, HelpHidden]>,
180180
HelpText<"Enable the strict forwarding of compilation context to downstream implicit module dependencies">;
181-
181+
182182
def no_strict_implicit_module_context :
183183
Flag<["-"], "no-strict-implicit-module-context">,
184184
Flags<[FrontendOption, HelpHidden]>,
@@ -315,7 +315,7 @@ def tools_directory : Separate<["-"], "tools-directory">,
315315

316316
def D : JoinedOrSeparate<["-"], "D">, Flags<[FrontendOption]>,
317317
HelpText<"Marks a conditional compilation flag as true">;
318-
318+
319319
def e : Separate<["-"], "e">, Flags<[NewDriverOnlyOption]>,
320320
HelpText<"Executes a line of code provided on the command line">;
321321

@@ -353,11 +353,22 @@ def import_objc_header : Separate<["-"], "import-objc-header">,
353353
def import_bridging_header : Separate<["-"], "import-bridging-header">,
354354
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
355355
Alias<import_objc_header>;
356+
def import_pch : Separate<["-"], "import-pch">,
357+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
358+
HelpText<"Import bridging header PCH file">;
356359

357360
def pch_output_dir: Separate<["-"], "pch-output-dir">,
358361
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
359362
HelpText<"Directory to persist automatically created precompiled bridging headers">;
360363

364+
def scanner_output_dir: Separate<["-"], "scanner-output-dir">,
365+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
366+
HelpText<"Directory to write generated files from swift dependency scanner">;
367+
368+
def experimental_bridging_header_chaining: Flag<["-"], "experimental-bridging-header-chaining">,
369+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
370+
HelpText<"Automatically chaining all the bridging headers">;
371+
361372
// FIXME: Unhide this once it doesn't depend on an output file map.
362373
def incremental : Flag<["-"], "incremental">,
363374
Flags<[NoInteractiveOption, HelpHidden, DoesNotAffectIncrementalBuild]>,
@@ -2117,7 +2128,7 @@ def external_plugin_path : Separate<["-"], "external-plugin-path">, Group<plugin
21172128
Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>,
21182129
HelpText<"Add directory to the plugin search path with a plugin server executable">,
21192130
MetaVarName<"<path>#<plugin-server-path>">;
2120-
2131+
21212132
def cas_backend: Flag<["-"], "cas-backend">,
21222133
Flags<[FrontendOption, NoDriverOption]>,
21232134
HelpText<"Enable using CASBackend for object file output">;

include/swift/Serialization/SerializationOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class SerializationOptions {
4545

4646
StringRef GroupInfoPath;
4747
StringRef ImportedHeader;
48+
StringRef ImportedPCHPath;
49+
StringRef EmbedBridgingHeader;
4850
StringRef ModuleLinkName;
4951
StringRef ModuleInterface;
5052
std::vector<std::string> ExtraClangOptions;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class SerializedASTFile final : public LoadedFile {
430430
getFilenameForPrivateDecl(const Decl *decl) const override;
431431

432432
virtual TypeDecl *lookupLocalType(StringRef MangledName) const override;
433-
433+
434434
virtual OpaqueTypeDecl *
435435
lookupOpaqueResultType(StringRef MangledName) override;
436436

@@ -577,6 +577,11 @@ bool extractCompilerFlagsFromInterface(
577577

578578
/// Extract the user module version number from an interface file.
579579
llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath);
580+
581+
/// Extract embedded bridging header from binary module.
582+
std::string
583+
extractEmbeddedBridgingHeaderContent(std::unique_ptr<llvm::MemoryBuffer> file,
584+
ASTContext &Context);
580585
} // end namespace swift
581586

582587
#endif

0 commit comments

Comments
 (0)