<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>