Skip to content

[Dependency Scanning] Reduce the amount of copying of collections of module IDs #83306

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
199 changes: 130 additions & 69 deletions include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,70 @@ struct ModuleDependencyIDHash {
}
};

// An iterable view over multiple joined ArrayRefs
// FIXME: std::ranges::join_view
template <typename T>
class JoinedArrayRefView {
public:
class Iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = const T *;
using reference = const T &;
Iterator(const JoinedArrayRefView *parent, size_t memberIndex,
size_t elementIndex)
: parentView(parent), collectionIndex(memberIndex),
elementIndex(elementIndex) {
checkAdvance();
}
const T &operator*() const {
return (parentView->memberCollections[collectionIndex])[elementIndex];
}
const T *operator->() const {
return &(parentView->memberCollections[collectionIndex])[elementIndex];
}
Iterator &operator++() {
++elementIndex;
checkAdvance();
return *this;
}
bool operator==(const Iterator &other) const {
return collectionIndex == other.collectionIndex &&
elementIndex == other.elementIndex;
}
bool operator!=(const Iterator &other) const { return !(*this == other); }

private:
const JoinedArrayRefView *parentView;
size_t collectionIndex;
size_t elementIndex;

void checkAdvance() {
while (collectionIndex < parentView->memberCollections.size() &&
elementIndex >=
parentView->memberCollections[collectionIndex].size()) {
++collectionIndex;
elementIndex = 0;
}
}
};

Iterator begin() const { return Iterator(this, 0, 0); }
Iterator end() const { return Iterator(this, memberCollections.size(), 0); }

template <typename... Arrays>
JoinedArrayRefView(Arrays... arrs) {
memberCollections.reserve(sizeof...(arrs));
(memberCollections.push_back(arrs), ...);
}

private:
std::vector<ArrayRef<T>> memberCollections;
};
using ModuleDependencyIDCollectionView = JoinedArrayRefView<ModuleDependencyID>;

using ModuleDependencyIDSet =
std::unordered_set<ModuleDependencyID, ModuleDependencyIDHash>;
using ModuleDependencyIDSetVector =
Expand Down Expand Up @@ -140,9 +204,9 @@ struct ScannerImportStatementInfo {
: importIdentifier(importIdentifier), importLocations({location}),
isExported(isExported), accessLevel(accessLevel) {}

ScannerImportStatementInfo(std::string importIdentifier, bool isExported,
AccessLevel accessLevel,
SmallVector<ImportDiagnosticLocationInfo, 4> locations)
ScannerImportStatementInfo(
std::string importIdentifier, bool isExported, AccessLevel accessLevel,
SmallVector<ImportDiagnosticLocationInfo, 4> locations)
: importIdentifier(importIdentifier), importLocations(locations),
isExported(isExported), accessLevel(accessLevel) {}

Expand Down Expand Up @@ -225,10 +289,9 @@ class ModuleDependencyInfoStorageBase {

struct CommonSwiftTextualModuleDependencyDetails {
CommonSwiftTextualModuleDependencyDetails(
ArrayRef<StringRef> buildCommandLine,
StringRef CASFileSystemRootID)
: bridgingHeaderFile(std::nullopt),
bridgingSourceFiles(), bridgingModuleDependencies(),
ArrayRef<StringRef> buildCommandLine, StringRef CASFileSystemRootID)
: bridgingHeaderFile(std::nullopt), bridgingSourceFiles(),
bridgingModuleDependencies(),
buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()),
CASFileSystemRootID(CASFileSystemRootID) {}

Expand Down Expand Up @@ -344,7 +407,8 @@ class SwiftSourceModuleDependenciesStorage
ArrayRef<ScannerImportStatementInfo> optionalModuleImports,
ArrayRef<StringRef> bridgingHeaderBuildCommandLine)
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftSource,
moduleImports, optionalModuleImports, {}),
moduleImports, optionalModuleImports,
{}),
textualModuleDetails(buildCommandLine, RootID),
testableImports(llvm::StringSet<>()),
bridgingHeaderBuildCommandLine(bridgingHeaderBuildCommandLine.begin(),
Expand All @@ -354,7 +418,6 @@ class SwiftSourceModuleDependenciesStorage
return new SwiftSourceModuleDependenciesStorage(*this);
}


