Skip to content

Commit 9e7816d

Browse files
committed
[Dependency Scanning] Reduce the amount of copying of collections of module IDs
Previously, frequently-used methods like 'getAllDependencies' and 'getAllClangDependencies' had to aggregate (copy) multiple collections stored in a 'ModuleDependencyInfo' into a new result array to present to the client. These methods have been refactored to instead return an iterable joined view of the constituent collections.
1 parent b4f2821 commit 9e7816d

File tree

6 files changed

+190
-133
lines changed

6 files changed

+190
-133
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,69 @@ struct ModuleDependencyIDHash {
9494
}
9595
};
9696

97+
// An iterable view over multiple joined ArrayRefs
98+
// FIXME: std::ranges::join_view
99+
template <typename T>
100+
class JoinedArrayRefView {
101+
public:
102+
class Iterator {
103+
public:
104+
using iterator_category = std::forward_iterator_tag;
105+
using value_type = T;
106+
using difference_type = std::ptrdiff_t;
107+
using pointer = const T*;
108+
using reference = const T&;
109+
Iterator(const JoinedArrayRefView *parent, size_t memberIndex,
110+
size_t elementIndex)
111+
: parentView(parent), collectionIndex(memberIndex),
112+
elementIndex(elementIndex) {
113+
checkAdvance();
114+
}
115+
const T &operator*() const {
116+
return (parentView->memberCollections[collectionIndex])[elementIndex];
117+
}
118+
const T *operator->() const {
119+
return &(parentView->memberCollections[collectionIndex])[elementIndex];
120+
}
121+
Iterator &operator++() {
122+
++elementIndex;
123+
checkAdvance();
124+
return *this;
125+
}
126+
bool operator==(const Iterator &other) const {
127+
return collectionIndex == other.collectionIndex &&
128+
elementIndex == other.elementIndex;
129+
}
130+
bool operator!=(const Iterator &other) const { return !(*this == other); }
131+
132+
private:
133+
const JoinedArrayRefView *parentView;
134+
size_t collectionIndex;
135+
size_t elementIndex;
136+
137+
void checkAdvance() {
138+
while (collectionIndex < parentView->memberCollections.size() &&
139+
elementIndex >= parentView->memberCollections[collectionIndex].size()) {
140+
++collectionIndex;
141+
elementIndex = 0;
142+
}
143+
}
144+
};
145+
146+
Iterator begin() const { return Iterator(this, 0, 0); }
147+
Iterator end() const { return Iterator(this, memberCollections.size(), 0); }
148+
149+
template <typename... Arrays>
150+
JoinedArrayRefView(Arrays ...arrs) {
151+
memberCollections.reserve(sizeof...(arrs));
152+
(memberCollections.push_back(arrs), ...);
153+
}
154+
155+
private:
156+
std::vector<ArrayRef<T>> memberCollections;
157+
};
158+
using ModuleDependencyIDCollectionView = JoinedArrayRefView<ModuleDependencyID>;
159+
97160
using ModuleDependencyIDSet =
98161
std::unordered_set<ModuleDependencyID, ModuleDependencyIDHash>;
99162
using ModuleDependencyIDSetVector =
@@ -718,9 +781,8 @@ class ModuleDependencyInfo {
718781
ArrayRef<ModuleDependencyID> getSwiftOverlayDependencies() const {
719782
return storage->swiftOverlayDependencies;
720783
}
721-
722-
void
723-
setCrossImportOverlayDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
784+
void setCrossImportOverlayDependencies(
785+
const ModuleDependencyIDCollectionView dependencyIDs) {
724786
assert(isSwiftModule());
725787
storage->crossImportOverlayModules.assign(dependencyIDs.begin(),
726788
dependencyIDs.end());
@@ -1051,12 +1113,16 @@ class ModuleDependenciesCache {
10511113
}
10521114

10531115
/// Query all dependencies
1054-
ModuleDependencyIDSetVector
1116+
ModuleDependencyIDCollectionView
10551117
getAllDependencies(const ModuleDependencyID &moduleID) const;
10561118

1119+
/// Query all directly-imported dependencies
1120+
ModuleDependencyIDCollectionView
1121+
getDirectImportedDependencies(const ModuleDependencyID &moduleID) const;
1122+
10571123
/// Query all Clang module dependencies.
1058-
ModuleDependencyIDSetVector
1059-
getClangDependencies(const ModuleDependencyID &moduleID) const;
1124+
ModuleDependencyIDCollectionView
1125+
getAllClangDependencies(const ModuleDependencyID &moduleID) const;
10601126

10611127
/// Query all directly-imported Swift dependencies
10621128
llvm::ArrayRef<ModuleDependencyID>
@@ -1138,9 +1204,17 @@ class ModuleDependenciesCache {
11381204
setHeaderClangDependencies(ModuleDependencyID moduleID,
11391205
const ArrayRef<ModuleDependencyID> dependencyIDs);
11401206
/// Resolve this module's cross-import overlay dependencies
1141-
void
1142-
setCrossImportOverlayDependencies(ModuleDependencyID moduleID,
1143-
const ArrayRef<ModuleDependencyID> dependencyIDs);
1207+
void setCrossImportOverlayDependencies(
1208+
ModuleDependencyID moduleID,
1209+
const ModuleDependencyIDCollectionView dependencyIDs) {
1210+
auto dependencyInfo = findKnownDependency(moduleID);
1211+
assert(dependencyInfo.getCrossImportOverlayDependencies().empty());
1212+
// Copy the existing info to a mutable one we can then replace it with,
1213+
// after setting its overlay dependencies.
1214+
auto updatedDependencyInfo = dependencyInfo;
1215+
updatedDependencyInfo.setCrossImportOverlayDependencies(dependencyIDs);
1216+
updateDependency(moduleID, updatedDependencyInfo);
1217+
}
11441218
/// Add to this module's set of visible Clang modules
11451219
void
11461220
addVisibleClangModules(ModuleDependencyID moduleID,

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,10 @@ class ModuleDependencyScanner {
248248
/// (bridging headers)
249249
/// 4. Swift overlay modules of all of the transitively imported Clang modules
250250
/// that have one
251-
ModuleDependencyIDSetVector
252-
resolveImportedModuleDependencies(const ModuleDependencyID &rootModuleID,
253-
ModuleDependenciesCache &cache);
251+
void
252+
resolveImportedModuleDependencies(
253+
const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
254+
ModuleDependencyIDSetVector &allModules);
254255
void resolveSwiftModuleDependencies(
255256
const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
256257
ModuleDependencyIDSetVector &discoveredSwiftModules);

lib/AST/ModuleDependencies.cpp

Lines changed: 56 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -850,74 +850,79 @@ void ModuleDependenciesCache::removeDependency(ModuleDependencyID moduleID) {
850850
map.erase(moduleID.ModuleName);
851851
}
852852

853-
void
854-
ModuleDependenciesCache::setImportedSwiftDependencies(ModuleDependencyID moduleID,
855-
const ArrayRef<ModuleDependencyID> dependencyIDs) {
853+
void ModuleDependenciesCache::setImportedSwiftDependencies(
854+
ModuleDependencyID moduleID,
855+
const ArrayRef<ModuleDependencyID> dependencyIDs) {
856856
auto dependencyInfo = findKnownDependency(moduleID);
857857
assert(dependencyInfo.getImportedSwiftDependencies().empty());
858858
#ifndef NDEBUG
859859
for (const auto &depID : dependencyIDs)
860860
assert(depID.Kind != ModuleDependencyKind::Clang);
861861
#endif
862-
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
862+
// Copy the existing info to a mutable one we can then replace it with, after
863+
// setting its overlay dependencies.
863864
auto updatedDependencyInfo = dependencyInfo;
864865
updatedDependencyInfo.setImportedSwiftDependencies(dependencyIDs);
865866
updateDependency(moduleID, updatedDependencyInfo);
866867
}
867-
void
868-
ModuleDependenciesCache::setImportedClangDependencies(ModuleDependencyID moduleID,
869-
const ArrayRef<ModuleDependencyID> dependencyIDs) {
868+
void ModuleDependenciesCache::setImportedClangDependencies(
869+
ModuleDependencyID moduleID,
870+
const ArrayRef<ModuleDependencyID> dependencyIDs) {
870871
auto dependencyInfo = findKnownDependency(moduleID);
871872
assert(dependencyInfo.getImportedClangDependencies().empty());
872873
#ifndef NDEBUG
873874
for (const auto &depID : dependencyIDs)
874875
assert(depID.Kind == ModuleDependencyKind::Clang);
875876
#endif
876-
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
877+
// Copy the existing info to a mutable one we can then replace it with, after
878+
// setting its overlay dependencies.
877879
auto updatedDependencyInfo = dependencyInfo;
878880
updatedDependencyInfo.setImportedClangDependencies(dependencyIDs);
879881
updateDependency(moduleID, updatedDependencyInfo);
880882
}
881-
void
882-
ModuleDependenciesCache::setHeaderClangDependencies(ModuleDependencyID moduleID,
883-
const ArrayRef<ModuleDependencyID> dependencyIDs) {
883+
void ModuleDependenciesCache::setHeaderClangDependencies(
884+
ModuleDependencyID moduleID,
885+
const ArrayRef<ModuleDependencyID> dependencyIDs) {
884886
auto dependencyInfo = findKnownDependency(moduleID);
885887
#ifndef NDEBUG
886888
for (const auto &depID : dependencyIDs)
887889
assert(depID.Kind == ModuleDependencyKind::Clang);
888890
#endif
889-
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
891+
// Copy the existing info to a mutable one we can then replace it with, after
892+
// setting its overlay dependencies.
890893
auto updatedDependencyInfo = dependencyInfo;
891894
updatedDependencyInfo.setHeaderClangDependencies(dependencyIDs);
892895
updateDependency(moduleID, updatedDependencyInfo);
893896
}
894-
void ModuleDependenciesCache::setSwiftOverlayDependencies(ModuleDependencyID moduleID,
895-
const ArrayRef<ModuleDependencyID> dependencyIDs) {
897+
void ModuleDependenciesCache::setSwiftOverlayDependencies(
898+
ModuleDependencyID moduleID,
899+
const ArrayRef<ModuleDependencyID> dependencyIDs) {
896900
auto dependencyInfo = findKnownDependency(moduleID);
897901
assert(dependencyInfo.getSwiftOverlayDependencies().empty());
898902
#ifndef NDEBUG
899903
for (const auto &depID : dependencyIDs)
900904
assert(depID.Kind != ModuleDependencyKind::Clang);
901905
#endif
902-
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
906+
// Copy the existing info to a mutable one we can then replace it with, after
907+
// setting its overlay dependencies.
903908
auto updatedDependencyInfo = dependencyInfo;
904909
updatedDependencyInfo.setSwiftOverlayDependencies(dependencyIDs);
905910
updateDependency(moduleID, updatedDependencyInfo);
906911
}
907-
void
908-
ModuleDependenciesCache::setCrossImportOverlayDependencies(ModuleDependencyID moduleID,
909-
const ArrayRef<ModuleDependencyID> dependencyIDs) {
910-
auto dependencyInfo = findKnownDependency(moduleID);
911-
assert(dependencyInfo.getCrossImportOverlayDependencies().empty());
912-
// Copy the existing info to a mutable one we can then replace it with, after setting its overlay dependencies.
913-
auto updatedDependencyInfo = dependencyInfo;
914-
updatedDependencyInfo.setCrossImportOverlayDependencies(dependencyIDs);
915-
updateDependency(moduleID, updatedDependencyInfo);
912+
913+
ModuleDependencyIDCollectionView ModuleDependenciesCache::getAllDependencies(
914+
const ModuleDependencyID &moduleID) const {
915+
const auto &moduleInfo = findKnownDependency(moduleID);
916+
return ModuleDependencyIDCollectionView(
917+
moduleInfo.getImportedSwiftDependencies(),
918+
moduleInfo.getImportedClangDependencies(),
919+
moduleInfo.getHeaderClangDependencies(),
920+
moduleInfo.getSwiftOverlayDependencies(),
921+
moduleInfo.getCrossImportOverlayDependencies());
916922
}
917923

918-
void
919-
ModuleDependenciesCache::addVisibleClangModules(ModuleDependencyID moduleID,
920-
const std::vector<std::string> &moduleNames) {
924+
void ModuleDependenciesCache::addVisibleClangModules(
925+
ModuleDependencyID moduleID, const std::vector<std::string> &moduleNames) {
921926
if (moduleNames.empty())
922927
return;
923928
auto dependencyInfo = findKnownDependency(moduleID);
@@ -926,88 +931,67 @@ ModuleDependenciesCache::addVisibleClangModules(ModuleDependencyID moduleID,
926931
updateDependency(moduleID, updatedDependencyInfo);
927932
}
928933

929-
llvm::StringSet<> &ModuleDependenciesCache::getVisibleClangModules(ModuleDependencyID moduleID) const {
934+
llvm::StringSet<> &ModuleDependenciesCache::getVisibleClangModules(
935+
ModuleDependencyID moduleID) const {
930936
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
931937
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
932938
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
933939
return findKnownDependency(moduleID).getVisibleClangModules();
934940
}
935941

936-
ModuleDependencyIDSetVector
937-
ModuleDependenciesCache::getAllDependencies(const ModuleDependencyID &moduleID) const {
942+
ModuleDependencyIDCollectionView
943+
ModuleDependenciesCache::getDirectImportedDependencies(
944+
const ModuleDependencyID &moduleID) const {
938945
const auto &moduleInfo = findKnownDependency(moduleID);
939-
ModuleDependencyIDSetVector result;
940-
if (moduleInfo.isSwiftModule()) {
941-
auto swiftImportedDepsRef = moduleInfo.getImportedSwiftDependencies();
942-
auto headerClangDepsRef = moduleInfo.getHeaderClangDependencies();
943-
auto overlayDependenciesRef = moduleInfo.getSwiftOverlayDependencies();
944-
result.insert(swiftImportedDepsRef.begin(),
945-
swiftImportedDepsRef.end());
946-
result.insert(headerClangDepsRef.begin(),
947-
headerClangDepsRef.end());
948-
result.insert(overlayDependenciesRef.begin(),
949-
overlayDependenciesRef.end());
950-
}
951-
952-
if (moduleInfo.isSwiftSourceModule()) {
953-
auto crossImportOverlayDepsRef = moduleInfo.getCrossImportOverlayDependencies();
954-
result.insert(crossImportOverlayDepsRef.begin(),
955-
crossImportOverlayDepsRef.end());
956-
}
957-
958-
auto clangImportedDepsRef = moduleInfo.getImportedClangDependencies();
959-
result.insert(clangImportedDepsRef.begin(),
960-
clangImportedDepsRef.end());
961-
962-
return result;
946+
return ModuleDependencyIDCollectionView(
947+
moduleInfo.getImportedSwiftDependencies(),
948+
moduleInfo.getImportedClangDependencies());
963949
}
964950

965-
ModuleDependencyIDSetVector
966-
ModuleDependenciesCache::getClangDependencies(const ModuleDependencyID &moduleID) const {
951+
ModuleDependencyIDCollectionView
952+
ModuleDependenciesCache::getAllClangDependencies(
953+
const ModuleDependencyID &moduleID) const {
967954
const auto &moduleInfo = findKnownDependency(moduleID);
968-
ModuleDependencyIDSetVector result;
969-
auto clangImportedDepsRef = moduleInfo.getImportedClangDependencies();
970-
result.insert(clangImportedDepsRef.begin(),
971-
clangImportedDepsRef.end());
972-
if (moduleInfo.isSwiftSourceModule() || moduleInfo.isSwiftBinaryModule()) {
973-
auto headerClangDepsRef = moduleInfo.getHeaderClangDependencies();
974-
result.insert(headerClangDepsRef.begin(),
975-
headerClangDepsRef.end());
976-
}
977-
return result;
955+
return ModuleDependencyIDCollectionView(
956+
moduleInfo.getImportedClangDependencies(),
957+
moduleInfo.getHeaderClangDependencies());
978958
}
979959

980960
llvm::ArrayRef<ModuleDependencyID>
981-
ModuleDependenciesCache::getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const {
961+
ModuleDependenciesCache::getImportedSwiftDependencies(
962+
const ModuleDependencyID &moduleID) const {
982963
const auto &moduleInfo = findKnownDependency(moduleID);
983964
assert(moduleInfo.isSwiftModule());
984965
return moduleInfo.getImportedSwiftDependencies();
985966
}
986967

987968
llvm::ArrayRef<ModuleDependencyID>
988-
ModuleDependenciesCache::getImportedClangDependencies(const ModuleDependencyID &moduleID) const {
969+
ModuleDependenciesCache::getImportedClangDependencies(
970+
const ModuleDependencyID &moduleID) const {
989971
const auto &moduleInfo = findKnownDependency(moduleID);
990972
return moduleInfo.getImportedClangDependencies();
991973
}
992974

993975
llvm::ArrayRef<ModuleDependencyID>
994-
ModuleDependenciesCache::getHeaderClangDependencies(const ModuleDependencyID &moduleID) const {
976+
ModuleDependenciesCache::getHeaderClangDependencies(
977+
const ModuleDependencyID &moduleID) const {
995978
const auto &moduleInfo = findKnownDependency(moduleID);
996979
assert(moduleInfo.isSwiftModule());
997980
return moduleInfo.getHeaderClangDependencies();
998981
}
999982

1000983
llvm::ArrayRef<ModuleDependencyID>
1001-
ModuleDependenciesCache::getSwiftOverlayDependencies(const ModuleDependencyID &moduleID) const {
984+
ModuleDependenciesCache::getSwiftOverlayDependencies(
985+
const ModuleDependencyID &moduleID) const {
1002986
const auto &moduleInfo = findKnownDependency(moduleID);
1003987
assert(moduleInfo.isSwiftModule());
1004988
return moduleInfo.getSwiftOverlayDependencies();
1005989
}
1006990

1007991
llvm::ArrayRef<ModuleDependencyID>
1008-
ModuleDependenciesCache::getCrossImportOverlayDependencies(const ModuleDependencyID &moduleID) const {
992+
ModuleDependenciesCache::getCrossImportOverlayDependencies(
993+
const ModuleDependencyID &moduleID) const {
1009994
const auto &moduleInfo = findKnownDependency(moduleID);
1010995
assert(moduleInfo.isSwiftSourceModule());
1011996
return moduleInfo.getCrossImportOverlayDependencies();
1012997
}
1013-

0 commit comments

Comments
 (0)