Skip to content

Commit 9d59044

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 8534f29 commit 9d59044

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

+1096
-277
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 2
28-
#define SWIFTSCAN_VERSION_MINOR 0
28+
#define SWIFTSCAN_VERSION_MINOR 1
2929

3030
SWIFTSCAN_BEGIN_DECLS
3131

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

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

227235
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"
@@ -338,6 +340,12 @@ class SwiftSourceModuleDependenciesStorage
338340
/// The Swift frontend invocation arguments to build bridging header.
339341
std::vector<std::string> bridgingHeaderBuildCommandLine;
340342

343+
/// The chained bridging header path if used.
344+
std::string chainedBridgingHeaderPath;
345+
346+
/// The chained bridging header source buffer if used.
347+
std::string chainedBridgingHeaderContent;
348+
341349
SwiftSourceModuleDependenciesStorage(
342350
StringRef RootID, ArrayRef<StringRef> buildCommandLine,
343351
ArrayRef<ScannerImportStatementInfo> moduleImports,
@@ -354,6 +362,7 @@ class SwiftSourceModuleDependenciesStorage
354362
return new SwiftSourceModuleDependenciesStorage(*this);
355363
}
356364

365+
357366
static bool classof(const ModuleDependencyInfoStorageBase *base) {
358367
return base->dependencyKind == ModuleDependencyKind::SwiftSource;
359368
}
@@ -370,6 +379,11 @@ class SwiftSourceModuleDependenciesStorage
370379
void addTestableImport(ImportPath::Module module) {
371380
testableImports.insert(module.front().Item.str());
372381
}
382+
383+
void setChainedBridgingHeaderBuffer(StringRef path, StringRef buffer) {
384+
chainedBridgingHeaderPath = path.str();
385+
chainedBridgingHeaderContent = buffer.str();
386+
}
373387
};
374388

