Skip to content

Commit 57c20e4

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.
1 parent 9907afa commit 57c20e4

38 files changed

+900
-243
lines changed

include/swift/AST/ModuleDependencies.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/ADT/DenseSet.h"
3131
#include "llvm/ADT/IntrusiveRefCntPtr.h"
3232
#include "llvm/ADT/StringSet.h"
33+
#include "llvm/CAS/ActionCache.h"
3334
#include "llvm/CAS/CASProvidingFileSystem.h"
3435
#include "llvm/CAS/CASReference.h"
3536
#include "llvm/CAS/CachingOnDiskFileSystem.h"
@@ -786,11 +787,11 @@ class ModuleDependencyInfo {
786787
setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
787788
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
788789
}
789-
790+
790791
const ArrayRef<std::string> getAuxiliaryFiles() const {
791792
return storage->auxiliaryFiles;
792793
}
793-
794+
794795
void
795796
setAuxiliaryFiles(const ArrayRef<std::string> auxiliaryFiles) {
796797
storage->auxiliaryFiles.assign(auxiliaryFiles.begin(), auxiliaryFiles.end());
@@ -978,7 +979,7 @@ class ModuleDependencyInfo {
978979
void addSourceFile(StringRef sourceFile);
979980

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

983984
/// Add bridging header include tree.
984985
void addBridgingHeaderIncludeTree(StringRef ID);
@@ -1042,8 +1043,9 @@ class SwiftDependencyScanningService {
10421043
/// If use clang include tree.
10431044
bool UseClangIncludeTree = false;
10441045

1045-
/// CAS ObjectStore Instance.
1046+
/// CAS Instance.
10461047
std::shared_ptr<llvm::cas::ObjectStore> CAS;
1048+
std::shared_ptr<llvm::cas::ActionCache> ActionCache;
10471049

10481050
/// File prefix mapper.
10491051
std::unique_ptr<llvm::PrefixMapper> Mapper;
@@ -1196,11 +1198,11 @@ class ModuleDependenciesCache {
11961198
/// Query all dependencies
11971199
ModuleDependencyIDSetVector
11981200
getAllDependencies(const ModuleDependencyID &moduleID) const;
1199-
1201+
12001202
/// Query all Clang module dependencies.
12011203
ModuleDependencyIDSetVector
12021204
getClangDependencies(const ModuleDependencyID &moduleID) const;
1203-
1205+
12041206
/// Query all directly-imported Swift dependencies
12051207
llvm::ArrayRef<ModuleDependencyID>
12061208
getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const;

include/swift/AST/SearchPathOptions.h

+3
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

+11-5
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

+3-1
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

+22-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/ModuleDependencies.h"
1717
#include "swift/Frontend/ModuleInterfaceLoader.h"
1818
#include "swift/Serialization/SerializedModuleLoader.h"
19+
#include "llvm/CAS/CASReference.h"
1920
#include "llvm/Support/ThreadPool.h"
2021

2122
namespace swift {
@@ -48,6 +49,11 @@ class ModuleDependencyScanningWorker {
4849
llvm::PrefixMapper *prefixMapper,
4950
bool isTestableImport = false);
5051

52+
/// Store cache entry for include tree.
53+
llvm::Error
54+
createCacheKeyForEmbeddedHeader(std::string embeddedHeaderIncludeTree,
55+
std::string chainedHeaderIncludeTree);
56+
5157
// Worker-specific instance of CompilerInvocation
5258
std::unique_ptr<CompilerInvocation> workerCompilerInvocation;
5359
// Worker-specific instance of ASTContext
@@ -59,6 +65,9 @@ class ModuleDependencyScanningWorker {
5965
// Swift and Clang module loaders acting as scanners.
6066
std::unique_ptr<ModuleInterfaceLoader> swiftScannerModuleLoader;
6167
std::unique_ptr<ClangImporter> clangScannerModuleLoader;
68+
// CAS instance.
69+
std::shared_ptr<llvm::cas::ObjectStore> CAS;
70+
std::shared_ptr<llvm::cas::ActionCache> ActionCache;
6271
// Restrict access to the parent scanner class.
6372
friend class ModuleDependencyScanner;
6473
};
@@ -116,10 +125,10 @@ class ModuleDependencyScanner {
116125
resolveAllClangModuleDependencies(ArrayRef<ModuleDependencyID> swiftModules,
117126
ModuleDependenciesCache &cache,
118127
ModuleDependencyIDSetVector &discoveredClangModules);
119-
void
120-
resolveHeaderDependencies(ArrayRef<ModuleDependencyID> swiftModules,
121-
ModuleDependenciesCache &cache,
122-
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
128+
void resolveHeaderDependencies(
129+
const ModuleDependencyID &rootModuleID,
130+
ArrayRef<ModuleDependencyID> swiftModules, ModuleDependenciesCache &cache,
131+
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
123132
void
124133
resolveSwiftOverlayDependencies(ArrayRef<ModuleDependencyID> swiftModules,
125134
ModuleDependenciesCache &cache,
@@ -151,13 +160,22 @@ class ModuleDependencyScanner {
151160
ModuleDependenciesCache &cache,
152161
llvm::function_ref<void(ModuleDependencyID)> action);
153162

163+
/// Performance BridgingHeader Chaining.
164+
llvm::Error
165+
performBridgingHeaderChaining(const ModuleDependencyID &rootModuleID,
166+
ModuleDependenciesCache &cache,
167+
ModuleDependencyIDSetVector &allModules);
168+
154169
/// Perform an operation utilizing one of the Scanning workers
155170
/// available to this scanner.
156171
template <typename Function, typename... Args>
157172
auto withDependencyScanningWorker(Function &&F, Args &&...ArgList);
158173

159174
Identifier getModuleImportIdentifier(StringRef moduleName);
160175

176+
/// Get scanner output file names.
177+
std::string getOutputFilename(StringRef suffix);
178+
161179
private:
162180
const CompilerInvocation &ScanCompilerInvocation;
163181
ASTContext &ScanASTContext;

include/swift/Frontend/CompileJobCacheKey.h

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/DiagnosticEngine.h"
2222
#include "swift/Basic/FileTypes.h"
2323
#include "llvm/ADT/ArrayRef.h"
24+
#include "llvm/CAS/CASReference.h"
2425
#include "llvm/CAS/ObjectStore.h"
2526
#include "llvm/Support/Error.h"
2627
#include "llvm/Support/raw_ostream.h"
@@ -49,6 +50,11 @@ createCompileJobCacheKeyForOutput(llvm::cas::ObjectStore &CAS,
4950
llvm::Error printCompileJobCacheKey(llvm::cas::ObjectStore &CAS,
5051
llvm::cas::ObjectRef Key,
5152
llvm::raw_ostream &os);
53+
54+
/// Create cache key for embedded bridging header.
55+
llvm::Expected<llvm::cas::ObjectRef> createEmbeddedBridgingHeaderCacheKey(
56+
llvm::cas::ObjectStore &CAS, llvm::cas::ObjectRef ChainedPCHIncludeTree);
57+
5258
} // namespace swift
5359

5460
#endif

include/swift/Frontend/FrontendOptions.h

+6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ 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+
5760
/// The map of aliases and real names of imported or referenced modules.
5861
llvm::StringMap<StringRef> ModuleAliasMap;
5962

@@ -369,6 +372,9 @@ class FrontendOptions {
369372
/// Emit remarks indicating use of the serialized module dependency scanning cache.
370373
bool EmitDependencyScannerCacheRemarks = false;
371374

375+
/// The path at which the dependency scanner can write generated files.
376+
std::string ScannerOutputDir;
377+
372378
/// Whether the dependency scanner invocation should resolve imports
373379
/// to filesystem modules in parallel.
374380
bool ParallelDependencyScan = true;

include/swift/Option/FrontendOptions.td

+9-9
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">,

include/swift/Option/Options.td

+15-4
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]>,
@@ -2123,7 +2134,7 @@ def external_plugin_path : Separate<["-"], "external-plugin-path">, Group<plugin
21232134
Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>,
21242135
HelpText<"Add directory to the plugin search path with a plugin server executable">,
21252136
MetaVarName<"<path>#<plugin-server-path>">;
2126-
2137+
21272138
def cas_backend: Flag<["-"], "cas-backend">,
21282139
Flags<[FrontendOption, NoDriverOption]>,
21292140
HelpText<"Enable using CASBackend for object file output">;

include/swift/Serialization/SerializationOptions.h

+2
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+
bool SerializeBridgingHeader = false;
4850
StringRef ModuleLinkName;
4951
StringRef ModuleInterface;
5052
std::vector<std::string> ExtraClangOptions;

0 commit comments

Comments
 (0)