summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/CloneModule.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-08-21 02:48:20 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2015-08-21 02:48:20 +0000
commit1dc6a8d1797086c630de2da3249dbcafb7157e27 (patch)
tree6fe3199373e4518779716bdf20aae61ab1356bd2 /llvm/lib/Transforms/Utils/CloneModule.cpp
parentcf61aae163542877e71c1c193829df0366793d8f (diff)
downloadbcm5719-llvm-1dc6a8d1797086c630de2da3249dbcafb7157e27.tar.gz
bcm5719-llvm-1dc6a8d1797086c630de2da3249dbcafb7157e27.zip
TransformUtils: Introduce module splitter.
The module splitter splits a module into linkable partitions. It will be used to implement parallel LTO code generation. This initial version of the splitter does not attempt to deal with the somewhat subtle symbol visibility issues around module splitting. These will be dealt with in a future change. Differential Revision: http://reviews.llvm.org/D12132 llvm-svn: 245662
Diffstat (limited to 'llvm/lib/Transforms/Utils/CloneModule.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/CloneModule.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/CloneModule.cpp b/llvm/lib/Transforms/Utils/CloneModule.cpp
index 61f1811e7b4..5e7cae5364a 100644
--- a/llvm/lib/Transforms/Utils/CloneModule.cpp
+++ b/llvm/lib/Transforms/Utils/CloneModule.cpp
@@ -33,6 +33,12 @@ Module *llvm::CloneModule(const Module *M) {
}
Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
+ return CloneModule(M, VMap, [](const GlobalValue *GV) { return true; });
+}
+
+Module *llvm::CloneModule(
+ const Module *M, ValueToValueMapTy &VMap,
+ std::function<bool(const GlobalValue *)> ShouldCloneDefinition) {
// First off, we need to create the new module.
Module *New = new Module(M->getModuleIdentifier(), M->getContext());
New->setDataLayout(M->getDataLayout());
@@ -68,6 +74,26 @@ Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
// Loop over the aliases in the module
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
I != E; ++I) {
+ if (!ShouldCloneDefinition(I)) {
+ // An alias cannot act as an external reference, so we need to create
+ // either a function or a global variable depending on the value type.
+ // FIXME: Once pointee types are gone we can probably pick one or the
+ // other.
+ GlobalValue *GV;
+ if (I->getValueType()->isFunctionTy())
+ GV = Function::Create(cast<FunctionType>(I->getValueType()),
+ GlobalValue::ExternalLinkage, I->getName(), New);
+ else
+ GV = new GlobalVariable(
+ *New, I->getValueType(), false, GlobalValue::ExternalLinkage,
+ (Constant *)nullptr, I->getName(), (GlobalVariable *)nullptr,
+ I->getThreadLocalMode(), I->getType()->getAddressSpace());
+ VMap[I] = GV;
+ // We do not copy attributes (mainly because copying between different
+ // kinds of globals is forbidden), but this is generally not required for
+ // correctness.
+ continue;
+ }
auto *PTy = cast<PointerType>(I->getType());
auto *GA = GlobalAlias::create(PTy, I->getLinkage(), I->getName(), New);
GA->copyAttributesFrom(I);
@@ -81,6 +107,11 @@ Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I) {
GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
+ if (!ShouldCloneDefinition(I)) {
+ // Skip after setting the correct linkage for an external reference.
+ GV->setLinkage(GlobalValue::ExternalLinkage);
+ continue;
+ }
if (I->hasInitializer())
GV->setInitializer(MapValue(I->getInitializer(), VMap));
}
@@ -89,6 +120,11 @@ Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
//
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
Function *F = cast<Function>(VMap[I]);
+ if (!ShouldCloneDefinition(I)) {
+ // Skip after setting the correct linkage for an external reference.
+ F->setLinkage(GlobalValue::ExternalLinkage);
+ continue;
+ }
if (!I->isDeclaration()) {
Function::arg_iterator DestI = F->arg_begin();
for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();
@@ -109,6 +145,9 @@ Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
// And aliases
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
I != E; ++I) {
+ // We already dealt with undefined aliases above.
+ if (!ShouldCloneDefinition(I))
+ continue;
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
if (const Constant *C = I->getAliasee())
GA->setAliasee(MapValue(C, VMap));
OpenPOWER on IntegriCloud