16 #define DEBUG_TYPE "split-module"
45 assert((!isa<Constant>(U) || isa<GlobalValue>(U)) &&
"Bad user");
49 GVtoClusterMap.unionSets(GV, F);
50 }
else if (isa<GlobalIndirectSymbol>(U) || isa<Function>(U) ||
51 isa<GlobalVariable>(U)) {
52 GVtoClusterMap.unionSets(GV, cast<GlobalValue>(U));
61 for (
auto *U : V->
users()) {
64 while (!Worklist.
empty()) {
67 if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
85 DEBUG(
dbgs() <<
"Partition module with (" << M->
size() <<
")functions\n");
86 ClusterMapType GVtoClusterMap;
87 ComdatMembersType ComdatMembers;
89 auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](
GlobalValue &GV) {
90 if (GV.isDeclaration())
94 GV.setName(
"__llvmsplit_unnamed");
100 if (
const Comdat *
C = GV.getComdat()) {
101 auto &Member = ComdatMembers[
C];
103 GVtoClusterMap.unionSets(Member, &GV);
110 if (
auto *GIS = dyn_cast<GlobalIndirectSymbol>(&GV)) {
112 GVtoClusterMap.unionSets(&GV, Base);
115 if (
const Function *
F = dyn_cast<Function>(&GV)) {
124 if (GV.hasLocalLinkage())
128 std::for_each(M->
begin(), M->
end(), recordGVSet);
134 auto CompareClusters = [](
const std::pair<unsigned, unsigned> &a,
135 const std::pair<unsigned, unsigned> &b) {
136 if (a.second || b.second)
137 return a.second > b.second;
139 return a.first > b.first;
142 std::priority_queue<std::pair<unsigned, unsigned>,
143 std::vector<std::pair<unsigned, unsigned>>,
144 decltype(CompareClusters)>
145 BalancinQueue(CompareClusters);
147 for (
unsigned i = 0;
i <
N; ++
i)
148 BalancinQueue.push(std::make_pair(
i, 0));
150 typedef std::pair<unsigned, ClusterMapType::iterator> SortType;
156 for (ClusterMapType::iterator
I = GVtoClusterMap.begin(),
157 E = GVtoClusterMap.end();
I !=
E; ++
I)
160 std::make_pair(std::distance(GVtoClusterMap.member_begin(
I),
161 GVtoClusterMap.member_end()),
I));
163 std::sort(Sets.
begin(), Sets.
end(), [](
const SortType &a,
const SortType &b) {
164 if (a.first == b.first)
165 return a.second->getData()->getName() > b.second->getData()->getName();
167 return a.first > b.first;
170 for (
auto &
I : Sets) {
171 unsigned CurrentClusterID = BalancinQueue.top().first;
172 unsigned CurrentClusterSize = BalancinQueue.top().second;
175 DEBUG(
dbgs() <<
"Root[" << CurrentClusterID <<
"] cluster_size(" <<
I.first
176 <<
") ----> " <<
I.second->getData()->getName() <<
"\n");
178 for (ClusterMapType::member_iterator
MI =
179 GVtoClusterMap.findLeader(
I.second);
180 MI != GVtoClusterMap.member_end(); ++
MI) {
181 if (!Visited.
insert(*MI).second)
183 DEBUG(
dbgs() <<
"----> " << (*MI)->getName()
184 << ((*MI)->hasLocalLinkage() ?
" l " :
" e ") <<
"\n");
186 ClusterIDMap[*
MI] = CurrentClusterID;
187 CurrentClusterSize++;
190 BalancinQueue.push(std::make_pair(CurrentClusterID, CurrentClusterSize));
203 GV->
setName(
"__llvmsplit_unnamed");
208 if (
auto *GIS = dyn_cast<GlobalIndirectSymbol>(GV))
225 return (R[0] | (R[1] << 8)) % N ==
I;
229 std::unique_ptr<Module> M,
unsigned N,
230 function_ref<
void(std::unique_ptr<Module> MPart)> ModuleCallback,
231 bool PreserveLocals) {
232 if (!PreserveLocals) {
245 ClusterIDMapType ClusterIDMap;
250 for (
unsigned I = 0;
I <
N; ++
I) {
252 std::unique_ptr<Module> MPart(
254 if (ClusterIDMap.count(GV))
255 return (ClusterIDMap[GV] ==
I);
260 MPart->setModuleInlineAsm(
"");
261 ModuleCallback(std::move(MPart));
void setVisibility(VisibilityTypes V)
void push_back(const T &Elt)
A Module instance is used to store all the information related to an LLVM module. ...
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.
Externally visible function.
static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const Value *V)
static void externalize(GlobalValue *GV)
StringRef getName() const
Return a constant reference to the value's name.
The address of a basic block.
void setName(const Twine &Name)
Change the name of the value.
LLVM_NODISCARD bool empty() const
global_iterator global_begin()
bool isConstantUsed() const
Return true if the constant has users other than constant expressions and other dangling things...
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static void findPartitions(Module *M, ClusterIDMapType &ClusterIDMap, unsigned N)
alias_iterator alias_end()
LLVM Basic Block Representation.
static void addNonConstUser(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const User *U)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
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...
std::unique_ptr< Module > CloneModule(const Module *M)
Return an exact copy of the specified module.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
global_iterator global_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()
alias_iterator alias_begin()
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
void setLinkage(LinkageTypes LT)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
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.
iterator_range< user_iterator > users()
const GlobalObject * getBaseObject() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N)
bool hasLocalLinkage() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.