LLVM 23.0.0git
SplitModule.cpp
Go to the documentation of this file.
1//===- SplitModule.cpp - Split a module into partitions -------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
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.
12//
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/IR/Comdat.h"
22#include "llvm/IR/Constant.h"
23#include "llvm/IR/Constants.h"
24#include "llvm/IR/Function.h"
25#include "llvm/IR/GlobalAlias.h"
27#include "llvm/IR/GlobalValue.h"
29#include "llvm/IR/Instruction.h"
30#include "llvm/IR/Module.h"
31#include "llvm/IR/User.h"
32#include "llvm/IR/Value.h"
34#include "llvm/Support/Debug.h"
36#include "llvm/Support/MD5.h"
40#include <cassert>
41#include <iterator>
42#include <memory>
43#include <queue>
44#include <utility>
45#include <vector>
46
47using namespace llvm;
48
49#define DEBUG_TYPE "split-module"
50
51namespace {
52
53using ClusterMapType = EquivalenceClasses<const GlobalValue *>;
54using ComdatMembersType = DenseMap<const Comdat *, const GlobalValue *>;
55using ClusterIDMapType = DenseMap<const GlobalValue *, unsigned>;
56
57bool compareClusters(const std::pair<unsigned, unsigned> &A,
58 const std::pair<unsigned, unsigned> &B) {
59 if (A.second || B.second)
60 return A.second > B.second;
61 return A.first > B.first;
62}
63
64using BalancingQueueType =
65 std::priority_queue<std::pair<unsigned, unsigned>,
66 std::vector<std::pair<unsigned, unsigned>>,
67 decltype(compareClusters) *>;
68
69} // end anonymous namespace
70
71static void addNonConstUser(ClusterMapType &GVtoClusterMap,
72 const GlobalValue *GV, const User *U) {
73 assert((!isa<Constant>(U) || isa<GlobalValue>(U)) && "Bad user");
74
75 if (const Instruction *I = dyn_cast<Instruction>(U)) {
76 const GlobalValue *F = I->getParent()->getParent();
77 GVtoClusterMap.unionSets(GV, F);
78 } else if (const GlobalValue *GVU = dyn_cast<GlobalValue>(U)) {
79 GVtoClusterMap.unionSets(GV, GVU);
80 } else {
81 llvm_unreachable("Underimplemented use case");
82 }
83}
84
85// Adds all GlobalValue users of V to the same cluster as GV.
86static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap,
87 const GlobalValue *GV, const Value *V) {
88 for (const auto *U : V->users()) {
90 Worklist.push_back(U);
91 while (!Worklist.empty()) {
92 const User *UU = Worklist.pop_back_val();
93 // For each constant that is not a GV (a pure const) recurse.
94 if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
95 Worklist.append(UU->user_begin(), UU->user_end());
96 continue;
97 }
98 addNonConstUser(GVtoClusterMap, GV, UU);
99 }
100 }
101}
102
104 const GlobalObject *GO = GV->getAliaseeObject();
105 if (const auto *GI = dyn_cast_or_null<GlobalIFunc>(GO))
106 GO = GI->getResolverFunction();
107 return GO;
108}
109
110// Find partitions for module in the way that no locals need to be
111// globalized.
112// Try to balance pack those partitions into N files since this roughly equals
113// thread balancing for the backend codegen step.
114static void findPartitions(Module &M, ClusterIDMapType &ClusterIDMap,
115 unsigned N) {
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
118 // locals to globals.
119 LLVM_DEBUG(dbgs() << "Partition module with (" << M.size()
120 << ") functions\n");
121 ClusterMapType GVtoClusterMap;
122 ComdatMembersType ComdatMembers;
123
124 auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](GlobalValue &GV) {
125 if (GV.isDeclaration())
126 return;
127
128 if (!GV.hasName())
129 GV.setName("__llvmsplit_unnamed");
130
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.
135 if (const Comdat *C = GV.getComdat()) {
136 auto &Member = ComdatMembers[C];
137 if (Member)
138 GVtoClusterMap.unionSets(Member, &GV);
139 else
140 Member = &GV;
141 }
142
143 // Aliases should not be separated from their aliasees and ifuncs should
144 // not be separated from their resolvers regardless of linkage.
145 if (const GlobalObject *Root = getGVPartitioningRoot(&GV))
146 if (&GV != Root)
147 GVtoClusterMap.unionSets(&GV, Root);
148
149 if (const Function *F = dyn_cast<Function>(&GV)) {
150 for (const BasicBlock &BB : *F) {
152 if (!BA || !BA->isConstantUsed())
153 continue;
154 addAllGlobalValueUsers(GVtoClusterMap, F, BA);
155 }
156 }
157
158 if (GV.hasLocalLinkage())
159 addAllGlobalValueUsers(GVtoClusterMap, &GV, &GV);
160 };
161
162 llvm::for_each(M.functions(), recordGVSet);
163 llvm::for_each(M.globals(), recordGVSet);
164 llvm::for_each(M.aliases(), recordGVSet);
165 llvm::for_each(M.ifuncs(), recordGVSet);
166
167 // Assigned all GVs to merged clusters while balancing number of objects in
168 // each.
169 BalancingQueueType BalancingQueue(compareClusters);
170 // Pre-populate priority queue with N slot blanks.
171 for (unsigned i = 0; i < N; ++i)
172 BalancingQueue.push(std::make_pair(i, 0));
173
175
176 // To guarantee determinism, we have to sort SCC according to size.
177 // When size is the same, use leader's name.
178 for (const auto &C : GVtoClusterMap) {
179 if (!C->isLeader())
180 continue;
181
182 unsigned CurrentClusterID = BalancingQueue.top().first;
183 unsigned CurrentClusterSize = BalancingQueue.top().second;
184 BalancingQueue.pop();
185
186 LLVM_DEBUG(dbgs() << "Root[" << CurrentClusterID << "] cluster_size("
187 << std::distance(GVtoClusterMap.member_begin(*C),
188 GVtoClusterMap.member_end())
189 << ") ----> " << C->getData()->getName() << "\n");
190
191 for (ClusterMapType::member_iterator MI = GVtoClusterMap.findLeader(*C);
192 MI != GVtoClusterMap.member_end(); ++MI) {
193 if (!Visited.insert(*MI).second)
194 continue;
195 LLVM_DEBUG(dbgs() << "----> " << (*MI)->getName()
196 << ((*MI)->hasLocalLinkage() ? " l " : " e ") << "\n");
197 Visited.insert(*MI);
198 ClusterIDMap[*MI] = CurrentClusterID;
199 CurrentClusterSize++;
200 }
201 // Add this set size to the number of entries in this cluster.
202 BalancingQueue.push(std::make_pair(CurrentClusterID, CurrentClusterSize));
203 }
204}
205
206static void externalize(GlobalValue *GV) {
207 if (GV->hasLocalLinkage()) {
210 }
211
212 // Unnamed entities must be named consistently between modules. setName will
213 // give a distinct name to each such entity.
214 if (!GV->hasName())
215 GV->setName("__llvmsplit_unnamed");
216}
217
218// Returns whether GV should be in partition (0-based) I of N.
219static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) {
220 if (const GlobalObject *Root = getGVPartitioningRoot(GV))
221 GV = Root;
222
223 StringRef Name;
224 if (const Comdat *C = GV->getComdat())
225 Name = C->getName();
226 else
227 Name = GV->getName();
228
229 // Partition by MD5 hash. We only need a few bits for evenness as the number
230 // of partitions will generally be in the 1-2 figure range; the low 16 bits
231 // are enough.
232 MD5 H;
234 H.update(Name);
235 H.final(R);
236 return (R[0] | (R[1] << 8)) % N == I;
237}
238
240 Module &M, unsigned N,
241 function_ref<void(std::unique_ptr<Module> MPart)> ModuleCallback,
242 bool PreserveLocals, bool RoundRobin) {
243 if (!PreserveLocals) {
244 for (Function &F : M)
245 externalize(&F);
246 for (GlobalVariable &GV : M.globals())
247 externalize(&GV);
248 for (GlobalAlias &GA : M.aliases())
249 externalize(&GA);
250 for (GlobalIFunc &GIF : M.ifuncs())
251 externalize(&GIF);
252 }
253
254 // This performs splitting without a need for externalization, which might not
255 // always be possible.
256 ClusterIDMapType ClusterIDMap;
257 findPartitions(M, ClusterIDMap, N);
258
259 // Find functions not mapped to modules in ClusterIDMap and count functions
260 // per module. Map unmapped functions using round-robin so that they skip
261 // being distributed by isInPartition() based on function name hashes below.
262 // This provides better uniformity of distribution of functions to modules
263 // in some cases - for example when the number of functions equals to N.
264 if (RoundRobin) {
265 DenseMap<unsigned, unsigned> ModuleFunctionCount;
266 SmallVector<const GlobalValue *> UnmappedFunctions;
267 for (const auto &F : M.functions()) {
268 if (F.isDeclaration() ||
270 continue;
271 auto It = ClusterIDMap.find(&F);
272 if (It == ClusterIDMap.end())
273 UnmappedFunctions.push_back(&F);
274 else
275 ++ModuleFunctionCount[It->second];
276 }
277 BalancingQueueType BalancingQueue(compareClusters);
278 for (unsigned I = 0; I < N; ++I) {
279 if (auto It = ModuleFunctionCount.find(I);
280 It != ModuleFunctionCount.end())
281 BalancingQueue.push(*It);
282 else
283 BalancingQueue.push({I, 0});
284 }
285 for (const auto *const F : UnmappedFunctions) {
286 const unsigned I = BalancingQueue.top().first;
287 const unsigned Count = BalancingQueue.top().second;
288 BalancingQueue.pop();
289 ClusterIDMap.insert({F, I});
290 BalancingQueue.push({I, Count + 1});
291 }
292 }
293
294 // FIXME: We should be able to reuse M as the last partition instead of
295 // cloning it. Note that the callers at the moment expect the module to
296 // be preserved, so will need some adjustments as well.
297 for (unsigned I = 0; I < N; ++I) {
299 std::unique_ptr<Module> MPart(
300 CloneModule(M, VMap, [&](const GlobalValue *GV) {
301 if (auto It = ClusterIDMap.find(GV); It != ClusterIDMap.end())
302 return It->second == I;
303 else
304 return isInPartition(GV, I, N);
305 }));
306 if (I != 0)
307 MPart->setModuleInlineAsm("");
308 ModuleCallback(std::move(MPart));
309 }
310}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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...
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define H(x, y, z)
Definition MD5.cpp:56
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)
#define LLVM_DEBUG(...)
Definition Debug.h:119
LLVM Basic Block Representation.
Definition BasicBlock.h:62
The address of a basic block.
Definition Constants.h:1082
static LLVM_ABI BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
LLVM_ABI 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)
Definition DenseMap.h:178
iterator end()
Definition DenseMap.h:85
This represents a collection of equivalence classes and supports three efficient operations: insert a...
bool hasLocalLinkage() const
LLVM_ABI const Comdat * getComdat() const
Definition Globals.cpp:210
void setLinkage(LinkageTypes LT)
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:450
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
void setVisibility(VisibilityTypes V)
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM Value Representation.
Definition Value.h:75
user_iterator user_begin()
Definition Value.h:402
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:393
user_iterator user_end()
Definition Value.h:410
bool hasName() const
Definition Value.h:261
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
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.
Definition CallingConv.h:34
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.
Definition STLExtras.h:1731
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI 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.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI std::unique_ptr< Module > CloneModule(const Module &M)
Return an exact copy of the specified module.
#define N