static bool classof(const ModuleDependencyInfoStorageBase *base) {
return base->dependencyKind == ModuleDependencyKind::SwiftSource;
}
Expand Down Expand Up @@ -401,9 +464,8 @@ class SwiftBinaryModuleDependencyStorage
compiledModulePath(compiledModulePath), moduleDocPath(moduleDocPath),
sourceInfoPath(sourceInfoPath), headerImport(headerImport),
definingModuleInterfacePath(definingModuleInterface),
serializedSearchPaths(serializedSearchPaths),
isFramework(isFramework), isStatic(isStatic),
userModuleVersion(userModuleVersion) {}
serializedSearchPaths(serializedSearchPaths), isFramework(isFramework),
isStatic(isStatic), userModuleVersion(userModuleVersion) {}

ModuleDependencyInfoStorageBase *clone() const override {
return new SwiftBinaryModuleDependencyStorage(*this);
Expand Down Expand Up @@ -498,8 +560,7 @@ class ClangModuleDependencyStorage : public ModuleDependencyInfoStorageBase {
StringRef CASFileSystemRootID,
StringRef clangIncludeTreeRoot,
StringRef moduleCacheKey, bool IsSystem)
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::Clang,
{}, {},
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::Clang, {}, {},
linkLibraries, moduleCacheKey),
pcmOutputPath(pcmOutputPath), mappedPCMPath(mappedPCMPath),
moduleMapFile(moduleMapFile), contextHash(contextHash),
Expand Down Expand Up @@ -579,31 +640,28 @@ class ModuleDependencyInfo {
std::make_unique<SwiftBinaryModuleDependencyStorage>(
compiledModulePath, moduleDocPath, sourceInfoPath, moduleImports,
optionalModuleImports, linkLibraries, serializedSearchPaths,
headerImport, definingModuleInterface,isFramework, isStatic,
headerImport, definingModuleInterface, isFramework, isStatic,
moduleCacheKey, userModuleVer));
}

/// Describe the main Swift module.
static ModuleDependencyInfo
forSwiftSourceModule(const std::string &CASFileSystemRootID,
ArrayRef<StringRef> buildCommands,
ArrayRef<ScannerImportStatementInfo> moduleImports,
ArrayRef<ScannerImportStatementInfo> optionalModuleImports,
ArrayRef<StringRef> bridgingHeaderBuildCommands) {
static ModuleDependencyInfo forSwiftSourceModule(
const std::string &CASFileSystemRootID, ArrayRef<StringRef> buildCommands,
ArrayRef<ScannerImportStatementInfo> moduleImports,
ArrayRef<ScannerImportStatementInfo> optionalModuleImports,
ArrayRef<StringRef> bridgingHeaderBuildCommands) {
return ModuleDependencyInfo(
std::make_unique<SwiftSourceModuleDependenciesStorage>(
CASFileSystemRootID, buildCommands, moduleImports,
optionalModuleImports, bridgingHeaderBuildCommands));
}

static ModuleDependencyInfo
forSwiftSourceModule() {
static ModuleDependencyInfo forSwiftSourceModule() {
return ModuleDependencyInfo(
std::make_unique<SwiftSourceModuleDependenciesStorage>(
StringRef(), ArrayRef<StringRef>(),
ArrayRef<ScannerImportStatementInfo>(),
ArrayRef<ScannerImportStatementInfo>(),
ArrayRef<StringRef>()));
StringRef(), ArrayRef<StringRef>(),
ArrayRef<ScannerImportStatementInfo>(),
ArrayRef<ScannerImportStatementInfo>(), ArrayRef<StringRef>()));
}

/// Describe the module dependencies for a Clang module that can be
Expand All @@ -630,16 +688,14 @@ class ModuleDependencyInfo {
return storage->optionalModuleImports;
}

