50#define DEBUG_TYPE "split-module"
62 assert((!isa<Constant>(U) || isa<GlobalValue>(U)) &&
"Bad user");
66 GVtoClusterMap.unionSets(GV,
F);
67 }
else if (
const GlobalValue *GVU = dyn_cast<GlobalValue>(U)) {
68 GVtoClusterMap.unionSets(GV, GVU);
77 for (
const auto *U : V->users()) {
80 while (!Worklist.
empty()) {
83 if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
94 if (
const auto *GI = dyn_cast_or_null<GlobalIFunc>(GO))
95 GO = GI->getResolverFunction();
108 LLVM_DEBUG(
dbgs() <<
"Partition module with (" << M.size() <<
")functions\n");
109 ClusterMapType GVtoClusterMap;
110 ComdatMembersType ComdatMembers;
112 auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](
GlobalValue &GV) {
113 if (GV.isDeclaration())
117 GV.setName(
"__llvmsplit_unnamed");
123 if (
const Comdat *
C = GV.getComdat()) {
124 auto &Member = ComdatMembers[
C];
126 GVtoClusterMap.unionSets(Member, &GV);
135 GVtoClusterMap.unionSets(&GV, Root);
137 if (
const Function *
F = dyn_cast<Function>(&GV)) {
146 if (GV.hasLocalLinkage())
156 auto CompareClusters = [](
const std::pair<unsigned, unsigned> &a,
157 const std::pair<unsigned, unsigned> &b) {
158 if (a.second || b.second)
159 return a.second > b.second;
161 return a.first > b.first;
164 std::priority_queue<std::pair<unsigned, unsigned>,
165 std::vector<std::pair<unsigned, unsigned>>,
166 decltype(CompareClusters)>
167 BalancinQueue(CompareClusters);
169 for (
unsigned i = 0; i <
N; ++i)
170 BalancinQueue.push(std::make_pair(i, 0));
172 using SortType = std::pair<unsigned, ClusterMapType::iterator>;
179 for (ClusterMapType::iterator
I = GVtoClusterMap.begin(),
180 E = GVtoClusterMap.end();
I !=
E; ++
I)
183 std::make_pair(std::distance(GVtoClusterMap.member_begin(
I),
184 GVtoClusterMap.member_end()),
I));
186 llvm::sort(Sets, [](
const SortType &a,
const SortType &b) {
187 if (a.first == b.first)
188 return a.second->getData()->getName() > b.second->getData()->getName();
190 return a.first > b.first;
193 for (
auto &
I : Sets) {
194 unsigned CurrentClusterID = BalancinQueue.top().first;
195 unsigned CurrentClusterSize = BalancinQueue.top().second;
198 LLVM_DEBUG(
dbgs() <<
"Root[" << CurrentClusterID <<
"] cluster_size("
199 <<
I.first <<
") ----> " <<
I.second->getData()->getName()
202 for (ClusterMapType::member_iterator
MI =
203 GVtoClusterMap.findLeader(
I.second);
204 MI != GVtoClusterMap.member_end(); ++
MI) {
205 if (!Visited.
insert(*MI).second)
208 << ((*MI)->hasLocalLinkage() ?
" l " :
" e ") <<
"\n");
210 ClusterIDMap[*
MI] = CurrentClusterID;
211 CurrentClusterSize++;
214 BalancinQueue.push(std::make_pair(CurrentClusterID, CurrentClusterSize));
227 GV->
setName(
"__llvmsplit_unnamed");
248 return (R[0] | (R[1] << 8)) %
N ==
I;
253 function_ref<
void(std::unique_ptr<Module> MPart)> ModuleCallback,
254 bool PreserveLocals) {
255 if (!PreserveLocals) {
268 ClusterIDMapType ClusterIDMap;
274 for (
unsigned I = 0;
I <
N; ++
I) {
276 std::unique_ptr<Module> MPart(
278 if (ClusterIDMap.count(GV))
279 return (ClusterIDMap[GV] ==
I);
284 MPart->setModuleInlineAsm(
"");
285 ModuleCallback(std::move(MPart));
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-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...
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
LLVM Basic Block Representation.
The address of a basic block.
static BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
bool isConstantUsed() const
Return true if the constant has users other than constant expressions and other dangling things.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
bool hasLocalLinkage() const
const Comdat * getComdat() const
void setLinkage(LinkageTypes LT)
const GlobalObject * getAliaseeObject() const
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
@ ExternalLinkage
Externally visible function.
A Module instance is used to store all the information related to an LLVM module.
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.
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
user_iterator user_begin()
void setName(const Twine &Name)
Change the name of the value.
StringRef getName() const
Return a constant reference to the value's name.
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.
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.
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void SplitModule(Module &M, unsigned N, function_ref< void(std::unique_ptr< Module > MPart)> ModuleCallback, bool PreserveLocals=false)
Splits the module M into N linkable partitions.
std::unique_ptr< Module > CloneModule(const Module &M)
Return an exact copy of the specified module.