<div dir="ltr">Hi Peter,<div><br></div><div>This is similar to the first version of the module splitter that I wrote for ORC. One of the lessons that came out of that, which may be of interest, was that the |M|*N cost of cloning all the global declarations became significant for some large modules, especially when you're doing all that work up-front (at least in a JIT context). I ended up rewriting the CompileOnDemand class, which does the splitting, to use CloneFunctionInto with a custom ValueMaterializer instead, and to clone partitions on the fly as they were about to be executed.</div><div><br></div><div>We could probably get the best of both worlds and share this functionality if CloneModule took a ValueMaterializer as well as the ShouldClone predicate: ShouldClone would identify the globals that the user wants, and the ValueMaterializer would clone any declarations needed by the bodies/initializers of those globals. </div><div><br></div><div>Cheers,</div><div>Lang.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 25, 2015 at 3:25 PM, Peter Collingbourne via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">It could, but I would also like to write a FilterModule function that takes<br>
a std::function with the same interface as CloneModule, but would modify<br>
the module in place. This could be used by SplitModule to build the last<br>
partition more efficiently, and would be a more natural replacement for<br>
GVExtractorPass and most of the code in llvm-extract.<br>
<br>
Peter<br>
<div class="HOEnZb"><div class="h5"><br>
On Tue, Aug 25, 2015 at 09:22:43AM -0400, Rafael Espíndola wrote:<br>
> Could llvm-extract use the new CloneModule?<br>
><br>
> On 20 August 2015 at 22:48, Peter Collingbourne via llvm-commits<br>
> <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
> > 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">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>
><br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Peter<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">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>
</div></div></blockquote></div><br></div>