std::string getModuleCacheKey() const {
return storage->moduleCacheKey;
}
std::string getModuleCacheKey() const { return storage->moduleCacheKey; }

void updateModuleCacheKey(const std::string &key) {
storage->moduleCacheKey = key;
}

void
setImportedSwiftDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
void setImportedSwiftDependencies(
const ArrayRef<ModuleDependencyID> dependencyIDs) {
assert(isSwiftModule());
storage->importedSwiftModules.assign(dependencyIDs.begin(),
dependencyIDs.end());
Expand All @@ -648,8 +704,8 @@ class ModuleDependencyInfo {
return storage->importedSwiftModules;
}

void
setImportedClangDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
void setImportedClangDependencies(
const ArrayRef<ModuleDependencyID> dependencyIDs) {
storage->importedClangModules.assign(dependencyIDs.begin(),
dependencyIDs.end());
}
Expand All @@ -664,15 +720,15 @@ class ModuleDependencyInfo {
case swift::ModuleDependencyKind::SwiftInterface: {
auto swiftInterfaceStorage =
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
swiftInterfaceStorage->textualModuleDetails.bridgingModuleDependencies.assign(dependencyIDs.begin(),
dependencyIDs.end());
swiftInterfaceStorage->textualModuleDetails.bridgingModuleDependencies
.assign(dependencyIDs.begin(), dependencyIDs.end());
break;
}
case swift::ModuleDependencyKind::SwiftSource: {
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
swiftSourceStorage->textualModuleDetails.bridgingModuleDependencies.assign(dependencyIDs.begin(),
dependencyIDs.end());
swiftSourceStorage->textualModuleDetails.bridgingModuleDependencies
.assign(dependencyIDs.begin(), dependencyIDs.end());
break;
}
case swift::ModuleDependencyKind::SwiftBinary: {
Expand All @@ -692,12 +748,14 @@ class ModuleDependencyInfo {
case swift::ModuleDependencyKind::SwiftInterface: {
auto swiftInterfaceStorage =
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
return swiftInterfaceStorage->textualModuleDetails.bridgingModuleDependencies;
return swiftInterfaceStorage->textualModuleDetails
.bridgingModuleDependencies;
}
case swift::ModuleDependencyKind::SwiftSource: {
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
return swiftSourceStorage->textualModuleDetails.bridgingModuleDependencies;
return swiftSourceStorage->textualModuleDetails
.bridgingModuleDependencies;
}
case swift::ModuleDependencyKind::SwiftBinary: {
auto swiftBinaryStorage =
Expand All @@ -709,8 +767,8 @@ class ModuleDependencyInfo {
}
}

void
setSwiftOverlayDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
void setSwiftOverlayDependencies(
const ArrayRef<ModuleDependencyID> dependencyIDs) {
assert(isSwiftModule());
storage->swiftOverlayDependencies.assign(dependencyIDs.begin(),
dependencyIDs.end());
Expand All @@ -719,8 +777,8 @@ class ModuleDependencyInfo {
return storage->swiftOverlayDependencies;
}

void
setCrossImportOverlayDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
void setCrossImportOverlayDependencies(
const ModuleDependencyIDCollectionView dependencyIDs) {
assert(isSwiftModule());
storage->crossImportOverlayModules.assign(dependencyIDs.begin(),
dependencyIDs.end());
Expand All @@ -733,8 +791,7 @@ class ModuleDependencyInfo {
return storage->linkLibraries;
}

void
setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
void setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
}

Expand Down Expand Up @@ -831,8 +888,7 @@ class ModuleDependencyInfo {

void
addVisibleClangModules(const std::vector<std::string> &moduleNames) const {
storage->visibleClangModules.insert(moduleNames.begin(),
moduleNames.end());
storage->visibleClangModules.insert(moduleNames.begin(), moduleNames.end());
}

/// Whether explicit input paths of all the module dependencies
Expand Down Expand Up @@ -1004,7 +1060,8 @@ class ModuleDependenciesCache {
/// Discovered dependencies
ModuleDependenciesKindMap ModuleDependenciesMap;
/// Set containing all of the Clang modules that have already been seen.
llvm::DenseSet<clang::tooling::dependencies::ModuleID> alreadySeenClangModules;
llvm::DenseSet<clang::tooling::dependencies::ModuleID>
alreadySeenClangModules;
/// Name of the module under scan
std::string mainScanModuleName;
/// The context hash of the current scanning invocation
Expand All @@ -1030,7 +1087,8 @@ class ModuleDependenciesCache {
/// Retrieve the dependencies map that corresponds to the given dependency
/// kind.
ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind);
const ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind) const;
const ModuleNameToDependencyMap &
getDependenciesMap(ModuleDependencyKind kind) const;

/// Whether we have cached dependency information for the given module.
bool hasDependency(const ModuleDependencyID &moduleID) const;
Expand All @@ -1051,20 +1109,25 @@ class ModuleDependenciesCache {
}

/// Query all dependencies
ModuleDependencyIDSetVector
ModuleDependencyIDCollectionView
getAllDependencies(const ModuleDependencyID &moduleID) const;

/// Query all directly-imported dependencies
ModuleDependencyIDCollectionView
getDirectImportedDependencies(const ModuleDependencyID &moduleID) const;

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

/// Query all directly-imported Swift dependencies
llvm::ArrayRef<ModuleDependencyID>
getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const;
/// Query all directly-imported Clang dependencies
llvm::ArrayRef<ModuleDependencyID>
getImportedClangDependencies(const ModuleDependencyID &moduleID) const;
/// Query all Clang module dependencies of this module's imported (bridging) header
/// Query all Clang module dependencies of this module's imported (bridging)
/// header
llvm::ArrayRef<ModuleDependencyID>
getHeaderClangDependencies(const ModuleDependencyID &moduleID) const;
/// Query Swift overlay dependencies
Expand All @@ -1074,8 +1137,7 @@ class ModuleDependenciesCache {
llvm::ArrayRef<ModuleDependencyID>
getCrossImportOverlayDependencies(const ModuleDependencyID &moduleID) const;
/// Query all visible Clang modules for a given Swift dependency
llvm::StringSet<>&
getVisibleClangModules(ModuleDependencyID moduleID) const;
llvm::StringSet<> &getVisibleClangModules(ModuleDependencyID moduleID) const;

/// Look for module dependencies for a module with the given ID
///
Expand Down Expand Up @@ -1113,20 +1175,20 @@ class ModuleDependenciesCache {
/// Update stored dependencies for the given module.
void updateDependency(ModuleDependencyID moduleID,
ModuleDependencyInfo dependencyInfo);

/// Remove a given dependency info from the cache.
void removeDependency(ModuleDependencyID moduleID);

/// Resolve this module's set of directly-imported Swift module
/// dependencies
void
setImportedSwiftDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs);
void setImportedSwiftDependencies(
ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs);
/// Resolve this module's set of directly-imported Clang module
/// dependencies
void
setImportedClangDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs);
void setImportedClangDependencies(
ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs);
/// Resolve this module's set of Swift module dependencies
/// that are Swift overlays of Clang module dependencies.
void
Expand All @@ -1138,13 +1200,12 @@ class ModuleDependenciesCache {
setHeaderClangDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs);
/// Resolve this module's cross-import overlay dependencies
void
setCrossImportOverlayDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs);
void setCrossImportOverlayDependencies(
ModuleDependencyID moduleID,
const ModuleDependencyIDCollectionView dependencyIDs);
/// Add to this module's set of visible Clang modules
void
addVisibleClangModules(ModuleDependencyID moduleID,
const std::vector<std::string> &moduleNames);
void addVisibleClangModules(ModuleDependencyID moduleID,
const std::vector<std::string> &moduleNames);

StringRef getMainModuleName() const { return mainScanModuleName; }

Expand Down
Loading