[llvm] r245662 - TransformUtils: Introduce module splitter.

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 06:22:43 PDT 2015


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


More information about the llvm-commits mailing list