[llvm] r245662 - TransformUtils: Introduce module splitter.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 15:25:29 PDT 2015


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


More information about the llvm-commits mailing list