[llvm] r245662 - TransformUtils: Introduce module splitter.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 23:15:11 PDT 2015


I haven't had a chance to have a good look yet (hopefully tomorrow), but at
first glance this looks really useful: I think it could replace some of the
quick-and-dirty partitioning stuff I wrote for Orc.

Very cool!

- Lang.


On Thu, Aug 20, 2015 at 10:15 PM, Eric Christopher <echristo at gmail.com>
wrote:

> From a quick glance... would this be useful with the on demand compilation
> stuff that Lang wrote for ORC? I know he splits up modules as well.
>
> -eric
>
>
> On Thu, Aug 20, 2015 at 7:49 PM 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
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150820/92272eb9/attachment.html>


More information about the llvm-commits mailing list