[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