Skip to content

Commit 8b2df4f

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 18fa490 commit 8b2df4f

Some content is hidden

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

44 files changed

+1093
-280
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/// SWIFTSCAN_VERSION_MINOR should increase when there are API additions.
2626
/// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
2727
#define SWIFTSCAN_VERSION_MAJOR 1
28-
#define SWIFTSCAN_VERSION_MINOR 0
28+
#define SWIFTSCAN_VERSION_MINOR 1
2929

3030
SWIFTSCAN_BEGIN_DECLS
3131

@@ -221,6 +221,14 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t
221221
swiftscan_swift_textual_detail_get_user_module_version(
222222
swiftscan_module_details_t details);
223223

224+
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
225+
swiftscan_swift_textual_detail_get_chained_bridging_header_path(
226+
swiftscan_module_details_t details);
227+
228+
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
229+
swiftscan_swift_textual_detail_get_chained_bridging_header_content(
230+
swiftscan_module_details_t details);
231+
224232
//=== Swift Binary Module Details query APIs ------------------------------===//
225233

226234
SWIFTSCAN_PUBLIC swiftscan_string_ref_t

include/swift/AST/ModuleDependencies.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
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"
3637
#include "llvm/CAS/ObjectStore.h"
3738
#include "llvm/Support/Error.h"
39+
#include "llvm/Support/MemoryBuffer.h"
3840
#include "llvm/Support/Mutex.h"
3941
#include "llvm/Support/PrefixMapper.h"
4042
#include "llvm/Support/VirtualFileSystem.h"
@@ -344,6 +346,12 @@ class SwiftSourceModuleDependenciesStorage
344346
/// The Swift frontend invocation arguments to build bridging header.
345347
std::vector<std::string> bridgingHeaderBuildCommandLine;
346348

349+
/// The chained bridging header path if used.
350+
std::string chainedBridgingHeaderPath;
351+
352+
/// The chained bridging header source buffer if used.
353+
std::string chainedBridgingHeaderContent;
354+
347355
SwiftSourceModuleDependenciesStorage(
348356
StringRef RootID, ArrayRef<StringRef> buildCommandLine,
349357
ArrayRef<ScannerImportStatementInfo> moduleImports,
@@ -361,6 +369,7 @@ class SwiftSourceModuleDependenciesStorage
361369
return new SwiftSourceModuleDependenciesStorage(*this);
362370
}
363371

372+
364373
static bool classof(const ModuleDependencyInfoStorageBase *base) {
365374
return base->dependencyKind == ModuleDependencyKind::SwiftSource;
366375
}
@@ -377,6 +386,11 @@ class SwiftSourceModuleDependenciesStorage
377386
void addTestableImport(ImportPath::Module module) {
378387
testableImports.insert(module.front().Item.str());
379388
}
389+
390+
void setChainedBridgingHeaderBuffer(StringRef path, StringRef buffer) {
391+
chainedBridgingHeaderPath = path.str();
392+
chainedBridgingHeaderContent = buffer.str();
393+
}
380394
};
381395

