52 #define DEBUG_TYPE "split-module" 64 assert((!isa<Constant>(U) || isa<GlobalValue>(U)) &&
"Bad user");
68 GVtoClusterMap.unionSets(GV, F);
69 }
else if (isa<GlobalIndirectSymbol>(U) || isa<Function>(U) ||
70 isa<GlobalVariable>(U)) {
71 GVtoClusterMap.unionSets(GV, cast<GlobalValue>(U));
80 for (
auto *U : V->
users()) {
83 while (!Worklist.
empty()) {
86 if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
106 ClusterMapType GVtoClusterMap;
107 ComdatMembersType ComdatMembers;
109 auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](
GlobalValue &GV) {
110 if (GV.isDeclaration())
114 GV.setName(
"__llvmsplit_unnamed");
120 if (
const Comdat *
C = GV.getComdat()) {
121 auto &Member = ComdatMembers[
C];
123 GVtoClusterMap.unionSets(Member, &GV);
130 if (
auto *GIS = dyn_cast<GlobalIndirectSymbol>(&GV)) {
132 GVtoClusterMap.unionSets(&GV,
Base);
135 if (
const Function *
F = dyn_cast<Function>(&GV)) {
144 if (GV.hasLocalLinkage())
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;
159 return a.first > b.first;
162 std::priority_queue<std::pair<unsigned, unsigned>,
163 std::vector<std::pair<unsigned, unsigned>>,
164 decltype(CompareClusters)>
165 BalancinQueue(CompareClusters);
167 for (
unsigned i = 0; i <
N; ++i)
168 BalancinQueue.push(std::make_pair(i, 0));
170 using SortType = std::pair<unsigned, ClusterMapType::iterator>;
177 for (ClusterMapType::iterator
I = GVtoClusterMap.begin(),
178 E = GVtoClusterMap.end();
I !=
E; ++
I)
181 std::make_pair(std::distance(GVtoClusterMap.member_begin(
I),
182 GVtoClusterMap.member_end()),
I));
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();
188 return a.first > b.first;
191 for (
auto &
I : Sets) {
192 unsigned CurrentClusterID = BalancinQueue.top().first;
193 unsigned CurrentClusterSize = BalancinQueue.top().second;
196 LLVM_DEBUG(
dbgs() <<
"Root[" << CurrentClusterID <<
"] cluster_size(" 197 <<
I.first <<
") ----> " <<
I.second->getData()->getName()
200 for (ClusterMapType::member_iterator
MI =
201 GVtoClusterMap.findLeader(
I.second);
202 MI != GVtoClusterMap.member_end(); ++
MI) {
203 if (!Visited.
insert(*MI).second)
206 << ((*MI)->hasLocalLinkage() ?
" l " :
" e ") <<
"\n");
208 ClusterIDMap[*
MI] = CurrentClusterID;
209 CurrentClusterSize++;
212 BalancinQueue.push(std::make_pair(CurrentClusterID, CurrentClusterSize));
225 GV->
setName(
"__llvmsplit_unnamed");
230 if (
auto *GIS = dyn_cast<GlobalIndirectSymbol>(GV))
247 return (R[0] | (R[1] << 8)) % N ==
I;
251 std::unique_ptr<Module> M,
unsigned N,
252 function_ref<
void(std::unique_ptr<Module> MPart)> ModuleCallback,
253 bool PreserveLocals) {
254 if (!PreserveLocals) {
267 ClusterIDMapType ClusterIDMap;
272 for (
unsigned I = 0;
I <
N; ++
I) {
274 std::unique_ptr<Module> MPart(
276 if (ClusterIDMap.count(GV))
277 return (ClusterIDMap[GV] ==
I);
282 MPart->setModuleInlineAsm(
"");
283 ModuleCallback(std::move(MPart));
void setVisibility(VisibilityTypes V)
bool hasLocalLinkage() const
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
bool isConstantUsed() const
Return true if the constant has users other than constant expressions and other dangling things...
void push_back(const T &Elt)
void SplitModule(std::unique_ptr< Module > M, unsigned N, function_ref< void(std::unique_ptr< Module > MPart)> ModuleCallback, bool PreserveLocals=false)
Splits the module M into N linkable partitions.
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...
Externally visible function.
static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const Value *V)
static void externalize(GlobalValue *GV)
The address of a basic block.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
void setName(const Twine &Name)
Change the name of the value.
static void findPartitions(Module *M, ClusterIDMapType &ClusterIDMap, unsigned N)
std::unique_ptr< Module > CloneModule(const Module &M)
Return an exact copy of the specified module.
iterator_range< iterator > functions()
LLVM Basic Block Representation.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void addNonConstUser(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const User *U)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void sort(IteratorTy Start, IteratorTy End)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
LLVM_NODISCARD T pop_back_val()
void setLinkage(LinkageTypes LT)
static BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const Comdat * getComdat() const
iterator_range< user_iterator > users()
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
LLVM_NODISCARD bool empty() const
StringRef getName() const
Return a constant reference to the value's name.
static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
LLVM Value Representation.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
iterator_range< global_iterator > globals()
StringRef - Represent a constant reference to a string, i.e.
UnaryPredicate for_each(R &&Range, UnaryPredicate P)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly...
iterator_range< alias_iterator > aliases()