Go to the documentation of this file.
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 (
auto *U : V->
users()) {
79 Worklist.push_back(U);
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(
"");
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
@ HiddenVisibility
The GV is hidden.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
static void externalize(GlobalValue *GV)
static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const Value *V)
static void findPartitions(Module &M, ClusterIDMapType &ClusterIDMap, unsigned N)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
user_iterator user_begin()
LLVM_NODISCARD T pop_back_val()
LLVM Basic Block Representation.
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
(vector float) vec_cmpeq(*A, *B) C
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int b
void setName(const Twine &Name)
Change the name of the value.
An efficient, type-erasing, non-owning reference to a callable.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
static void addNonConstUser(ClusterMapType &GVtoClusterMap, const GlobalValue *GV, const User *U)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
void setLinkage(LinkageTypes LT)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasLocalLinkage() const
A Module instance is used to store all the information related to an LLVM module.
The address of a basic block.
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const GlobalObject * getAliaseeObject() const
StringRef getName() const
Return a constant reference to the value's name.
const Comdat * getComdat() const
void sort(IteratorTy Start, IteratorTy End)
@ ExternalLinkage
Externally visible function.
std::unique_ptr< Module > CloneModule(const Module &M)
Return an exact copy of the specified module.
static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N)
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
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.
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.
void setVisibility(VisibilityTypes V)
LLVM Value Representation.
iterator_range< user_iterator > users()
static const GlobalObject * getGVPartitioningRoot(const GlobalValue *GV)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.