Skip to content

Commit

Permalink
[BrdigingHeader] Auto bridging header chaining
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cachemeifyoucan committed Jan 22, 2025
1 parent 2e92644 commit 055cccd
Show file tree
Hide file tree
Showing 38 changed files with 897 additions and 242 deletions.
14 changes: 8 additions & 6 deletions include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/CAS/ActionCache.h"
#include "llvm/CAS/CASProvidingFileSystem.h"
#include "llvm/CAS/CASReference.h"
#include "llvm/CAS/CachingOnDiskFileSystem.h"
Expand Down Expand Up @@ -786,11 +787,11 @@ class ModuleDependencyInfo {
setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
}

const ArrayRef<std::string> getAuxiliaryFiles() const {
return storage->auxiliaryFiles;
}

void
setAuxiliaryFiles(const ArrayRef<std::string> auxiliaryFiles) {
storage->auxiliaryFiles.assign(auxiliaryFiles.begin(), auxiliaryFiles.end());
Expand Down Expand Up @@ -978,7 +979,7 @@ class ModuleDependencyInfo {
void addSourceFile(StringRef sourceFile);

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

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

/// CAS ObjectStore Instance.
/// CAS Instance.
std::shared_ptr<llvm::cas::ObjectStore> CAS;
std::shared_ptr<llvm::cas::ActionCache> ActionCache;

/// File prefix mapper.
std::unique_ptr<llvm::PrefixMapper> Mapper;
Expand Down Expand Up @@ -1196,11 +1198,11 @@ class ModuleDependenciesCache {
/// Query all dependencies
ModuleDependencyIDSetVector
getAllDependencies(const ModuleDependencyID &moduleID) const;

/// Query all Clang module dependencies.
ModuleDependencyIDSetVector
getClangDependencies(const ModuleDependencyID &moduleID) const;

/// Query all directly-imported Swift dependencies
llvm::ArrayRef<ModuleDependencyID>
getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const;
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/SearchPathOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,9 @@ class SearchPathOptions {
/// "in-package", must not require package-only module dependencies.
bool ResolveInPackageModuleDependencies = false;

/// Enable auto bridging header chaining.
bool BridgingHeaderChaining = false;

/// Return all module search paths that (non-recursively) contain a file whose
/// name is in \p Filenames.
SmallVector<const ModuleSearchPath *, 4>
Expand Down
16 changes: 11 additions & 5 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ namespace swift {
/// Maximum number of typo corrections we are allowed to perform.
/// This is disabled by default until we can get typo-correction working within acceptable performance bounds.
unsigned TypoCorrectionLimit = 0;

/// Should access control be respected?
bool EnableAccessControl = true;

Expand Down Expand Up @@ -260,7 +260,7 @@ namespace swift {

/// Emit a remark when indexing a system module.
bool EnableIndexingSystemModuleRemarks = false;

/// Emit a remark on early exit in explicit interface build
bool EnableSkipExplicitInterfaceModuleBuildRemarks = false;

Expand Down Expand Up @@ -691,7 +691,7 @@ namespace swift {
void clearAllPlatformConditionValues() {
PlatformConditionValues.clear();
}

/// Returns the value for the given platform condition or an empty string.
StringRef getPlatformConditionValue(PlatformConditionKind Kind) const;

Expand Down Expand Up @@ -871,7 +871,7 @@ namespace swift {
/// 4.2 GHz Intel Core i7.
/// (It's arbitrary, but will keep the compiler from taking too much time.)
unsigned SwitchCheckingInvocationThreshold = 200000;

/// If true, the time it takes to type-check each function will be dumped
/// to llvm::errs().
bool DebugTimeFunctionBodies = false;
Expand Down Expand Up @@ -915,7 +915,7 @@ namespace swift {

/// Enable experimental operator designated types feature.
bool EnableOperatorDesignatedTypes = false;

/// Disable constraint system performance hacks.
bool DisableConstraintSolverPerformanceHacks = false;

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

/// The bridging header PCH file.
std::string BridgingHeaderPCH;

/// When automatically generating a precompiled header from the bridging
/// header, place it in this directory.
std::string PrecompiledHeaderOutputDir;
Expand Down Expand Up @@ -1084,6 +1087,9 @@ namespace swift {
/// compilation source targets.
std::vector<std::string>
getReducedExtraArgsForSwiftModuleDependency() const;

/// Get PCH input path. Return empty string if there is no PCH input.
std::string getPCHInputPath() const;
};

} // end namespace swift
Expand Down
4 changes: 3 additions & 1 deletion include/swift/ClangImporter/ClangImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,14 +506,16 @@ class ClangImporter final : public ClangModuleLoader {
/// information will be augmented with information about the given
/// textual header inputs.
///
/// \param headerPath the path to the header to be scanned.
///
/// \param clangScanningTool The clang dependency scanner.
///
/// \param cache The module dependencies cache to update, with information
/// about new Clang modules discovered along the way.
///
/// \returns \c true if an error occurred, \c false otherwise
bool getHeaderDependencies(
ModuleDependencyID moduleID,
ModuleDependencyID moduleID, StringRef headerPath,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &headerClangModuleDependencies,
Expand Down
26 changes: 22 additions & 4 deletions include/swift/DependencyScan/ModuleDependencyScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "swift/AST/ModuleDependencies.h"
#include "swift/Frontend/ModuleInterfaceLoader.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "llvm/CAS/CASReference.h"
#include "llvm/Support/ThreadPool.h"

namespace swift {
Expand Down Expand Up @@ -48,6 +49,11 @@ class ModuleDependencyScanningWorker {
llvm::PrefixMapper *prefixMapper,
bool isTestableImport = false);

/// Store cache entry for include tree.
llvm::Error
createCacheKeyForEmbeddedHeader(std::string embeddedHeaderIncludeTree,
std::string chainedHeaderIncludeTree);

// Worker-specific instance of CompilerInvocation
std::unique_ptr<CompilerInvocation> workerCompilerInvocation;
// Worker-specific instance of ASTContext
Expand All @@ -59,6 +65,9 @@ class ModuleDependencyScanningWorker {
// Swift and Clang module loaders acting as scanners.
std::unique_ptr<ModuleInterfaceLoader> swiftScannerModuleLoader;
std::unique_ptr<ClangImporter> clangScannerModuleLoader;
// CAS instance.
std::shared_ptr<llvm::cas::ObjectStore> CAS;
std::shared_ptr<llvm::cas::ActionCache> ActionCache;
// Restrict access to the parent scanner class.
friend class ModuleDependencyScanner;
};
Expand Down Expand Up @@ -116,10 +125,10 @@ class ModuleDependencyScanner {
resolveAllClangModuleDependencies(ArrayRef<ModuleDependencyID> swiftModules,
ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &discoveredClangModules);
void
resolveHeaderDependencies(ArrayRef<ModuleDependencyID> swiftModules,
ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
void resolveHeaderDependencies(
const ModuleDependencyID &rootModuleID,
ArrayRef<ModuleDependencyID> swiftModules, ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
void
resolveSwiftOverlayDependencies(ArrayRef<ModuleDependencyID> swiftModules,
ModuleDependenciesCache &cache,
Expand Down Expand Up @@ -151,13 +160,22 @@ class ModuleDependencyScanner {
ModuleDependenciesCache &cache,
llvm::function_ref<void(ModuleDependencyID)> action);

/// Performance BridgingHeader Chaining.
llvm::Error
performBridgingHeaderChaining(const ModuleDependencyID &rootModuleID,
ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &allModules);

/// Perform an operation utilizing one of the Scanning workers
/// available to this scanner.
template <typename Function, typename... Args>
auto withDependencyScanningWorker(Function &&F, Args &&...ArgList);

Identifier getModuleImportIdentifier(StringRef moduleName);

/// Get scanner output file names.
std::string getOutputFilename(StringRef suffix);

private:
const CompilerInvocation &ScanCompilerInvocation;
ASTContext &ScanASTContext;
Expand Down
6 changes: 6 additions & 0 deletions include/swift/Frontend/CompileJobCacheKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "swift/AST/DiagnosticEngine.h"
#include "swift/Basic/FileTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/CAS/CASReference.h"
#include "llvm/CAS/ObjectStore.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
Expand Down Expand Up @@ -49,6 +50,11 @@ createCompileJobCacheKeyForOutput(llvm::cas::ObjectStore &CAS,
llvm::Error printCompileJobCacheKey(llvm::cas::ObjectStore &CAS,
llvm::cas::ObjectRef Key,
llvm::raw_ostream &os);

/// Create cache key for embedded bridging header.
llvm::Expected<llvm::cas::ObjectRef> createEmbeddedBridgingHeaderCacheKey(
llvm::cas::ObjectStore &CAS, llvm::cas::ObjectRef ChainedPCHIncludeTree);

} // namespace swift

#endif
6 changes: 6 additions & 0 deletions include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class FrontendOptions {
/// An Objective-C header to import and make implicitly visible.
std::string ImplicitObjCHeaderPath;

/// An Objective-C pch to import and make implicitly visible.
std::string ImplicitObjCPCHPath;

/// The map of aliases and real names of imported or referenced modules.
llvm::StringMap<StringRef> ModuleAliasMap;

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

/// The path at which the dependency scanner can write generated files.
std::string ScannerOutputDir;

/// Whether the dependency scanner invocation should resolve imports
/// to filesystem modules in parallel.
bool ParallelDependencyScan = true;
Expand Down
18 changes: 9 additions & 9 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,12 @@ def verify_generic_signatures : Separate<["-"], "verify-generic-signatures">,

def show_diagnostics_after_fatal : Flag<["-"], "show-diagnostics-after-fatal">,
HelpText<"Keep emitting subsequent diagnostics after a fatal error">;

def enable_cross_import_overlays : Flag<["-"], "enable-cross-import-overlays">,
HelpText<"Automatically import declared cross-import overlays.">;
def disable_cross_import_overlays : Flag<["-"], "disable-cross-import-overlays">,
HelpText<"Do not automatically import declared cross-import overlays.">;

def enable_testable_attr_requires_testable_module :
Flag<["-"], "enable-testable-attr-requires-testable-module">,
HelpText<"Enable checking of @testable">;
Expand All @@ -186,7 +186,7 @@ def enable_target_os_checking :
def disable_target_os_checking :
Flag<["-"], "disable-target-os-checking">,
HelpText<"Disable checking the target OS of serialized modules">;

def crosscheck_unqualified_lookup : Flag<["-"], "crosscheck-unqualified-lookup">,
HelpText<"Compare legacy DeclContext- to ASTScope-based unqualified name lookup (for debugging)">;

Expand Down Expand Up @@ -378,9 +378,9 @@ def public_autolink_library :
// HIDDEN FLAGS
let Flags = [FrontendOption, NoDriverOption, HelpHidden] in {

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

def checked_async_objc_bridging : Joined<["-"], "checked-async-objc-bridging=">,
HelpText<"Control whether checked continuations are used when bridging "
Expand Down Expand Up @@ -900,7 +900,7 @@ def disable_concrete_type_metadata_mangled_name_accessors : Flag<["-"], "disable
def disable_standard_substitutions_in_reflection_mangling : Flag<["-"], "disable-standard-substitutions-in-reflection-mangling">,
HelpText<"Disable referencing stdlib symbols via mangled names in reflection mangling">,
Flags<[FrontendOption, HelpHidden]>;

def playground : Flag<["-"], "playground">,
HelpText<"Apply the playground semantics and transformation">;

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

def sil_verify_all : Flag<["-"], "sil-verify-all">,
HelpText<"Verify SIL after each transform">;

def sil_verify_none : Flag<["-"], "sil-verify-none">,
HelpText<"Completely disable SIL verification">;

def sil_ownership_verify_all : Flag<["-"], "sil-ownership-verify-all">,
HelpText<"Verify ownership after each transform">;

def verify_all_substitution_maps : Flag<["-"], "verify-all-substitution-maps">,
HelpText<"Verify all SubstitutionMaps on construction">;

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

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

def target_sdk_version : Separate<["-"], "target-sdk-version">,
Expand Down
19 changes: 15 additions & 4 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,12 @@ def verify_incremental_dependencies :
Flag<["-"], "verify-incremental-dependencies">,
Flags<[FrontendOption, HelpHidden]>,
HelpText<"Enable the dependency verifier for each frontend job">;

def strict_implicit_module_context :
Flag<["-"], "strict-implicit-module-context">,
Flags<[FrontendOption, HelpHidden]>,
HelpText<"Enable the strict forwarding of compilation context to downstream implicit module dependencies">;

def no_strict_implicit_module_context :
Flag<["-"], "no-strict-implicit-module-context">,
Flags<[FrontendOption, HelpHidden]>,
Expand Down Expand Up @@ -315,7 +315,7 @@ def tools_directory : Separate<["-"], "tools-directory">,

def D : JoinedOrSeparate<["-"], "D">, Flags<[FrontendOption]>,
HelpText<"Marks a conditional compilation flag as true">;

def e : Separate<["-"], "e">, Flags<[NewDriverOnlyOption]>,
HelpText<"Executes a line of code provided on the command line">;

Expand Down Expand Up @@ -353,11 +353,22 @@ def import_objc_header : Separate<["-"], "import-objc-header">,
def import_bridging_header : Separate<["-"], "import-bridging-header">,
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
Alias<import_objc_header>;
def import_pch : Separate<["-"], "import-pch">,
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
HelpText<"Import bridging header PCH file">;

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

def scanner_output_dir: Separate<["-"], "scanner-output-dir">,
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
HelpText<"Directory to write generated files from swift dependency scanner">;

def experimental_bridging_header_chaining: Flag<["-"], "experimental-bridging-header-chaining">,
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
HelpText<"Automatically chaining all the bridging headers">;

// FIXME: Unhide this once it doesn't depend on an output file map.
def incremental : Flag<["-"], "incremental">,
Flags<[NoInteractiveOption, HelpHidden, DoesNotAffectIncrementalBuild]>,
Expand Down Expand Up @@ -2117,7 +2128,7 @@ def external_plugin_path : Separate<["-"], "external-plugin-path">, Group<plugin
Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>,
HelpText<"Add directory to the plugin search path with a plugin server executable">,
MetaVarName<"<path>#<plugin-server-path>">;

def cas_backend: Flag<["-"], "cas-backend">,
Flags<[FrontendOption, NoDriverOption]>,
HelpText<"Enable using CASBackend for object file output">;
Expand Down
2 changes: 2 additions & 0 deletions include/swift/Serialization/SerializationOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class SerializationOptions {

StringRef GroupInfoPath;
StringRef ImportedHeader;
StringRef ImportedPCHPath;
bool SerializeBridgingHeader = false;
StringRef ModuleLinkName;
StringRef ModuleInterface;
std::vector<std::string> ExtraClangOptions;
Expand Down
Loading

0 comments on commit 055cccd

Please sign in to comment.