LLVM 24.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"
41#include <cassert>
42#include <iterator>
43#include <memory>
44#include <queue>
45#include <utility>
46#include <vector>
47
48using namespace llvm;
49
50#define DEBUG_TYPE "split-module"
51
52namespace {
53
54using ClusterMapType = EquivalenceClasses<const GlobalValue *>;
55using ComdatMembersType = DenseMap<const Comdat *, const GlobalValue *>;
56using ClusterIDMapType = DenseMap<const GlobalValue *, unsigned>;
57
58bool compareClusters(const std::pair<unsigned, unsigned> &A,
59 const std::pair<unsigned, unsigned> &B) {
60 if (A.second || B.second)
61 return A.second > B.second;
62 return A.first > B.first;
63}
64
65using BalancingQueueType =
66 std::priority_queue<std::pair<unsigned, unsigned>,
67 std::vector<std::pair<unsigned, unsigned>>,
68 decltype(compareClusters) *>;
69
70} // end anonymous namespace
71
72static void addNonConstUser(ClusterMapType &GVtoClusterMap,
73 const GlobalValue *GV, const User *U) {
74 assert((!isa<Constant>(U) || isa<GlobalValue>(U)) && "Bad user");
75
76 if (const Instruction *I = dyn_cast<Instruction>(U)) {
77 const GlobalValue *F = I->getParent()->getParent();
78 GVtoClusterMap.unionSets(GV, F);
79 } else if (const GlobalValue *GVU = dyn_cast<GlobalValue>(U)) {
80 GVtoClusterMap.unionSets(GV, GVU);
81 } else {
82 llvm_unreachable("Underimplemented use case");
83 }
84}
85
86// Adds all GlobalValue users of V to the same cluster as GV.
87static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap,
88 const GlobalValue *GV, const Value *V) {
89 for (const auto *U : V->users()) {
91 Worklist.push_back(U);
92 while (!Worklist.empty()) {
93 const User *UU = Worklist.pop_back_val();
94 // For each constant that is not a GV (a pure const) recurse.
95 if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
96 Worklist.append(UU->user_begin(), UU->user_end());
97 continue;
98 }
99 addNonConstUser(GVtoClusterMap, GV, UU);
100 }
101 }
102}
103
105 const GlobalObject *GO = GV->getAliaseeObject();
106 if (const auto *GI = dyn_cast_or_null<GlobalIFunc>(GO))
107 GO = GI->getResolverFunction();
108 return GO;
109}
110
111// Find partitions for module in the way that no locals need to be
112// globalized.
113// Try to balance pack those partitions into N files since this roughly equals
114// thread balancing for the backend codegen step.
115static void findPartitions(Module &M, ClusterIDMapType &ClusterIDMap,
116 unsigned N) {
117 // At this point module should have the proper mix of globals and locals.
118 // As we attempt to partition this module, we must not change any
119 // locals to globals.
120 LLVM_DEBUG(dbgs() << "Partition module with (" << M.size()
121 << ") functions\n");
122 ClusterMapType GVtoClusterMap;
123 ComdatMembersType ComdatMembers;
124
125 auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](GlobalValue &GV) {
126 if (GV.isDeclaration())
127 return;
128
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
206// Returns whether GV should be in partition (0-based) I of N.
207static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) {
208 if (const GlobalObject *Root = getGVPartitioningRoot(GV))
209 GV = Root;
210
211 StringRef Name;
212 if (const Comdat *C = GV->getComdat())
213 Name = C->getName();
214 else
215 Name = GV->getName();
216
217 // Partition by MD5 hash. We only need a few bits for evenness as the number
218 // of partitions will generally be in the 1-2 figure range; the low 16 bits
219 // are enough.
220 MD5 H;
222 H.update(Name);
223 H.final(R);
224 return (R[0] | (R[1] << 8)) % N == I;
225}
226
228 Module &M, unsigned N,
229 function_ref<void(std::unique_ptr<Module> MPart)> ModuleCallback,
230 bool PreserveLocals, bool RoundRobin) {
231 if (!PreserveLocals) {
232 for (Function &F : M)
234 for (GlobalVariable &GV : M.globals())
236 for (GlobalAlias &GA : M.aliases())
238 for (GlobalIFunc &GIF : M.ifuncs())
240 }
241
242 // This performs splitting without a need for externalization, which might not
243 // always be possible.
244 ClusterIDMapType ClusterIDMap;
245 findPartitions(M, ClusterIDMap, N);
246
247 // Find functions not mapped to modules in ClusterIDMap and count functions
248 // per module. Map unmapped functions using round-robin so that they skip
249 // being distributed by isInPartition() based on function name hashes below.
250 // This provides better uniformity of distribution of functions to modules
251 // in some cases - for example when the number of functions equals to N.
252 if (RoundRobin) {
253 DenseMap<unsigned, unsigned> ModuleFunctionCount;
254 SmallVector<const GlobalValue *> UnmappedFunctions;
255 for (const auto &F : M.functions()) {
256 if (F.isDeclaration() ||
258 continue;
259 auto It = ClusterIDMap.find(&F);
260 if (It == ClusterIDMap.end())
261 UnmappedFunctions.push_back(&F);
262 else
263 ++ModuleFunctionCount[It->second];
264 }
265 BalancingQueueType BalancingQueue(compareClusters);
266 for (unsigned I = 0; I < N; ++I) {
267 if (auto It = ModuleFunctionCount.find(I);
268 It != ModuleFunctionCount.end())
269 BalancingQueue.push(*It);
270 else
271 BalancingQueue.push({I, 0});
272 }
273 for (const auto *const F : UnmappedFunctions) {
274 const unsigned I = BalancingQueue.top().first;
275 const unsigned Count = BalancingQueue.top().second;
276 BalancingQueue.pop();
277 ClusterIDMap.insert({F, I});
278 BalancingQueue.push({I, Count + 1});
279 }
280 }
281
282 // FIXME: We should be able to reuse M as the last partition instead of
283 // cloning it. Note that the callers at the moment expect the module to
284 // be preserved, so will need some adjustments as well.
285 for (unsigned I = 0; I < N; ++I) {
287 std::unique_ptr<Module> MPart(
288 CloneModule(M, VMap, [&](const GlobalValue *GV) {
289 if (auto It = ClusterIDMap.find(GV); It != ClusterIDMap.end())
290 return It->second == I;
291 else
292 return isInPartition(GV, I, N);
293 }));
294 if (I != 0)
295 MPart->removeModuleInlineAsm();
296 ModuleCallback(std::move(MPart));
297 }
298}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 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:1088
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:251
iterator end()
Definition DenseMap.h:169
This represents a collection of equivalence classes and supports three efficient operations: insert a...
LLVM_ABI const Comdat * getComdat() const
Definition Globals.cpp:274
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:521
@ 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:68
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:404
user_iterator user_end()
Definition Value.h:412
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
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.
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:1732
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
LLVM_ABI void nameUnnamedGlobalValue(GlobalValue &GV)
Assign a stable name to GV if it is unnamed, so that it is named consistently across the split partit...
LLVM_ABI void externalizeGlobal(GlobalValue &GV)
If GV has local linkage, promote it to external + hidden visibility so it can be referenced across mo...
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
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
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