[llvm] r245662 - TransformUtils: Introduce module splitter.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 21:55:50 PDT 2015


Hi Peter,

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.

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.

Cheers,
Lang.


On Tue, Aug 25, 2015 at 3:25 PM, Peter Collingbourne via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

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


More information about the llvm-commits mailing list