<div dir="ltr">From a quick glance... would this be useful with the on demand compilation stuff that Lang wrote for ORC? I know he splits up modules as well.<div><br></div><div>-eric<br><br><div class="gmail_quote"><div dir="ltr">On Thu, Aug 20, 2015 at 7:49 PM Peter Collingbourne via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: pcc<br>
Date: Thu Aug 20 21:48:20 2015<br>
New Revision: 245662<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=245662&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=245662&view=rev</a><br>
Log:<br>
TransformUtils: Introduce module splitter.<br>
<br>
The module splitter splits a module into linkable partitions. It will<br>
be used to implement parallel LTO code generation.<br>
<br>
This initial version of the splitter does not attempt to deal with the<br>
somewhat subtle symbol visibility issues around module splitting. These<br>
will be dealt with in a future change.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D12132" rel="noreferrer" target="_blank">http://reviews.llvm.org/D12132</a><br>
<br>
Added:<br>
llvm/trunk/include/llvm/Transforms/Utils/SplitModule.h<br>
llvm/trunk/lib/Transforms/Utils/SplitModule.cpp<br>
llvm/trunk/test/tools/llvm-split/<br>
llvm/trunk/test/tools/llvm-split/alias.ll<br>
llvm/trunk/test/tools/llvm-split/comdat.ll<br>
llvm/trunk/test/tools/llvm-split/function.ll<br>
llvm/trunk/test/tools/llvm-split/global.ll<br>
llvm/trunk/test/tools/llvm-split/internal.ll<br>
llvm/trunk/test/tools/llvm-split/unnamed.ll<br>
llvm/trunk/tools/llvm-split/<br>
llvm/trunk/tools/llvm-split/CMakeLists.txt<br>
llvm/trunk/tools/llvm-split/LLVMBuild.txt<br>
- copied, changed from r245661, llvm/trunk/tools/LLVMBuild.txt<br>
llvm/trunk/tools/llvm-split/Makefile<br>
llvm/trunk/tools/llvm-split/llvm-split.cpp<br>
Modified:<br>
llvm/trunk/include/llvm/Transforms/Utils/Cloning.h<br>
llvm/trunk/lib/Transforms/Utils/CMakeLists.txt<br>
llvm/trunk/lib/Transforms/Utils/CloneModule.cpp<br>
llvm/trunk/test/CMakeLists.txt<br>
llvm/trunk/test/lit.cfg<br>
llvm/trunk/tools/LLVMBuild.txt<br>
llvm/trunk/tools/Makefile<br>
<br>
Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=245662&r1=245661&r2=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=245662&r1=245661&r2=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original)<br>
+++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Thu Aug 20 21:48:20 2015<br>
@@ -23,6 +23,7 @@<br>
#include "llvm/IR/ValueHandle.h"<br>
#include "llvm/IR/ValueMap.h"<br>
#include "llvm/Transforms/Utils/ValueMapper.h"<br>
+#include <functional><br>
<br>
namespace llvm {<br>
<br>
@@ -52,6 +53,14 @@ class DominatorTree;<br>
Module *CloneModule(const Module *M);<br>
Module *CloneModule(const Module *M, ValueToValueMapTy &VMap);<br>
<br>
+/// Return a copy of the specified module. The ShouldCloneDefinition function<br>
+/// controls whether a specific GlobalValue's definition is cloned. If the<br>
+/// function returns false, the module copy will contain an external reference<br>
+/// in place of the global definition.<br>
+Module *<br>
+CloneModule(const Module *M, ValueToValueMapTy &VMap,<br>
+ std::function<bool(const GlobalValue *)> ShouldCloneDefinition);<br>
+<br>
/// ClonedCodeInfo - This struct can be used to capture information about code<br>
/// being cloned, while it is being cloned.<br>
struct ClonedCodeInfo {<br>
<br>
Added: llvm/trunk/include/llvm/Transforms/Utils/SplitModule.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SplitModule.h?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SplitModule.h?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/Utils/SplitModule.h (added)<br>
+++ llvm/trunk/include/llvm/Transforms/Utils/SplitModule.h Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,43 @@<br>
+//===- SplitModule.h - Split a module into partitions -----------*- C++ -*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines the function llvm::SplitModule, which splits a module<br>
+// into multiple linkable partitions. It can be used to implement parallel code<br>
+// generation for link-time optimization.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_TRANSFORMS_UTILS_SPLITMODULE_H<br>
+#define LLVM_TRANSFORMS_UTILS_SPLITMODULE_H<br>
+<br>
+#include <functional><br>
+#include <memory><br>
+<br>
+namespace llvm {<br>
+<br>
+class Module;<br>
+class StringRef;<br>
+<br>
+/// Splits the module M into N linkable partitions. The function ModuleCallback<br>
+/// is called N times passing each individual partition as the MPart argument.<br>
+///<br>
+/// FIXME: This function does not deal with the somewhat subtle symbol<br>
+/// visibility issues around module splitting, including (but not limited to):<br>
+///<br>
+/// - Internal symbols should not collide with symbols defined outside the<br>
+/// module.<br>
+/// - Internal symbols defined in module-level inline asm should be visible to<br>
+/// each partition.<br>
+void SplitModule(<br>
+ std::unique_ptr<Module> M, unsigned N,<br>
+ std::function<void(std::unique_ptr<Module> MPart)> ModuleCallback);<br>
+<br>
+} // End llvm namespace<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=245662&r1=245661&r2=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=245662&r1=245661&r2=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Thu Aug 20 21:48:20 2015<br>
@@ -34,6 +34,7 @@ add_llvm_library(LLVMTransformUtils<br>
SimplifyIndVar.cpp<br>
SimplifyInstructions.cpp<br>
SimplifyLibCalls.cpp<br>
+ SplitModule.cpp<br>
SymbolRewriter.cpp<br>
UnifyFunctionExitNodes.cpp<br>
Utils.cpp<br>
<br>
Modified: llvm/trunk/lib/Transforms/Utils/CloneModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneModule.cpp?rev=245662&r1=245661&r2=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneModule.cpp?rev=245662&r1=245661&r2=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Utils/CloneModule.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Utils/CloneModule.cpp Thu Aug 20 21:48:20 2015<br>
@@ -33,6 +33,12 @@ Module *llvm::CloneModule(const Module *<br>
}<br>
<br>
Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {<br>
+ return CloneModule(M, VMap, [](const GlobalValue *GV) { return true; });<br>
+}<br>
+<br>
+Module *llvm::CloneModule(<br>
+ const Module *M, ValueToValueMapTy &VMap,<br>
+ std::function<bool(const GlobalValue *)> ShouldCloneDefinition) {<br>
// First off, we need to create the new module.<br>
Module *New = new Module(M->getModuleIdentifier(), M->getContext());<br>
New->setDataLayout(M->getDataLayout());<br>
@@ -68,6 +74,26 @@ Module *llvm::CloneModule(const Module *<br>
// Loop over the aliases in the module<br>
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();<br>
I != E; ++I) {<br>
+ if (!ShouldCloneDefinition(I)) {<br>
+ // An alias cannot act as an external reference, so we need to create<br>
+ // either a function or a global variable depending on the value type.<br>
+ // FIXME: Once pointee types are gone we can probably pick one or the<br>
+ // other.<br>
+ GlobalValue *GV;<br>
+ if (I->getValueType()->isFunctionTy())<br>
+ GV = Function::Create(cast<FunctionType>(I->getValueType()),<br>
+ GlobalValue::ExternalLinkage, I->getName(), New);<br>
+ else<br>
+ GV = new GlobalVariable(<br>
+ *New, I->getValueType(), false, GlobalValue::ExternalLinkage,<br>
+ (Constant *)nullptr, I->getName(), (GlobalVariable *)nullptr,<br>
+ I->getThreadLocalMode(), I->getType()->getAddressSpace());<br>
+ VMap[I] = GV;<br>
+ // We do not copy attributes (mainly because copying between different<br>
+ // kinds of globals is forbidden), but this is generally not required for<br>
+ // correctness.<br>
+ continue;<br>
+ }<br>
auto *PTy = cast<PointerType>(I->getType());<br>
auto *GA = GlobalAlias::create(PTy, I->getLinkage(), I->getName(), New);<br>
GA->copyAttributesFrom(I);<br>
@@ -81,6 +107,11 @@ Module *llvm::CloneModule(const Module *<br>
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();<br>
I != E; ++I) {<br>
GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);<br>
+ if (!ShouldCloneDefinition(I)) {<br>
+ // Skip after setting the correct linkage for an external reference.<br>
+ GV->setLinkage(GlobalValue::ExternalLinkage);<br>
+ continue;<br>
+ }<br>
if (I->hasInitializer())<br>
GV->setInitializer(MapValue(I->getInitializer(), VMap));<br>
}<br>
@@ -89,6 +120,11 @@ Module *llvm::CloneModule(const Module *<br>
//<br>
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {<br>
Function *F = cast<Function>(VMap[I]);<br>
+ if (!ShouldCloneDefinition(I)) {<br>
+ // Skip after setting the correct linkage for an external reference.<br>
+ F->setLinkage(GlobalValue::ExternalLinkage);<br>
+ continue;<br>
+ }<br>
if (!I->isDeclaration()) {<br>
Function::arg_iterator DestI = F->arg_begin();<br>
for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();<br>
@@ -109,6 +145,9 @@ Module *llvm::CloneModule(const Module *<br>
// And aliases<br>
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();<br>
I != E; ++I) {<br>
+ // We already dealt with undefined aliases above.<br>
+ if (!ShouldCloneDefinition(I))<br>
+ continue;<br>
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);<br>
if (const Constant *C = I->getAliasee())<br>
GA->setAliasee(MapValue(C, VMap));<br>
<br>
Added: llvm/trunk/lib/Transforms/Utils/SplitModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SplitModule.cpp?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SplitModule.cpp?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Utils/SplitModule.cpp (added)<br>
+++ llvm/trunk/lib/Transforms/Utils/SplitModule.cpp Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,85 @@<br>
+//===- SplitModule.cpp - Split a module into partitions -------------------===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines the function llvm::SplitModule, which splits a module<br>
+// into multiple linkable partitions. It can be used to implement parallel code<br>
+// generation for link-time optimization.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/Transforms/Utils/SplitModule.h"<br>
+#include "llvm/ADT/Hashing.h"<br>
+#include "llvm/IR/Function.h"<br>
+#include "llvm/IR/GlobalAlias.h"<br>
+#include "llvm/IR/GlobalObject.h"<br>
+#include "llvm/IR/GlobalValue.h"<br>
+#include "llvm/IR/Module.h"<br>
+#include "llvm/Support/MD5.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include "llvm/Transforms/Utils/Cloning.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+static void externalize(GlobalValue *GV) {<br>
+ if (GV->hasLocalLinkage()) {<br>
+ GV->setLinkage(GlobalValue::ExternalLinkage);<br>
+ GV->setVisibility(GlobalValue::HiddenVisibility);<br>
+ }<br>
+<br>
+ // Unnamed entities must be named consistently between modules. setName will<br>
+ // give a distinct name to each such entity.<br>
+ if (!GV->hasName())<br>
+ GV->setName("__llvmsplit_unnamed");<br>
+}<br>
+<br>
+// Returns whether GV should be in partition (0-based) I of N.<br>
+static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) {<br>
+ if (auto GA = dyn_cast<GlobalAlias>(GV))<br>
+ if (const GlobalObject *Base = GA->getBaseObject())<br>
+ GV = Base;<br>
+<br>
+ StringRef Name;<br>
+ if (const Comdat *C = GV->getComdat())<br>
+ Name = C->getName();<br>
+ else<br>
+ Name = GV->getName();<br>
+<br>
+ // Partition by MD5 hash. We only need a few bits for evenness as the number<br>
+ // of partitions will generally be in the 1-2 figure range; the low 16 bits<br>
+ // are enough.<br>
+ MD5 H;<br>
+ MD5::MD5Result R;<br>
+ H.update(Name);<br>
+ H.final(R);<br>
+ return (R[0] | (R[1] << 8)) % N == I;<br>
+}<br>
+<br>
+void llvm::SplitModule(<br>
+ std::unique_ptr<Module> M, unsigned N,<br>
+ std::function<void(std::unique_ptr<Module> MPart)> ModuleCallback) {<br>
+ for (Function &F : *M)<br>
+ externalize(&F);<br>
+ for (GlobalVariable &GV : M->globals())<br>
+ externalize(&GV);<br>
+ for (GlobalAlias &GA : M->aliases())<br>
+ externalize(&GA);<br>
+<br>
+ // FIXME: We should be able to reuse M as the last partition instead of<br>
+ // cloning it.<br>
+ for (unsigned I = 0; I != N; ++I) {<br>
+ ValueToValueMapTy VMap;<br>
+ std::unique_ptr<Module> MPart(<br>
+ CloneModule(M.get(), VMap, [=](const GlobalValue *GV) {<br>
+ return isInPartition(GV, I, N);<br>
+ }));<br>
+ if (I != 0)<br>
+ MPart->setModuleInlineAsm("");<br>
+ ModuleCallback(std::move(MPart));<br>
+ }<br>
+}<br>
<br>
Modified: llvm/trunk/test/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=245662&r1=245661&r2=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=245662&r1=245661&r2=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CMakeLists.txt (original)<br>
+++ llvm/trunk/test/CMakeLists.txt Thu Aug 20 21:48:20 2015<br>
@@ -46,6 +46,7 @@ set(LLVM_TEST_DEPENDS<br>
llvm-readobj<br>
llvm-rtdyld<br>
llvm-size<br>
+ llvm-split<br>
llvm-symbolizer<br>
llvm-tblgen<br>
macho-dump<br>
<br>
Modified: llvm/trunk/test/lit.cfg<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=245662&r1=245661&r2=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=245662&r1=245661&r2=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/lit.cfg (original)<br>
+++ llvm/trunk/test/lit.cfg Thu Aug 20 21:48:20 2015<br>
@@ -248,6 +248,7 @@ for pattern in [r"\bbugpoint\b(?!-)",<br>
r"\bllvm-readobj\b",<br>
r"\bllvm-rtdyld\b",<br>
r"\bllvm-size\b",<br>
+ r"\bllvm-split\b",<br>
r"\bllvm-tblgen\b",<br>
r"\bllvm-c-test\b",<br>
r"\bmacho-dump\b",<br>
<br>
Added: llvm/trunk/test/tools/llvm-split/alias.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/alias.ll?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/alias.ll?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-split/alias.ll (added)<br>
+++ llvm/trunk/test/tools/llvm-split/alias.ll Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,19 @@<br>
+; RUN: llvm-split -o %t %s<br>
+; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s<br>
+; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s<br>
+<br>
+; CHECK0-DAG: @afoo = alias [2 x i8*]* @foo<br>
+; CHECK1-DAG: @afoo = external global [2 x i8*]<br>
+@afoo = alias [2 x i8*]* @foo<br>
+<br>
+; CHECK0-DAG: declare void @abar()<br>
+; CHECK1-DAG: @abar = alias void ()* @bar<br>
+@abar = alias void ()* @bar<br>
+<br>
+@foo = global [2 x i8*] [i8* bitcast (void ()* @bar to i8*), i8* bitcast (void ()* @abar to i8*)]<br>
+<br>
+define void @bar() {<br>
+ store [2 x i8*] zeroinitializer, [2 x i8*]* @foo<br>
+ store [2 x i8*] zeroinitializer, [2 x i8*]* @afoo<br>
+ ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/llvm-split/comdat.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/comdat.ll?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/comdat.ll?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-split/comdat.ll (added)<br>
+++ llvm/trunk/test/tools/llvm-split/comdat.ll Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,19 @@<br>
+; RUN: llvm-split -o %t %s<br>
+; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s<br>
+; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s<br>
+<br>
+$foo = comdat any<br>
+<br>
+; CHECK0: define void @foo()<br>
+; CHECK1: declare void @foo()<br>
+define void @foo() comdat {<br>
+ call void @bar()<br>
+ ret void<br>
+}<br>
+<br>
+; CHECK0: define void @bar()<br>
+; CHECK1: declare void @bar()<br>
+define void @bar() comdat($foo) {<br>
+ call void @foo()<br>
+ ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/llvm-split/function.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/function.ll?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/function.ll?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-split/function.ll (added)<br>
+++ llvm/trunk/test/tools/llvm-split/function.ll Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,17 @@<br>
+; RUN: llvm-split -o %t %s<br>
+; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s<br>
+; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s<br>
+<br>
+; CHECK0: define void @foo()<br>
+; CHECK1: declare void @foo()<br>
+define void @foo() {<br>
+ call void @bar()<br>
+ ret void<br>
+}<br>
+<br>
+; CHECK0: declare void @bar()<br>
+; CHECK1: define void @bar()<br>
+define void @bar() {<br>
+ call void @foo()<br>
+ ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/llvm-split/global.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/global.ll?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/global.ll?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-split/global.ll (added)<br>
+++ llvm/trunk/test/tools/llvm-split/global.ll Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,11 @@<br>
+; RUN: llvm-split -o %t %s<br>
+; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s<br>
+; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s<br>
+<br>
+; CHECK0: @foo = global i8* bitcast<br>
+; CHECK1: @foo = external global i8*<br>
+@foo = global i8* bitcast (i8** @bar to i8*)<br>
+<br>
+; CHECK0: @bar = external global i8*<br>
+; CHECK1: @bar = global i8* bitcast<br>
+@bar = global i8* bitcast (i8** @foo to i8*)<br>
<br>
Added: llvm/trunk/test/tools/llvm-split/internal.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/internal.ll?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/internal.ll?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-split/internal.ll (added)<br>
+++ llvm/trunk/test/tools/llvm-split/internal.ll Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,17 @@<br>
+; RUN: llvm-split -o %t %s<br>
+; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s<br>
+; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s<br>
+<br>
+; CHECK0: define hidden void @foo()<br>
+; CHECK1: declare hidden void @foo()<br>
+define internal void @foo() {<br>
+ call void @bar()<br>
+ ret void<br>
+}<br>
+<br>
+; CHECK0: declare void @bar()<br>
+; CHECK1: define void @bar()<br>
+define void @bar() {<br>
+ call void @foo()<br>
+ ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/tools/llvm-split/unnamed.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/unnamed.ll?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-split/unnamed.ll?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-split/unnamed.ll (added)<br>
+++ llvm/trunk/test/tools/llvm-split/unnamed.ll Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,31 @@<br>
+; RUN: llvm-split -o %t %s<br>
+; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s<br>
+; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s<br>
+<br>
+; CHECK0: declare hidden void @__llvmsplit_unnamed()<br>
+; CHECK1: define hidden void @__llvmsplit_unnamed()<br>
+define internal void @0() {<br>
+ ; CHECK1: call void @foo()<br>
+ call void @foo()<br>
+ ret void<br>
+}<br>
+<br>
+; CHECK0: declare hidden void @__llvmsplit_unnamed1()<br>
+; CHECK1: define hidden void @__llvmsplit_unnamed1()<br>
+define internal void @1() {<br>
+ ; CHECK1: call void @foo()<br>
+ ; CHECK1: call void @foo()<br>
+ call void @foo()<br>
+ call void @foo()<br>
+ ret void<br>
+}<br>
+<br>
+; CHECK0: define void @foo()<br>
+; CHECK1: declare void @foo()<br>
+define void @foo() {<br>
+ ; CHECK0: call void @__llvmsplit_unnamed1()<br>
+ ; CHECK0: call void @__llvmsplit_unnamed()<br>
+ call void @1()<br>
+ call void @0()<br>
+ ret void<br>
+}<br>
<br>
Modified: llvm/trunk/tools/LLVMBuild.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/LLVMBuild.txt?rev=245662&r1=245661&r2=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/LLVMBuild.txt?rev=245662&r1=245661&r2=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/LLVMBuild.txt (original)<br>
+++ llvm/trunk/tools/LLVMBuild.txt Thu Aug 20 21:48:20 2015<br>
@@ -40,6 +40,7 @@ subdirectories =<br>
llvm-profdata<br>
llvm-rtdyld<br>
llvm-size<br>
+ llvm-split<br>
macho-dump<br>
opt<br>
verify-uselistorder<br>
<br>
Modified: llvm/trunk/tools/Makefile<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=245662&r1=245661&r2=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=245662&r1=245661&r2=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/Makefile (original)<br>
+++ llvm/trunk/tools/Makefile Thu Aug 20 21:48:20 2015<br>
@@ -32,7 +32,8 @@ PARALLEL_DIRS := opt llvm-as llvm-dis ll<br>
macho-dump llvm-objdump llvm-readobj llvm-rtdyld \<br>
llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \<br>
llvm-profdata llvm-symbolizer obj2yaml yaml2obj llvm-c-test \<br>
- llvm-cxxdump verify-uselistorder dsymutil llvm-pdbdump<br>
+ llvm-cxxdump verify-uselistorder dsymutil llvm-pdbdump \<br>
+ llvm-split<br>
<br>
# If Intel JIT Events support is configured, build an extra tool to test it.<br>
ifeq ($(USE_INTEL_JITEVENTS), 1)<br>
<br>
Added: llvm/trunk/tools/llvm-split/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/CMakeLists.txt?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/CMakeLists.txt?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-split/CMakeLists.txt (added)<br>
+++ llvm/trunk/tools/llvm-split/CMakeLists.txt Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,11 @@<br>
+set(LLVM_LINK_COMPONENTS<br>
+ TransformUtils<br>
+ BitWriter<br>
+ Core<br>
+ IRReader<br>
+ Support<br>
+ )<br>
+<br>
+add_llvm_tool(llvm-split<br>
+ llvm-split.cpp<br>
+ )<br>
<br>
Copied: llvm/trunk/tools/llvm-split/LLVMBuild.txt (from r245661, llvm/trunk/tools/LLVMBuild.txt)<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/LLVMBuild.txt?p2=llvm/trunk/tools/llvm-split/LLVMBuild.txt&p1=llvm/trunk/tools/LLVMBuild.txt&r1=245661&r2=245662&rev=245662&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/LLVMBuild.txt?p2=llvm/trunk/tools/llvm-split/LLVMBuild.txt&p1=llvm/trunk/tools/LLVMBuild.txt&r1=245661&r2=245662&rev=245662&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/LLVMBuild.txt (original)<br>
+++ llvm/trunk/tools/llvm-split/LLVMBuild.txt Thu Aug 20 21:48:20 2015<br>
@@ -1,4 +1,4 @@<br>
-;===- ./tools/LLVMBuild.txt ------------------------------------*- Conf -*--===;<br>
+;===- ./tools/llvm-split/LLVMBuild.txt -------------------------*- Conf -*--===;<br>
;<br>
; The LLVM Compiler Infrastructure<br>
;<br>
@@ -15,36 +15,8 @@<br>
;<br>
;===------------------------------------------------------------------------===;<br>
<br>
-[common]<br>
-subdirectories =<br>
- bugpoint<br>
- dsymutil<br>
- llc<br>
- lli<br>
- llvm-ar<br>
- llvm-as<br>
- llvm-bcanalyzer<br>
- llvm-cov<br>
- llvm-diff<br>
- llvm-dis<br>
- llvm-dwarfdump<br>
- llvm-extract<br>
- llvm-jitlistener<br>
- llvm-link<br>
- llvm-lto<br>
- llvm-mc<br>
- llvm-mcmarkup<br>
- llvm-nm<br>
- llvm-objdump<br>
- llvm-pdbdump<br>
- llvm-profdata<br>
- llvm-rtdyld<br>
- llvm-size<br>
- macho-dump<br>
- opt<br>
- verify-uselistorder<br>
-<br>
[component_0]<br>
-type = Group<br>
-name = Tools<br>
-parent = $ROOT<br>
+type = Tool<br>
+name = llvm-split<br>
+parent = Tools<br>
+required_libraries = TransformUtils BitWriter Core IRReader Support<br>
<br>
Added: llvm/trunk/tools/llvm-split/Makefile<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/Makefile?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/Makefile?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-split/Makefile (added)<br>
+++ llvm/trunk/tools/llvm-split/Makefile Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,17 @@<br>
+##===- tools/llvm-split/Makefile ---------------------------*- Makefile -*-===##<br>
+#<br>
+# The LLVM Compiler Infrastructure<br>
+#<br>
+# This file is distributed under the University of Illinois Open Source<br>
+# License. See LICENSE.TXT for details.<br>
+#<br>
+##===----------------------------------------------------------------------===##<br>
+<br>
+LEVEL := ../..<br>
+TOOLNAME := llvm-split<br>
+LINK_COMPONENTS := transformutils bitwriter core irreader support<br>
+<br>
+# This tool has no plugins, optimize startup time.<br>
+TOOL_NO_EXPORTS := 1<br>
+<br>
+include $(LEVEL)/Makefile.common<br>
<br>
Added: llvm/trunk/tools/llvm-split/llvm-split.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/llvm-split.cpp?rev=245662&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-split/llvm-split.cpp?rev=245662&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-split/llvm-split.cpp (added)<br>
+++ llvm/trunk/tools/llvm-split/llvm-split.cpp Thu Aug 20 21:48:20 2015<br>
@@ -0,0 +1,67 @@<br>
+//===-- llvm-split: command line tool for testing module splitter ---------===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This program can be used to test the llvm::SplitModule function.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ADT/StringExtras.h"<br>
+#include "llvm/Bitcode/ReaderWriter.h"<br>
+#include "llvm/IR/LLVMContext.h"<br>
+#include "llvm/IRReader/IRReader.h"<br>
+#include "llvm/Support/CommandLine.h"<br>
+#include "llvm/Support/FileSystem.h"<br>
+#include "llvm/Support/SourceMgr.h"<br>
+#include "llvm/Support/ToolOutputFile.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include "llvm/Transforms/Utils/SplitModule.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+static cl::opt<std::string><br>
+InputFilename(cl::Positional, cl::desc("<input bitcode file>"),<br>
+ cl::init("-"), cl::value_desc("filename"));<br>
+<br>
+static cl::opt<std::string><br>
+OutputFilename("o", cl::desc("Override output filename"),<br>
+ cl::value_desc("filename"));<br>
+<br>
+static cl::opt<unsigned> NumOutputs("j", cl::Prefix, cl::init(2),<br>
+ cl::desc("Number of output files"));<br>
+<br>
+int main(int argc, char **argv) {<br>
+ LLVMContext &Context = getGlobalContext();<br>
+ SMDiagnostic Err;<br>
+ cl::ParseCommandLineOptions(argc, argv, "LLVM module splitter\n");<br>
+<br>
+ std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);<br>
+<br>
+ if (!M) {<br>
+ Err.print(argv[0], errs());<br>
+ return 1;<br>
+ }<br>
+<br>
+ unsigned I = 0;<br>
+ SplitModule(std::move(M), NumOutputs, [&](std::unique_ptr<Module> MPart) {<br>
+ std::error_code EC;<br>
+ std::unique_ptr<tool_output_file> Out(new tool_output_file(<br>
+ OutputFilename + utostr(I++), EC, sys::fs::F_None));<br>
+ if (EC) {<br>
+ errs() << EC.message() << '\n';<br>
+ exit(1);<br>
+ }<br>
+<br>
+ WriteBitcodeToFile(MPart.get(), Out->os());<br>
+<br>
+ // Declare success.<br>
+ Out->keep();<br>
+ });<br>
+<br>
+ return 0;<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div>