xref: /llvm-project/llvm/lib/Transforms/Utils/SplitModule.cpp (revision 1a6e1ee42a6af255d45e3fd2fe87021dd31f79bb)
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 
15 #include "llvm/Transforms/Utils/SplitModule.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/EquivalenceClasses.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/SmallVector.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"
26 #include "llvm/IR/GlobalObject.h"
27 #include "llvm/IR/GlobalIndirectSymbol.h"
28 #include "llvm/IR/GlobalValue.h"
29 #include "llvm/IR/GlobalVariable.h"
30 #include "llvm/IR/Instruction.h"
31 #include "llvm/IR/Module.h"
32 #include "llvm/IR/User.h"
33 #include "llvm/IR/Value.h"
34 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Support/ErrorHandling.h"
37 #include "llvm/Support/MD5.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include "llvm/Transforms/Utils/Cloning.h"
40 #include "llvm/Transforms/Utils/ValueMapper.h"
41 #include <algorithm>
42 #include <cassert>
43 #include <iterator>
44 #include <memory>
45 #include <queue>
46 #include <utility>
47 #include <vector>
48 
49 using namespace llvm;
50 
51 #define DEBUG_TYPE "split-module"
52 
53 namespace {
54 
55 using ClusterMapType = EquivalenceClasses<const GlobalValue *>;
56 using ComdatMembersType = DenseMap<const Comdat *, const GlobalValue *>;
57 using ClusterIDMapType = DenseMap<const GlobalValue *, unsigned>;
58 
59 } // end anonymous namespace
60 
61 static void addNonConstUser(ClusterMapType &GVtoClusterMap,
62                             const GlobalValue *GV, const User *U) {
63   assert((!isa<Constant>(U) || isa<GlobalValue>(U)) && "Bad user");
64 
65   if (const Instruction *I = dyn_cast<Instruction>(U)) {
66     const GlobalValue *F = I->getParent()->getParent();
67     GVtoClusterMap.unionSets(GV, F);
68   } else if (isa<GlobalIndirectSymbol>(U) || isa<Function>(U) ||
69              isa<GlobalVariable>(U)) {
70     GVtoClusterMap.unionSets(GV, cast<GlobalValue>(U));
71   } else {
72     llvm_unreachable("Underimplemented use case");
73   }
74 }
75 
76 // Adds all GlobalValue users of V to the same cluster as GV.
77 static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap,
78                                    const GlobalValue *GV, const Value *V) {
79   for (auto *U : V->users()) {
80     SmallVector<const User *, 4> Worklist;
81     Worklist.push_back(U);
82     while (!Worklist.empty()) {
83       const User *UU = Worklist.pop_back_val();
84       // For each constant that is not a GV (a pure const) recurse.
85       if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
86         Worklist.append(UU->user_begin(), UU->user_end());
87         continue;
88       }
89       addNonConstUser(GVtoClusterMap, GV, UU);
90     }
91   }
92 }
93 
94 // Find partitions for module in the way that no locals need to be
95 // globalized.
96 // Try to balance pack those partitions into N files since this roughly equals
97 // thread balancing for the backend codegen step.
98 static void findPartitions(Module &M, ClusterIDMapType &ClusterIDMap,
99                            unsigned N) {
100   // At this point module should have the proper mix of globals and locals.
101   // As we attempt to partition this module, we must not change any
102   // locals to globals.
103   LLVM_DEBUG(dbgs() << "Partition module with (" << M.size() << ")functions\n");
104   ClusterMapType GVtoClusterMap;
105   ComdatMembersType ComdatMembers;
106 
107   auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](GlobalValue &GV) {
108     if (GV.isDeclaration())
109       return;
110 
111     if (!GV.hasName())
112       GV.setName("__llvmsplit_unnamed");
113 
114     // Comdat groups must not be partitioned. For comdat groups that contain
115     // locals, record all their members here so we can keep them together.
116     // Comdat groups that only contain external globals are already handled by
117     // the MD5-based partitioning.
118     if (const Comdat *C = GV.getComdat()) {
119       auto &Member = ComdatMembers[C];
120       if (Member)
121         GVtoClusterMap.unionSets(Member, &GV);
122       else
123         Member = &GV;
124     }
125 
126     // For aliases we should not separate them from their aliasees regardless
127     // of linkage.
128     if (auto *GIS = dyn_cast<GlobalAlias>(&GV)) {
129       if (const GlobalObject *Base = GIS->getBaseObject())
130         GVtoClusterMap.unionSets(&GV, Base);
131     } else if (auto *GIS = dyn_cast<GlobalIFunc>(&GV)) {
132       GVtoClusterMap.unionSets(&GV, GIS->getResolverFunction());
133     }
134 
135     if (const Function *F = dyn_cast<Function>(&GV)) {
136       for (const BasicBlock &BB : *F) {
137         BlockAddress *BA = BlockAddress::lookup(&BB);
138         if (!BA || !BA->isConstantUsed())
139           continue;
140         addAllGlobalValueUsers(GVtoClusterMap, F, BA);
141       }
142     }
143 
144     if (GV.hasLocalLinkage())
145       addAllGlobalValueUsers(GVtoClusterMap, &GV, &GV);
146   };
147 
148   llvm::for_each(M.functions(), recordGVSet);
149   llvm::for_each(M.globals(), recordGVSet);
150   llvm::for_each(M.aliases(), recordGVSet);
151 
152   // Assigned all GVs to merged clusters while balancing number of objects in
153   // each.
154   auto CompareClusters = [](const std::pair<unsigned, unsigned> &a,
155                             const std::pair<unsigned, unsigned> &b) {
156     if (a.second || b.second)
157       return a.second > b.second;
158     else
159       return a.first > b.first;
160   };
161 
162   std::priority_queue<std::pair<unsigned, unsigned>,
163                       std::vector<std::pair<unsigned, unsigned>>,
164                       decltype(CompareClusters)>
165       BalancinQueue(CompareClusters);
166   // Pre-populate priority queue with N slot blanks.
167   for (unsigned i = 0; i < N; ++i)
168     BalancinQueue.push(std::make_pair(i, 0));
169 
170   using SortType = std::pair<unsigned, ClusterMapType::iterator>;
171 
172   SmallVector<SortType, 64> Sets;
173   SmallPtrSet<const GlobalValue *, 32> Visited;
174 
175   // To guarantee determinism, we have to sort SCC according to size.
176   // When size is the same, use leader's name.
177   for (ClusterMapType::iterator I = GVtoClusterMap.begin(),
178                                 E = GVtoClusterMap.end(); I != E; ++I)
179     if (I->isLeader())
180       Sets.push_back(
181           std::make_pair(std::distance(GVtoClusterMap.member_begin(I),
182                                        GVtoClusterMap.member_end()), I));
183 
184   llvm::sort(Sets, [](const SortType &a, const SortType &b) {
185     if (a.first == b.first)
186       return a.second->getData()->getName() > b.second->getData()->getName();
187     else
188       return a.first > b.first;
189   });
190 
191   for (auto &I : Sets) {
192     unsigned CurrentClusterID = BalancinQueue.top().first;
193     unsigned CurrentClusterSize = BalancinQueue.top().second;
194     BalancinQueue.pop();
195 
196     LLVM_DEBUG(dbgs() << "Root[" << CurrentClusterID << "] cluster_size("
197                       << I.first << ") ----> " << I.second->getData()->getName()
198                       << "\n");
199 
200     for (ClusterMapType::member_iterator MI =
201              GVtoClusterMap.findLeader(I.second);
202          MI != GVtoClusterMap.member_end(); ++MI) {
203       if (!Visited.insert(*MI).second)
204         continue;
205       LLVM_DEBUG(dbgs() << "----> " << (*MI)->getName()
206                         << ((*MI)->hasLocalLinkage() ? " l " : " e ") << "\n");
207       Visited.insert(*MI);
208       ClusterIDMap[*MI] = CurrentClusterID;
209       CurrentClusterSize++;
210     }
211     // Add this set size to the number of entries in this cluster.
212     BalancinQueue.push(std::make_pair(CurrentClusterID, CurrentClusterSize));
213   }
214 }
215 
216 static void externalize(GlobalValue *GV) {
217   if (GV->hasLocalLinkage()) {
218     GV->setLinkage(GlobalValue::ExternalLinkage);
219     GV->setVisibility(GlobalValue::HiddenVisibility);
220   }
221 
222   // Unnamed entities must be named consistently between modules. setName will
223   // give a distinct name to each such entity.
224   if (!GV->hasName())
225     GV->setName("__llvmsplit_unnamed");
226 }
227 
228 // Returns whether GV should be in partition (0-based) I of N.
229 static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) {
230   if (auto *GIS = dyn_cast<GlobalAlias>(GV)) {
231     if (const GlobalObject *Base = GIS->getBaseObject())
232       GV = Base;
233   } else if (auto *GIS = dyn_cast<GlobalIFunc>(GV)) {
234     GV = GIS->getResolverFunction();
235   }
236 
237   StringRef Name;
238   if (const Comdat *C = GV->getComdat())
239     Name = C->getName();
240   else
241     Name = GV->getName();
242 
243   // Partition by MD5 hash. We only need a few bits for evenness as the number
244   // of partitions will generally be in the 1-2 figure range; the low 16 bits
245   // are enough.
246   MD5 H;
247   MD5::MD5Result R;
248   H.update(Name);
249   H.final(R);
250   return (R[0] | (R[1] << 8)) % N == I;
251 }
252 
253 void llvm::SplitModule(
254     Module &M, unsigned N,
255     function_ref<void(std::unique_ptr<Module> MPart)> ModuleCallback,
256     bool PreserveLocals) {
257   if (!PreserveLocals) {
258     for (Function &F : M)
259       externalize(&F);
260     for (GlobalVariable &GV : M.globals())
261       externalize(&GV);
262     for (GlobalAlias &GA : M.aliases())
263       externalize(&GA);
264     for (GlobalIFunc &GIF : M.ifuncs())
265       externalize(&GIF);
266   }
267 
268   // This performs splitting without a need for externalization, which might not
269   // always be possible.
270   ClusterIDMapType ClusterIDMap;
271   findPartitions(M, ClusterIDMap, N);
272 
273   // FIXME: We should be able to reuse M as the last partition instead of
274   // cloning it. Note that the callers at the moment expect the module to
275   // be preserved, so will need some adjustments as well.
276   for (unsigned I = 0; I < N; ++I) {
277     ValueToValueMapTy VMap;
278     std::unique_ptr<Module> MPart(
279         CloneModule(M, VMap, [&](const GlobalValue *GV) {
280           if (ClusterIDMap.count(GV))
281             return (ClusterIDMap[GV] == I);
282           else
283             return isInPartition(GV, I, N);
284         }));
285     if (I != 0)
286       MPart->setModuleInlineAsm("");
287     ModuleCallback(std::move(MPart));
288   }
289 }
290