Skip to content

[BridgingHeader] Auto bridging header chaining #78623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion include/swift-c/DependencyScan/DependencyScan.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/// SWIFTSCAN_VERSION_MINOR should increase when there are API additions.
/// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
#define SWIFTSCAN_VERSION_MAJOR 2
#define SWIFTSCAN_VERSION_MINOR 0
#define SWIFTSCAN_VERSION_MINOR 1

SWIFTSCAN_BEGIN_DECLS

Expand Down Expand Up @@ -222,6 +222,14 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t
swiftscan_swift_textual_detail_get_user_module_version(
swiftscan_module_details_t details);

SWIFTSCAN_PUBLIC swiftscan_string_ref_t
swiftscan_swift_textual_detail_get_chained_bridging_header_path(
swiftscan_module_details_t details);

SWIFTSCAN_PUBLIC swiftscan_string_ref_t
swiftscan_swift_textual_detail_get_chained_bridging_header_content(
swiftscan_module_details_t details);

//=== Swift Binary Module Details query APIs ------------------------------===//

SWIFTSCAN_PUBLIC swiftscan_string_ref_t
Expand Down
30 changes: 24 additions & 6 deletions include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@
#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"
#include "llvm/CAS/ObjectStore.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/PrefixMapper.h"
#include "llvm/Support/VirtualFileSystem.h"
Expand Down Expand Up @@ -338,6 +340,12 @@ class SwiftSourceModuleDependenciesStorage
/// The Swift frontend invocation arguments to build bridging header.
std::vector<std::string> bridgingHeaderBuildCommandLine;

/// The chained bridging header path if used.
std::string chainedBridgingHeaderPath;

/// The chained bridging header source buffer if used.
std::string chainedBridgingHeaderContent;

SwiftSourceModuleDependenciesStorage(
StringRef RootID, ArrayRef<StringRef> buildCommandLine,
ArrayRef<ScannerImportStatementInfo> moduleImports,
Expand All @@ -354,6 +362,7 @@ class SwiftSourceModuleDependenciesStorage
return new SwiftSourceModuleDependenciesStorage(*this);
}


static bool classof(const ModuleDependencyInfoStorageBase *base) {
return base->dependencyKind == ModuleDependencyKind::SwiftSource;
}
Expand All @@ -370,6 +379,11 @@ class SwiftSourceModuleDependenciesStorage
void addTestableImport(ImportPath::Module module) {
testableImports.insert(module.front().Item.str());
}

void setChainedBridgingHeaderBuffer(StringRef path, StringRef buffer) {
chainedBridgingHeaderPath = path.str();
chainedBridgingHeaderContent = buffer.str();
}
};

/// Describes the dependencies of a pre-built Swift module (with no
Expand Down Expand Up @@ -769,11 +783,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 @@ -961,11 +975,14 @@ 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);

/// Set the chained bridging header buffer.
void setChainedBridgingHeaderBuffer(StringRef path, StringRef buffer);

/// Collect a map from a secondary module name to a list of cross-import
/// overlays, when this current module serves as the primary module.
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
Expand Down Expand Up @@ -1025,8 +1042,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 @@ -1182,11 +1200,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 @@ -577,6 +577,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 @@ -684,7 +684,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 @@ -864,7 +864,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 @@ -908,7 +908,7 @@ namespace swift {

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

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

Expand Down Expand Up @@ -956,6 +956,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 @@ -1077,6 +1080,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
10 changes: 9 additions & 1 deletion include/swift/ClangImporter/ClangImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,14 +508,17 @@ 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, std::optional<StringRef> headerPath,
std::optional<llvm::MemoryBufferRef> sourceBuffer,
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &headerClangModuleDependencies,
Expand Down Expand Up @@ -677,6 +680,11 @@ class ClangImporter final : public ClangModuleLoader {
const clang::TypedefType *getTypeDefForCXXCFOptionsDefinition(
const clang::Decl *candidateDecl) override;

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

SourceLoc importSourceLocation(clang::SourceLocation loc) override;
};

Expand Down
7 changes: 7 additions & 0 deletions include/swift/DependencyScan/DependencyScanImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ typedef struct {

/// User module version
swiftscan_string_ref_t user_module_version;

/// Chained bridging header path.
swiftscan_string_ref_t chained_bridging_header_path;

/// Chained bridging header content.
swiftscan_string_ref_t chained_bridging_header_content;

} swiftscan_swift_textual_details_t;

/// Swift modules with only a binary module file.
Expand Down
22 changes: 18 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,9 @@ class ModuleDependencyScanner {
resolveAllClangModuleDependencies(ArrayRef<ModuleDependencyID> swiftModules,
ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &discoveredClangModules);
void
resolveHeaderDependencies(ArrayRef<ModuleDependencyID> swiftModules,
ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
void resolveHeaderDependencies(
ArrayRef<ModuleDependencyID> swiftModules, ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
void
resolveSwiftOverlayDependencies(ArrayRef<ModuleDependencyID> swiftModules,
ModuleDependenciesCache &cache,
Expand Down Expand Up @@ -151,6 +159,12 @@ 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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ using SwiftSourceModuleDetailsLayout =
IdentifierIDField, // CASFileSystemRootID
IdentifierIDField, // bridgingHeaderIncludeTree
FlagIDArrayIDField, // buildCommandLine
FlagIDArrayIDField // bridgingHeaderBuildCommandLine
FlagIDArrayIDField, // bridgingHeaderBuildCommandLine
IdentifierIDField, // chainedBridgingHeaderPath
IdentifierIDField // chainedBridgingHeaderContent
>;

using SwiftBinaryModuleDetailsLayout =
Expand Down
2 changes: 2 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,7 @@ createCompileJobCacheKeyForOutput(llvm::cas::ObjectStore &CAS,
llvm::Error printCompileJobCacheKey(llvm::cas::ObjectStore &CAS,
llvm::cas::ObjectRef Key,
llvm::raw_ostream &os);

} // namespace swift

#endif
9 changes: 9 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 @@ -374,6 +377,12 @@ 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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't think the scanner should be writing out any generated files. Rather, it should communicate any files that need generating to the client, i.e. SwiftDriver, and then have the client do the required IO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that for CAS purposes we do need to have the scanner have the information of where the chained bridging header will ultimately be serialized to, we could add an option for this specifically: -chained-bridging-header-output-path that the build system client can provide.


/// If the scanner output is written directly to the disk for debugging.
bool WriteScannerOutput = false;

/// Whether the dependency scanner invocation should resolve imports
/// to filesystem modules in parallel.
bool ParallelDependencyScan = true;
Expand Down
Loading