[llvm] [llvm][transforms] Add a new algorithm to SplitModule (PR #95941)
Ilia Sergachev via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 2 12:36:47 PDT 2024
================
@@ -268,6 +268,38 @@ void llvm::SplitModule(
ClusterIDMapType ClusterIDMap;
findPartitions(M, ClusterIDMap, N);
+ // Find empty modules and functions not mapped to modules in ClusterIDMap.
+ // Map these functions to the empty modules so that they skip being
+ // distributed by isInPartition() based on function name hashes below.
+ // This provides better uniformity of distribution of functions to modules
+ // in some cases - for example when the number of functions equals to N.
+ if (TryToAvoidEmptyModules) {
+ DenseSet<unsigned> NonEmptyModules;
+ SmallVector<const GlobalValue *> UnmappedFunctions;
+ for (const auto &F : M.functions()) {
+ if (F.isDeclaration() ||
+ F.getLinkage() != GlobalValue::LinkageTypes::ExternalLinkage)
+ continue;
+ auto It = ClusterIDMap.find(&F);
+ if (It == ClusterIDMap.end())
+ UnmappedFunctions.push_back(&F);
+ else
+ NonEmptyModules.insert(It->second);
+ }
+ SmallVector<unsigned> EmptyModules;
+ for (unsigned I = 0; I < N; ++I) {
+ if (!NonEmptyModules.contains(I))
+ EmptyModules.push_back(I);
+ }
+ auto NextEmptyModuleIt = EmptyModules.begin();
+ for (const auto F : UnmappedFunctions) {
+ if (NextEmptyModuleIt == EmptyModules.end())
+ break;
+ ClusterIDMap.insert({F, *NextEmptyModuleIt});
+ ++NextEmptyModuleIt;
+ }
----------------
sergachev wrote:
> I don't quite get this loop, seems like you won't distribute all the unmapped functions, but only at most a number equal to the empty modules? All the others will be distributed by isInPartition() if I read this loop correctly.
Correct. Our main use case for this is to request the number of modules equal to the number of functions - then (provided that the functions are independent) the algorithm generates exactly 1 function per module. The behavior corresponds to the name of the flag - TryToAvoidEmptyModules.
> Why don't you just circle back to EmptyModules.begin() instead of breaking out of the loop?
Can do that too - this would become a different algorithm, completely overriding the hash-based distribution. For our goal (1 function per module) this would work equally. Do you think we should change it this way?
> Also should we skip the loop over UnmappedFunctions if EmptyModules.empty() ?
Indeed. Fixed.
https://github.com/llvm/llvm-project/pull/95941
More information about the llvm-commits
mailing list