forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245662 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
19 changed files
with
413 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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*] | ||
@afoo = alias [2 x i8*]* @foo | ||
|
||
; CHECK0-DAG: declare void @abar() | ||
; CHECK1-DAG: @abar = alias void ()* @bar | ||
@abar = alias void ()* @bar | ||
|
||
@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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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* | ||
@foo = global i8* bitcast (i8** @bar to i8*) | ||
|
||
; CHECK0: @bar = external global i8* | ||
; CHECK1: @bar = global i8* bitcast | ||
@bar = global i8* bitcast (i8** @foo to i8*) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ subdirectories = | |
llvm-profdata | ||
llvm-rtdyld | ||
llvm-size | ||
llvm-split | ||
macho-dump | ||
opt | ||
verify-uselistorder | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.