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 1 commit 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
92 changes: 83 additions & 9 deletions include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,69 @@ 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 @@ -718,9 +781,8 @@ class ModuleDependencyInfo {
ArrayRef<ModuleDependencyID> getSwiftOverlayDependencies() const {
return storage->swiftOverlayDependencies;
}

void
setCrossImportOverlayDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
void setCrossImportOverlayDependencies(
const ModuleDependencyIDCollectionView dependencyIDs) {
assert(isSwiftModule());
storage->crossImportOverlayModules.assign(dependencyIDs.begin(),
dependencyIDs.end());
Expand Down Expand Up @@ -1051,12 +1113,16 @@ 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>
Expand Down Expand Up @@ -1138,9 +1204,17 @@ 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) {
auto dependencyInfo = findKnownDependency(moduleID);
assert(dependencyInfo.getCrossImportOverlayDependencies().empty());
// Copy the existing info to a mutable one we can then replace it with,
// after setting its overlay dependencies.
auto updatedDependencyInfo = dependencyInfo;
updatedDependencyInfo.setCrossImportOverlayDependencies(dependencyIDs);
updateDependency(moduleID, updatedDependencyInfo);
}
/// Add to this module's set of visible Clang modules
void
addVisibleClangModules(ModuleDependencyID moduleID,
Expand Down
7 changes: 4 additions & 3 deletions include/swift/DependencyScan/ModuleDependencyScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ class ModuleDependencyScanner {
/// (bridging headers)
/// 4. Swift overlay modules of all of the transitively imported Clang modules
/// that have one
ModuleDependencyIDSetVector
resolveImportedModuleDependencies(const ModuleDependencyID &rootModuleID,
ModuleDependenciesCache &cache);
void
resolveImportedModuleDependencies(
const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &allModules);
void resolveSwiftModuleDependencies(
const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
ModuleDependencyIDSetVector &discoveredSwiftModules);
Expand Down
128 changes: 56 additions & 72 deletions lib/AST/ModuleDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,74 +850,79 @@ void ModuleDependenciesCache::removeDependency(ModuleDependencyID moduleID) {
map.erase(moduleID.ModuleName);
}

void
ModuleDependenciesCache::setImportedSwiftDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
void ModuleDependenciesCache::setImportedSwiftDependencies(
ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
auto dependencyInfo = findKnownDependency(moduleID);
assert(dependencyInfo.getImportedSwiftDependencies().empty());
#ifndef NDEBUG
for (const auto &depID : dependencyIDs)
assert(depID.Kind != ModuleDependencyKind::Clang);
#endif
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
// Copy the existing info to a mutable one we can then replace it with, after
// setting its overlay dependencies.
auto updatedDependencyInfo = dependencyInfo;
updatedDependencyInfo.setImportedSwiftDependencies(dependencyIDs);
updateDependency(moduleID, updatedDependencyInfo);
}
void
ModuleDependenciesCache::setImportedClangDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
void ModuleDependenciesCache::setImportedClangDependencies(
ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
auto dependencyInfo = findKnownDependency(moduleID);
assert(dependencyInfo.getImportedClangDependencies().empty());
#ifndef NDEBUG
for (const auto &depID : dependencyIDs)
assert(depID.Kind == ModuleDependencyKind::Clang);
#endif
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
// Copy the existing info to a mutable one we can then replace it with, after
// setting its overlay dependencies.
auto updatedDependencyInfo = dependencyInfo;
updatedDependencyInfo.setImportedClangDependencies(dependencyIDs);
updateDependency(moduleID, updatedDependencyInfo);
}
void
ModuleDependenciesCache::setHeaderClangDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
void ModuleDependenciesCache::setHeaderClangDependencies(
ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
auto dependencyInfo = findKnownDependency(moduleID);
#ifndef NDEBUG
for (const auto &depID : dependencyIDs)
assert(depID.Kind == ModuleDependencyKind::Clang);
#endif
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
// Copy the existing info to a mutable one we can then replace it with, after
// setting its overlay dependencies.
auto updatedDependencyInfo = dependencyInfo;
updatedDependencyInfo.setHeaderClangDependencies(dependencyIDs);
updateDependency(moduleID, updatedDependencyInfo);
}
void ModuleDependenciesCache::setSwiftOverlayDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
void ModuleDependenciesCache::setSwiftOverlayDependencies(
ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
auto dependencyInfo = findKnownDependency(moduleID);
assert(dependencyInfo.getSwiftOverlayDependencies().empty());
#ifndef NDEBUG
for (const auto &depID : dependencyIDs)
assert(depID.Kind != ModuleDependencyKind::Clang);
#endif
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
// Copy the existing info to a mutable one we can then replace it with, after
// setting its overlay dependencies.
auto updatedDependencyInfo = dependencyInfo;
updatedDependencyInfo.setSwiftOverlayDependencies(dependencyIDs);
updateDependency(moduleID, updatedDependencyInfo);
}
void
ModuleDependenciesCache::setCrossImportOverlayDependencies(ModuleDependencyID moduleID,
const ArrayRef<ModuleDependencyID> dependencyIDs) {
auto dependencyInfo = findKnownDependency(moduleID);
assert(dependencyInfo.getCrossImportOverlayDependencies().empty());
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
auto updatedDependencyInfo = dependencyInfo;
updatedDependencyInfo.setCrossImportOverlayDependencies(dependencyIDs);
updateDependency(moduleID, updatedDependencyInfo);

ModuleDependencyIDCollectionView ModuleDependenciesCache::getAllDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
return ModuleDependencyIDCollectionView(
moduleInfo.getImportedSwiftDependencies(),
moduleInfo.getImportedClangDependencies(),
moduleInfo.getHeaderClangDependencies(),
moduleInfo.getSwiftOverlayDependencies(),
moduleInfo.getCrossImportOverlayDependencies());
}

void
ModuleDependenciesCache::addVisibleClangModules(ModuleDependencyID moduleID,
const std::vector<std::string> &moduleNames) {
void ModuleDependenciesCache::addVisibleClangModules(
ModuleDependencyID moduleID, const std::vector<std::string> &moduleNames) {
if (moduleNames.empty())
return;
auto dependencyInfo = findKnownDependency(moduleID);
Expand All @@ -926,88 +931,67 @@ ModuleDependenciesCache::addVisibleClangModules(ModuleDependencyID moduleID,
updateDependency(moduleID, updatedDependencyInfo);
}

llvm::StringSet<> &ModuleDependenciesCache::getVisibleClangModules(ModuleDependencyID moduleID) const {
llvm::StringSet<> &ModuleDependenciesCache::getVisibleClangModules(
ModuleDependencyID moduleID) const {
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
return findKnownDependency(moduleID).getVisibleClangModules();
}

ModuleDependencyIDSetVector
ModuleDependenciesCache::getAllDependencies(const ModuleDependencyID &moduleID) const {
ModuleDependencyIDCollectionView
ModuleDependenciesCache::getDirectImportedDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
ModuleDependencyIDSetVector result;
if (moduleInfo.isSwiftModule()) {
auto swiftImportedDepsRef = moduleInfo.getImportedSwiftDependencies();
auto headerClangDepsRef = moduleInfo.getHeaderClangDependencies();
auto overlayDependenciesRef = moduleInfo.getSwiftOverlayDependencies();
result.insert(swiftImportedDepsRef.begin(),
swiftImportedDepsRef.end());
result.insert(headerClangDepsRef.begin(),
headerClangDepsRef.end());
result.insert(overlayDependenciesRef.begin(),
overlayDependenciesRef.end());
}

if (moduleInfo.isSwiftSourceModule()) {
auto crossImportOverlayDepsRef = moduleInfo.getCrossImportOverlayDependencies();
result.insert(crossImportOverlayDepsRef.begin(),
crossImportOverlayDepsRef.end());
}

auto clangImportedDepsRef = moduleInfo.getImportedClangDependencies();
result.insert(clangImportedDepsRef.begin(),
clangImportedDepsRef.end());

return result;
return ModuleDependencyIDCollectionView(
moduleInfo.getImportedSwiftDependencies(),
moduleInfo.getImportedClangDependencies());
}

ModuleDependencyIDSetVector
ModuleDependenciesCache::getClangDependencies(const ModuleDependencyID &moduleID) const {
ModuleDependencyIDCollectionView
ModuleDependenciesCache::getAllClangDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
ModuleDependencyIDSetVector result;
auto clangImportedDepsRef = moduleInfo.getImportedClangDependencies();
result.insert(clangImportedDepsRef.begin(),
clangImportedDepsRef.end());
if (moduleInfo.isSwiftSourceModule() || moduleInfo.isSwiftBinaryModule()) {
auto headerClangDepsRef = moduleInfo.getHeaderClangDependencies();
result.insert(headerClangDepsRef.begin(),
headerClangDepsRef.end());
}
return result;
return ModuleDependencyIDCollectionView(
moduleInfo.getImportedClangDependencies(),
moduleInfo.getHeaderClangDependencies());
}

llvm::ArrayRef<ModuleDependencyID>
ModuleDependenciesCache::getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const {
ModuleDependenciesCache::getImportedSwiftDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
assert(moduleInfo.isSwiftModule());
return moduleInfo.getImportedSwiftDependencies();
}

llvm::ArrayRef<ModuleDependencyID>
ModuleDependenciesCache::getImportedClangDependencies(const ModuleDependencyID &moduleID) const {
ModuleDependenciesCache::getImportedClangDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
return moduleInfo.getImportedClangDependencies();
}

llvm::ArrayRef<ModuleDependencyID>
ModuleDependenciesCache::getHeaderClangDependencies(const ModuleDependencyID &moduleID) const {
ModuleDependenciesCache::getHeaderClangDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
assert(moduleInfo.isSwiftModule());
return moduleInfo.getHeaderClangDependencies();
}

llvm::ArrayRef<ModuleDependencyID>
ModuleDependenciesCache::getSwiftOverlayDependencies(const ModuleDependencyID &moduleID) const {
ModuleDependenciesCache::getSwiftOverlayDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
assert(moduleInfo.isSwiftModule());
return moduleInfo.getSwiftOverlayDependencies();
}

llvm::ArrayRef<ModuleDependencyID>
ModuleDependenciesCache::getCrossImportOverlayDependencies(const ModuleDependencyID &moduleID) const {
ModuleDependenciesCache::getCrossImportOverlayDependencies(
const ModuleDependencyID &moduleID) const {
const auto &moduleInfo = findKnownDependency(moduleID);
assert(moduleInfo.isSwiftSourceModule());
return moduleInfo.getCrossImportOverlayDependencies();
}

Loading