aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SplitModule.cpp
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-03-31 21:55:11 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-03-31 21:55:11 +0000
commitf74f091ea6141a6b7efc0f9480e10451bcb0c200 (patch)
tree0df5aa9b8432f28054034d935b54c052956a389b /llvm/lib/Transforms/Utils/SplitModule.cpp
parentae272d718e882b18258a587ce111a4150d761b5e (diff)
downloadllvm-f74f091ea6141a6b7efc0f9480e10451bcb0c200.zip
llvm-f74f091ea6141a6b7efc0f9480e10451bcb0c200.tar.gz
llvm-f74f091ea6141a6b7efc0f9480e10451bcb0c200.tar.bz2
Preserve blockaddress use edges in the module splitter.
"blockaddress" can not apply to an external function. All blockaddress constant uses must belong to the same module as the definition of the target function. llvm-svn: 265061
Diffstat (limited to 'llvm/lib/Transforms/Utils/SplitModule.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SplitModule.cpp91
1 files changed, 46 insertions, 45 deletions
diff --git a/llvm/lib/Transforms/Utils/SplitModule.cpp b/llvm/lib/Transforms/Utils/SplitModule.cpp
index 993d3e5..718edad 100644
--- a/llvm/lib/Transforms/Utils/SplitModule.cpp
+++ b/llvm/lib/Transforms/Utils/SplitModule.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalObject.h"
@@ -55,6 +56,24 @@ static void addNonConstUser(ClusterMapType &GVtoClusterMap,
}
}
+// Adds all GlobalValue users of V to the same cluster as GV.
+static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap,
+ const GlobalValue *GV, const Value *V) {
+ for (auto *U : V->users()) {
+ SmallVector<const User *, 4> Worklist;
+ Worklist.push_back(U);
+ while (!Worklist.empty()) {
+ const User *UU = Worklist.pop_back_val();
+ // For each constant that is not a GV (a pure const) recurse.
+ if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
+ Worklist.append(UU->user_begin(), UU->user_end());
+ continue;
+ }
+ addNonConstUser(GVtoClusterMap, GV, UU);
+ }
+ }
+}
+
// Find partitions for module in the way that no locals need to be
// globalized.
// Try to balance pack those partitions into N files since this roughly equals
@@ -64,7 +83,6 @@ static void findPartitions(Module *M, ClusterIDMapType &ClusterIDMap,
// At this point module should have the proper mix of globals and locals.
// As we attempt to partition this module, we must not change any
// locals to globals.
-
DEBUG(dbgs() << "Partition module with (" << M->size() << ")functions\n");
ClusterMapType GVtoClusterMap;
ComdatMembersType ComdatMembers;
@@ -95,23 +113,17 @@ static void findPartitions(Module *M, ClusterIDMapType &ClusterIDMap,
GVtoClusterMap.unionSets(&GV, Base);
}
- // Further only iterate over local GVs.
- if (!GV.hasLocalLinkage())
- return;
-
- for (auto *U : GV.users()) {
- SmallVector<const User *, 4> Worklist;
- Worklist.push_back(U);
- while (!Worklist.empty()) {
- const User *UU = Worklist.pop_back_val();
- // For each constant that is not a GV (a pure const) recurse.
- if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
- Worklist.append(UU->user_begin(), UU->user_end());
+ if (const Function *F = dyn_cast<Function>(&GV)) {
+ for (const BasicBlock &BB : *F) {
+ BlockAddress *BA = BlockAddress::lookup(&BB);
+ if (!BA || !BA->isConstantUsed())
continue;
- }
- addNonConstUser(GVtoClusterMap, &GV, UU);
+ addAllGlobalValueUsers(GVtoClusterMap, F, BA);
}
}
+
+ if (GV.hasLocalLinkage())
+ addAllGlobalValueUsers(GVtoClusterMap, &GV, &GV);
};
std::for_each(M->begin(), M->end(), recordGVSet);
@@ -225,37 +237,26 @@ void llvm::SplitModule(
externalize(&GV);
for (GlobalAlias &GA : M->aliases())
externalize(&GA);
+ }
- // FIXME: We should be able to reuse M as the last partition instead of
- // cloning it.
- for (unsigned I = 0; I != N; ++I) {
- ValueToValueMapTy VMap;
- std::unique_ptr<Module> MPart(
- CloneModule(M.get(), VMap, [=](const GlobalValue *GV) {
- return isInPartition(GV, I, N);
- }));
- if (I != 0)
- MPart->setModuleInlineAsm("");
- ModuleCallback(std::move(MPart));
- }
- } else {
- // This performs splitting without a need for externalization, which might not
- // always be possible.
- ClusterIDMapType ClusterIDMap;
- findPartitions(M.get(), ClusterIDMap, N);
+ // This performs splitting without a need for externalization, which might not
+ // always be possible.
+ ClusterIDMapType ClusterIDMap;
+ findPartitions(M.get(), ClusterIDMap, N);
- for (unsigned I = 0; I < N; ++I) {
- ValueToValueMapTy VMap;
- std::unique_ptr<Module> MPart(
- CloneModule(M.get(), VMap, [&](const GlobalValue *GV) {
- if (ClusterIDMap.count(GV))
- return (ClusterIDMap[GV] == I);
- else
- return isInPartition(GV, I, N);
- }));
- if (I != 0)
- MPart->setModuleInlineAsm("");
- ModuleCallback(std::move(MPart));
- }
+ // FIXME: We should be able to reuse M as the last partition instead of
+ // cloning it.
+ for (unsigned I = 0; I < N; ++I) {
+ ValueToValueMapTy VMap;
+ std::unique_ptr<Module> MPart(
+ CloneModule(M.get(), VMap, [&](const GlobalValue *GV) {
+ if (ClusterIDMap.count(GV))
+ return (ClusterIDMap[GV] == I);
+ else
+ return isInPartition(GV, I, N);
+ }));
+ if (I != 0)
+ MPart->setModuleInlineAsm("");
+ ModuleCallback(std::move(MPart));
}
}