382396
/// Describes the dependencies of a pre-built Swift module (with no
@@ -786,11 +800,11 @@ class ModuleDependencyInfo {
786800
setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
787801
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
788802
}
789-
803+
790804
const ArrayRef<std::string> getAuxiliaryFiles() const {
791805
return storage->auxiliaryFiles;
792806
}
793-
807+
794808
void
795809
setAuxiliaryFiles(const ArrayRef<std::string> auxiliaryFiles) {
796810
storage->auxiliaryFiles.assign(auxiliaryFiles.begin(), auxiliaryFiles.end());
@@ -978,11 +992,14 @@ class ModuleDependencyInfo {
978992
void addSourceFile(StringRef sourceFile);
979993

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

983997
/// Add bridging header include tree.
984998
void addBridgingHeaderIncludeTree(StringRef ID);
985999

1000+
/// Set the chained bridging header buffer.
1001+
void setChainedBridgingHeaderBuffer(StringRef path, StringRef buffer);
1002+
9861003
/// Collect a map from a secondary module name to a list of cross-import
9871004
/// overlays, when this current module serves as the primary module.
9881005
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
@@ -1042,8 +1059,9 @@ class SwiftDependencyScanningService {
10421059
/// If use clang include tree.
10431060
bool UseClangIncludeTree = false;
10441061

1045-
/// CAS ObjectStore Instance.
1062+
/// CAS Instance.
10461063
std::shared_ptr<llvm::cas::ObjectStore> CAS;
1064+
std::shared_ptr<llvm::cas::ActionCache> ActionCache;
10471065

10481066
/// File prefix mapper.
10491067
std::unique_ptr<llvm::PrefixMapper> Mapper;
@@ -1196,11 +1214,11 @@ class ModuleDependenciesCache {
11961214
/// Query all dependencies
11971215
ModuleDependencyIDSetVector
11981216
getAllDependencies(const ModuleDependencyID &moduleID) const;
1199-
1217+
12001218
/// Query all Clang module dependencies.
12011219
ModuleDependencyIDSetVector
12021220
getClangDependencies(const ModuleDependencyID &moduleID) const;
1203-
1221+
12041222
/// Query all directly-imported Swift dependencies
12051223
llvm::ArrayRef<ModuleDependencyID>
12061224
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

@@ -687,7 +687,7 @@ namespace swift {
687687
void clearAllPlatformConditionValues() {
688688
PlatformConditionValues.clear();
689689
}
690-
690+
691691
/// Returns the value for the given platform condition or an empty string.
692692
StringRef getPlatformConditionValue(PlatformConditionKind Kind) const;
693693

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

912912
/// Enable experimental operator designated types feature.
913913
bool EnableOperatorDesignatedTypes = false;
914-
914+
915915
/// Disable constraint system performance hacks.
916916
bool DisableConstraintSolverPerformanceHacks = false;
917917

@@ -959,6 +959,9 @@ namespace swift {
959959
/// The bridging header or PCH that will be imported.
960960
std::string BridgingHeader;
961961

962+
/// The bridging header PCH file.
963+
std::string BridgingHeaderPCH;
964+
962965
/// When automatically generating a precompiled header from the bridging
963966
/// header, place it in this directory.
964967
std::string PrecompiledHeaderOutputDir;
@@ -1080,6 +1083,9 @@ namespace swift {
10801083
/// compilation source targets.
10811084
std::vector<std::string>
10821085
getReducedExtraArgsForSwiftModuleDependency() const;
1086+
1087+
/// Get PCH input path. Return empty string if there is no PCH input.
1088+
std::string getPCHInputPath() const;
10831089
};
10841090

10851091
} // end namespace swift

include/swift/ClangImporter/ClangImporter.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,14 +506,17 @@ 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, std::optional<StringRef> headerPath,
519+
std::optional<llvm::MemoryBufferRef> sourceBuffer,
517520
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
518521
ModuleDependenciesCache &cache,
519522
ModuleDependencyIDSetVector &headerClangModuleDependencies,
@@ -675,6 +678,11 @@ class ClangImporter final : public ClangModuleLoader {
675678
const clang::TypedefType *getTypeDefForCXXCFOptionsDefinition(
676679
const clang::Decl *candidateDecl) override;
677680

681+
/// Create cache key for embedded bridging header.
682+
static llvm::Expected<llvm::cas::ObjectRef>
683+
createEmbeddedBridgingHeaderCacheKey(
684+
llvm::cas::ObjectStore &CAS, llvm::cas::ObjectRef ChainedPCHIncludeTree);
685+
678686
SourceLoc importSourceLocation(clang::SourceLocation loc) override;
679687
};
680688

include/swift/DependencyScan/DependencyScanImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ typedef struct {
135135

136136
/// User module version
137137
swiftscan_string_ref_t user_module_version;
138+
139+
/// Chained bridging header path.
140+
swiftscan_string_ref_t chained_bridging_header_path;
141+
142+
/// Chained bridging header content.
143+
swiftscan_string_ref_t chained_bridging_header_content;
144+
138145
} swiftscan_swift_textual_details_t;
139146

140147
/// Swift modules with only a binary module file.

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 19 additions & 4 deletions
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,6 +160,12 @@ 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>

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,9 @@ using SwiftSourceModuleDetailsLayout =
227227
IdentifierIDField, // CASFileSystemRootID
228228
IdentifierIDField, // bridgingHeaderIncludeTree
229229
FlagIDArrayIDField, // buildCommandLine
230-
FlagIDArrayIDField // bridgingHeaderBuildCommandLine
230+
FlagIDArrayIDField, // bridgingHeaderBuildCommandLine
231+
IdentifierIDField, // chainedBridgingHeaderPath
232+
IdentifierIDField // chainedBridgingHeaderContent
231233
>;
232234

233235
using SwiftBinaryModuleDetailsLayout =

include/swift/Frontend/CompileJobCacheKey.h

Lines changed: 2 additions & 0 deletions
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,7 @@ createCompileJobCacheKeyForOutput(llvm::cas::ObjectStore &CAS,
4950
llvm::Error printCompileJobCacheKey(llvm::cas::ObjectStore &CAS,
5051
llvm::cas::ObjectRef Key,
5152
llvm::raw_ostream &os);
53+
5254
} // namespace swift
5355

5456
#endif

include/swift/Frontend/FrontendOptions.h

Lines changed: 9 additions & 0 deletions
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,12 @@ 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+
378+
/// If the scanner output is written directly to the disk for debugging.
379+
bool WriteScannerOutput = false;
380+
372381
/// Whether the dependency scanner invocation should resolve imports
373382
/// to filesystem modules in parallel.
374383
bool ParallelDependencyScan = true;

0 commit comments

Comments
 (0)