375389
/// Describes the dependencies of a pre-built Swift module (with no
@@ -769,11 +783,11 @@ class ModuleDependencyInfo {
769783
setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
770784
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
771785
}
772-
786+
773787
const ArrayRef<std::string> getAuxiliaryFiles() const {
774788
return storage->auxiliaryFiles;
775789
}
776-
790+
777791
void
778792
setAuxiliaryFiles(const ArrayRef<std::string> auxiliaryFiles) {
779793
storage->auxiliaryFiles.assign(auxiliaryFiles.begin(), auxiliaryFiles.end());
@@ -961,11 +975,14 @@ class ModuleDependencyInfo {
961975
void addSourceFile(StringRef sourceFile);
962976

963977
/// Add source files that the header input depends on.
964-
void addHeaderSourceFile(StringRef bridgingSourceFile);
978+
void setHeaderSourceFiles(const std::vector<std::string> &sourceFiles);
965979

966980
/// Add bridging header include tree.
967981
void addBridgingHeaderIncludeTree(StringRef ID);
968982

983+
/// Set the chained bridging header buffer.
984+
void setChainedBridgingHeaderBuffer(StringRef path, StringRef buffer);
985+
969986
/// Collect a map from a secondary module name to a list of cross-import
970987
/// overlays, when this current module serves as the primary module.
971988
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
@@ -1025,8 +1042,9 @@ class SwiftDependencyScanningService {
10251042
/// If use clang include tree.
10261043
bool UseClangIncludeTree = false;
10271044

1028-
/// CAS ObjectStore Instance.
1045+
/// CAS Instance.
10291046
std::shared_ptr<llvm::cas::ObjectStore> CAS;
1047+
std::shared_ptr<llvm::cas::ActionCache> ActionCache;
10301048

10311049
/// File prefix mapper.
10321050
std::unique_ptr<llvm::PrefixMapper> Mapper;
@@ -1182,11 +1200,11 @@ class ModuleDependenciesCache {
11821200
/// Query all dependencies
11831201
ModuleDependencyIDSetVector
11841202
getAllDependencies(const ModuleDependencyID &moduleID) const;
1185-
1203+
11861204
/// Query all Clang module dependencies.
11871205
ModuleDependencyIDSetVector
11881206
getClangDependencies(const ModuleDependencyID &moduleID) const;
1189-
1207+
11901208
/// Query all directly-imported Swift dependencies
11911209
llvm::ArrayRef<ModuleDependencyID>
11921210
getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const;

include/swift/AST/SearchPathOptions.h

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

580+
/// Enable auto bridging header chaining.
581+
bool BridgingHeaderChaining = false;
582+
580583
/// Return all module search paths that (non-recursively) contain a file whose
581584
/// name is in \p Filenames.
582585
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

@@ -684,7 +684,7 @@ namespace swift {
684684
void clearAllPlatformConditionValues() {
685685
PlatformConditionValues.clear();
686686
}
687-
687+
688688
/// Returns the value for the given platform condition or an empty string.
689689
StringRef getPlatformConditionValue(PlatformConditionKind Kind) const;
690690

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

909909
/// Enable experimental operator designated types feature.
910910
bool EnableOperatorDesignatedTypes = false;
911-
911+
912912
/// Disable constraint system performance hacks.
913913
bool DisableConstraintSolverPerformanceHacks = false;
914914

@@ -956,6 +956,9 @@ namespace swift {
956956
/// The bridging header or PCH that will be imported.
957957
std::string BridgingHeader;
958958

959+
/// The bridging header PCH file.
960+
std::string BridgingHeaderPCH;
961+
959962
/// When automatically generating a precompiled header from the bridging
960963
/// header, place it in this directory.
961964
std::string PrecompiledHeaderOutputDir;
@@ -1077,6 +1080,9 @@ namespace swift {
10771080
/// compilation source targets.
10781081
std::vector<std::string>
10791082
getReducedExtraArgsForSwiftModuleDependency() const;
1083+
1084+
/// Get PCH input path. Return empty string if there is no PCH input.
1085+
std::string getPCHInputPath() const;
10801086
};
10811087

10821088
} // end namespace swift

include/swift/ClangImporter/ClangImporter.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,14 +508,17 @@ class ClangImporter final : public ClangModuleLoader {
508508
/// information will be augmented with information about the given
509509
/// textual header inputs.
510510
///
511+
/// \param headerPath the path to the header to be scanned.
512+
///
511513
/// \param clangScanningTool The clang dependency scanner.
512514
///
513515
/// \param cache The module dependencies cache to update, with information
514516
/// about new Clang modules discovered along the way.
515517
///
516518
/// \returns \c true if an error occurred, \c false otherwise
517519
bool getHeaderDependencies(
518-
ModuleDependencyID moduleID,
520+
ModuleDependencyID moduleID, std::optional<StringRef> headerPath,
521+
std::optional<llvm::MemoryBufferRef> sourceBuffer,
519522
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
520523
ModuleDependenciesCache &cache,
521524
ModuleDependencyIDSetVector &headerClangModuleDependencies,
@@ -677,6 +680,11 @@ class ClangImporter final : public ClangModuleLoader {
677680
const clang::TypedefType *getTypeDefForCXXCFOptionsDefinition(
678681
const clang::Decl *candidateDecl) override;
679682

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

include/swift/DependencyScan/DependencyScanImpl.h

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

131131
/// User module version
132132
swiftscan_string_ref_t user_module_version;
133+
134+
/// Chained bridging header path.
135+
swiftscan_string_ref_t chained_bridging_header_path;
136+
137+
/// Chained bridging header content.
138+
swiftscan_string_ref_t chained_bridging_header_content;
139+
133140
} swiftscan_swift_textual_details_t;
134141

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

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 18 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,9 @@ 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+
ArrayRef<ModuleDependencyID> swiftModules, ModuleDependenciesCache &cache,
130+
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
123131
void
124132
resolveSwiftOverlayDependencies(ArrayRef<ModuleDependencyID> swiftModules,
125133
ModuleDependenciesCache &cache,
@@ -151,6 +159,12 @@ class ModuleDependencyScanner {
151159
ModuleDependenciesCache &cache,
152160
llvm::function_ref<void(ModuleDependencyID)> action);
153161

162+
/// Performance BridgingHeader Chaining.
163+
llvm::Error
164+
performBridgingHeaderChaining(const ModuleDependencyID &rootModuleID,
165+
ModuleDependenciesCache &cache,
166+
ModuleDependencyIDSetVector &allModules);
167+
154168
/// Perform an operation utilizing one of the Scanning workers
155169
/// available to this scanner.
156170
template <typename Function, typename... Args>

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,9 @@ using SwiftSourceModuleDetailsLayout =
233233
IdentifierIDField, // CASFileSystemRootID
234234
IdentifierIDField, // bridgingHeaderIncludeTree
235235
FlagIDArrayIDField, // buildCommandLine
236-
FlagIDArrayIDField // bridgingHeaderBuildCommandLine
236+
FlagIDArrayIDField, // bridgingHeaderBuildCommandLine
237+
IdentifierIDField, // chainedBridgingHeaderPath
238+
IdentifierIDField // chainedBridgingHeaderContent
237239
>;
238240

239241
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

@@ -374,6 +377,12 @@ class FrontendOptions {
374377
/// Emit remarks indicating use of the serialized module dependency scanning cache.
375378
bool EmitDependencyScannerCacheRemarks = false;
376379

380+
/// The path at which the dependency scanner can write generated files.
381+
std::string ScannerOutputDir;
382+
383+
/// If the scanner output is written directly to the disk for debugging.
384+
bool WriteScannerOutput = false;
385+
377386
/// Whether the dependency scanner invocation should resolve imports
378387
/// to filesystem modules in parallel.
379388
bool ParallelDependencyScan = true;

0 commit comments

Comments
 (0)