1//===- SplitModule.cpp - Split a module into partitions -------------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file defines the function llvm::SplitModule, which splits a module 10// into multiple linkable partitions. It can be used to implement parallel code 11// generation for link-time optimization. 13//===----------------------------------------------------------------------===// 49#define DEBUG_TYPE "split-module" 57bool compareClusters(
const std::pair<unsigned, unsigned> &
A,
58const std::pair<unsigned, unsigned> &
B) {
59if (
A.second ||
B.second)
60returnA.second >
B.second;
61returnA.first >
B.first;
64usingBalancingQueueType =
65 std::priority_queue<std::pair<unsigned, unsigned>,
66 std::vector<std::pair<unsigned, unsigned>>,
67decltype(compareClusters) *>;
69}
// end anonymous namespace 73assert((!isa<Constant>(U) || isa<GlobalValue>(U)) &&
"Bad user");
77 GVtoClusterMap.unionSets(GV,
F);
78 }
elseif (
constGlobalValue *GVU = dyn_cast<GlobalValue>(U)) {
79 GVtoClusterMap.unionSets(GV, GVU);
85// Adds all GlobalValue users of V to the same cluster as GV. 88for (
constauto *U : V->users()) {
91while (!Worklist.
empty()) {
93// For each constant that is not a GV (a pure const) recurse. 94if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
105if (
constauto *GI = dyn_cast_or_null<GlobalIFunc>(GO))
106 GO = GI->getResolverFunction();
110// Find partitions for module in the way that no locals need to be 112// Try to balance pack those partitions into N files since this roughly equals 113// thread balancing for the backend codegen step. 116// At this point module should have the proper mix of globals and locals. 117// As we attempt to partition this module, we must not change any 121 ClusterMapType GVtoClusterMap;
122 ComdatMembersType ComdatMembers;
124auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](
GlobalValue &GV) {
125if (GV.isDeclaration())
129 GV.setName(
"__llvmsplit_unnamed");
131// Comdat groups must not be partitioned. For comdat groups that contain 132// locals, record all their members here so we can keep them together. 133// Comdat groups that only contain external globals are already handled by 134// the MD5-based partitioning. 135if (
constComdat *
C = GV.getComdat()) {
136auto &Member = ComdatMembers[
C];
138 GVtoClusterMap.unionSets(Member, &GV);
143// Aliases should not be separated from their aliasees and ifuncs should 144// not be separated from their resolvers regardless of linkage. 147 GVtoClusterMap.unionSets(&GV, Root);
149if (
constFunction *
F = dyn_cast<Function>(&GV)) {
158if (GV.hasLocalLinkage())
166// Assigned all GVs to merged clusters while balancing number of objects in 168 BalancingQueueType BalancingQueue(compareClusters);
169// Pre-populate priority queue with N slot blanks. 170for (
unsigned i = 0; i <
N; ++i)
171 BalancingQueue.push(std::make_pair(i, 0));
173usingSortType = std::pair<unsigned, ClusterMapType::iterator>;
178// To guarantee determinism, we have to sort SCC according to size. 179// When size is the same, use leader's name. 180for (ClusterMapType::iterator
I = GVtoClusterMap.begin(),
181 E = GVtoClusterMap.end();
185 std::make_pair(std::distance(GVtoClusterMap.member_begin(
I),
186 GVtoClusterMap.member_end()),
189llvm::sort(Sets, [](
const SortType &a,
const SortType &b) {
190if (a.first == b.first)
191return a.second->getData()->getName() > b.second->getData()->getName();
193return a.first > b.first;
196for (
auto &
I : Sets) {
197unsigned CurrentClusterID = BalancingQueue.top().first;
198unsigned CurrentClusterSize = BalancingQueue.top().second;
199 BalancingQueue.pop();
201LLVM_DEBUG(
dbgs() <<
"Root[" << CurrentClusterID <<
"] cluster_size(" 202 <<
I.first <<
") ----> " <<
I.second->getData()->getName()
205for (ClusterMapType::member_iterator
MI =
206 GVtoClusterMap.findLeader(
I.second);
207MI != GVtoClusterMap.member_end(); ++
MI) {
208if (!Visited.
insert(*MI).second)
211 << ((*MI)->hasLocalLinkage() ?
" l " :
" e ") <<
"\n");
213 ClusterIDMap[*
MI] = CurrentClusterID;
214 CurrentClusterSize++;
216// Add this set size to the number of entries in this cluster. 217 BalancingQueue.push(std::make_pair(CurrentClusterID, CurrentClusterSize));
227// Unnamed entities must be named consistently between modules. setName will 228// give a distinct name to each such entity. 230 GV->
setName(
"__llvmsplit_unnamed");
233// Returns whether GV should be in partition (0-based) I of N. 244// Partition by MD5 hash. We only need a few bits for evenness as the number 245// of partitions will generally be in the 1-2 figure range; the low 16 bits 251return (R[0] | (R[1] << 8)) %
N ==
I;
256function_ref<
void(std::unique_ptr<Module> MPart)> ModuleCallback,
257bool PreserveLocals,
bool RoundRobin) {
258if (!PreserveLocals) {
269// This performs splitting without a need for externalization, which might not 270// always be possible. 271 ClusterIDMapType ClusterIDMap;
274// Find functions not mapped to modules in ClusterIDMap and count functions 275// per module. Map unmapped functions using round-robin so that they skip 276// being distributed by isInPartition() based on function name hashes below. 277// This provides better uniformity of distribution of functions to modules 278// in some cases - for example when the number of functions equals to N. 282for (
constauto &
F : M.functions()) {
283if (
F.isDeclaration() ||
284F.getLinkage() != GlobalValue::LinkageTypes::ExternalLinkage)
286auto It = ClusterIDMap.find(&
F);
287if (It == ClusterIDMap.end())
290 ++ModuleFunctionCount[It->second];
292 BalancingQueueType BalancingQueue(compareClusters);
293for (
unsignedI = 0;
I <
N; ++
I) {
294if (
auto It = ModuleFunctionCount.
find(
I);
295 It != ModuleFunctionCount.
end())
296 BalancingQueue.push(*It);
298 BalancingQueue.push({
I, 0});
300for (
constauto *
constF : UnmappedFunctions) {
301constunsignedI = BalancingQueue.top().first;
302constunsigned Count = BalancingQueue.top().second;
303 BalancingQueue.pop();
304 ClusterIDMap.insert({
F,
I});
305 BalancingQueue.push({
I, Count + 1});
309// FIXME: We should be able to reuse M as the last partition instead of 310// cloning it. Note that the callers at the moment expect the module to 311// be preserved, so will need some adjustments as well. 312for (
unsignedI = 0;
I <
N; ++
I) {
314 std::unique_ptr<Module> MPart(
316if (
auto It = ClusterIDMap.find(GV); It != ClusterIDMap.end())
317return It->second ==
I;
322 MPart->setModuleInlineAsm(
"");
323 ModuleCallback(std::move(MPart));
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
Generic implementation of equivalence classes through the use Tarjan's efficient union-find algorithm...
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N)
static void addNonConstUser(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const User *U)
static void findPartitions(Module &M, ClusterIDMapType &ClusterIDMap, unsigned N)
static void externalize(GlobalValue *GV)
static const GlobalObject * getGVPartitioningRoot(const GlobalValue *GV)
static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const Value *V)
LLVM Basic Block Representation.
The address of a basic block.
static BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
bool isConstantUsed() const
Return true if the constant has users other than constant expressions and other dangling things.
iterator find(const_arg_type_t< KeyT > Val)
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
bool hasLocalLinkage() const
const Comdat * getComdat() const
void setLinkage(LinkageTypes LT)
const GlobalObject * getAliaseeObject() const
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
@ ExternalLinkage
Externally visible function.
A Module instance is used to store all the information related to an LLVM module.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
user_iterator user_begin()
void setName(const Twine &Name)
Change the name of the value.
StringRef getName() const
Return a constant reference to the value's name.
An efficient, type-erasing, non-owning reference to a callable.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
void SplitModule(Module &M, unsigned N, function_ref< void(std::unique_ptr< Module > MPart)> ModuleCallback, bool PreserveLocals=false, bool RoundRobin=false)
Splits the module M into N linkable partitions.
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::unique_ptr< Module > CloneModule(const Module &M)
Return an exact copy of the specified module.