Skip to content

Commit 020d4fb

Browse files
committed
New bitcode linker flags:
-only-needed -- link in only symbols needed by destination module -internalize -- internalize linked symbols Differential Revision: http://reviews.llvm.org/D12459 llvm-svn: 246561
1 parent 6194363 commit 020d4fb

File tree

5 files changed

+91
-20
lines changed

5 files changed

+91
-20
lines changed

llvm/include/llvm/Linker/Linker.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ class Linker {
6060
bool hasType(StructType *Ty);
6161
};
6262

63+
enum Flags {
64+
None = 0,
65+
OverrideFromSrc = (1 << 0),
66+
LinkOnlyNeeded = (1 << 1),
67+
InternalizeLinkedSymbols = (1 << 2)
68+
};
69+
6370
Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler);
6471
Linker(Module *M);
6572

@@ -70,15 +77,17 @@ class Linker {
7077
/// Passing OverrideSymbols as true will have symbols from Src
7178
/// shadow those in the Dest.
7279
/// Returns true on error.
73-
bool linkInModule(Module *Src, bool OverrideSymbols = false);
80+
bool linkInModule(Module *Src, unsigned Flags = Flags::None);
7481

7582
/// \brief Set the composite to the passed-in module.
7683
void setModule(Module *Dst);
7784

7885
static bool LinkModules(Module *Dest, Module *Src,
79-
DiagnosticHandlerFunction DiagnosticHandler);
86+
DiagnosticHandlerFunction DiagnosticHandler,
87+
unsigned Flags = Flags::None);
8088

81-
static bool LinkModules(Module *Dest, Module *Src);
89+
static bool LinkModules(Module *Dest, Module *Src,
90+
unsigned Flags = Flags::None);
8291

8392
private:
8493
void init(Module *M, DiagnosticHandlerFunction DiagnosticHandler);

llvm/lib/Linker/LinkModules.cpp

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -425,19 +425,23 @@ class ModuleLinker {
425425
DiagnosticHandlerFunction DiagnosticHandler;
426426

427427
/// For symbol clashes, prefer those from Src.
428-
bool OverrideFromSrc;
428+
unsigned Flags;
429429

430430
public:
431431
ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM,
432-
DiagnosticHandlerFunction DiagnosticHandler,
433-
bool OverrideFromSrc)
432+
DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags)
434433
: DstM(dstM), SrcM(srcM), TypeMap(Set),
435434
ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues),
436-
DiagnosticHandler(DiagnosticHandler), OverrideFromSrc(OverrideFromSrc) {
437-
}
435+
DiagnosticHandler(DiagnosticHandler), Flags(Flags) {}
438436

439437
bool run();
440438

439+
bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; }
440+
bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; }
441+
bool shouldInternalizeLinkedSymbols() {
442+
return Flags & Linker::InternalizeLinkedSymbols;
443+
}
444+
441445
private:
442446
bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest,
443447
const GlobalValue &Src);
@@ -730,7 +734,7 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
730734
const GlobalValue &Dest,
731735
const GlobalValue &Src) {
732736
// Should we unconditionally use the Src?
733-
if (OverrideFromSrc) {
737+
if (shouldOverrideFromSrc()) {
734738
LinkFromSrc = true;
735739
return false;
736740
}
@@ -1081,13 +1085,20 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
10811085
} else {
10821086
// If the GV is to be lazily linked, don't create it just yet.
10831087
// The ValueMaterializerTy will deal with creating it if it's used.
1084-
if (!DGV && !OverrideFromSrc &&
1088+
if (!DGV && !shouldOverrideFromSrc() &&
10851089
(SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() ||
10861090
SGV->hasAvailableExternallyLinkage())) {
10871091
DoNotLinkFromSource.insert(SGV);
10881092
return false;
10891093
}
10901094

1095+
// When we only want to link in unresolved dependencies, blacklist
1096+
// the symbol unless unless DestM has a matching declaration (DGV).
1097+
if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) {
1098+
DoNotLinkFromSource.insert(SGV);
1099+
return false;
1100+
}
1101+
10911102
NewGV = copyGlobalValueProto(TypeMap, *DstM, SGV);
10921103

10931104
if (DGV && isa<Function>(DGV))
@@ -1249,6 +1260,9 @@ void ModuleLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) {
12491260
bool ModuleLinker::linkGlobalValueBody(GlobalValue &Src) {
12501261
Value *Dst = ValueMap[&Src];
12511262
assert(Dst);
1263+
if (shouldInternalizeLinkedSymbols())
1264+
if (auto *DGV = dyn_cast<GlobalValue>(Dst))
1265+
DGV->setLinkage(GlobalValue::InternalLinkage);
12521266
if (auto *F = dyn_cast<Function>(&Src))
12531267
return linkFunctionBody(cast<Function>(*Dst), *F);
12541268
if (auto *GVar = dyn_cast<GlobalVariable>(&Src)) {
@@ -1632,6 +1646,11 @@ bool ModuleLinker::run() {
16321646
GlobalValue *SGV = LazilyLinkGlobalValues.back();
16331647
LazilyLinkGlobalValues.pop_back();
16341648

1649+
// Skip declarations that ValueMaterializer may have created in
1650+
// case we link in only some of SrcM.
1651+
if (shouldLinkOnlyNeeded() && SGV->isDeclaration())
1652+
continue;
1653+
16351654
assert(!SGV->isDeclaration() && "users should not pass down decls");
16361655
if (linkGlobalValueBody(*SGV))
16371656
return true;
@@ -1759,9 +1778,9 @@ void Linker::deleteModule() {
17591778
Composite = nullptr;
17601779
}
17611780

1762-
bool Linker::linkInModule(Module *Src, bool OverrideSymbols) {
1781+
bool Linker::linkInModule(Module *Src, unsigned Flags) {
17631782
ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src,
1764-
DiagnosticHandler, OverrideSymbols);
1783+
DiagnosticHandler, Flags);
17651784
bool RetCode = TheLinker.run();
17661785
Composite->dropTriviallyDeadConstantArrays();
17671786
return RetCode;
@@ -1781,14 +1800,15 @@ void Linker::setModule(Module *Dst) {
17811800
/// Upon failure, the Dest module could be in a modified state, and shouldn't be
17821801
/// relied on to be consistent.
17831802
bool Linker::LinkModules(Module *Dest, Module *Src,
1784-
DiagnosticHandlerFunction DiagnosticHandler) {
1803+
DiagnosticHandlerFunction DiagnosticHandler,
1804+
unsigned Flags) {
17851805
Linker L(Dest, DiagnosticHandler);
1786-
return L.linkInModule(Src);
1806+
return L.linkInModule(Src, Flags);
17871807
}
17881808

1789-
bool Linker::LinkModules(Module *Dest, Module *Src) {
1809+
bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Flags) {
17901810
Linker L(Dest);
1791-
return L.linkInModule(Src);
1811+
return L.linkInModule(Src, Flags);
17921812
}
17931813

17941814
//===----------------------------------------------------------------------===//

llvm/test/Linker/Inputs/linkage.c.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@X = global i32 5
2+
@U = global i32 6
3+
define i32 @foo() { ret i32 7 }
4+
define i32 @unused() { ret i32 8 }

llvm/test/Linker/link-flags.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: llvm-as %S/Inputs/linkage.b.ll -o %t.b.bc
2+
; RUN: llvm-as %S/Inputs/linkage.c.ll -o %t.c.bc
3+
; RUN: llvm-link -S %t.b.bc %t.c.bc | FileCheck %s -check-prefix=B -check-prefix=C -check-prefix=CU
4+
; RUN: llvm-link -S -only-needed %t.b.bc %t.c.bc | FileCheck %s -check-prefix=B -check-prefix=C -check-prefix=CN
5+
; RUN: llvm-link -S -internalize %t.b.bc %t.c.bc | FileCheck %s -check-prefix=B -check-prefix=CI
6+
; RUN: llvm-link -S -internalize -only-needed %t.b.bc %t.c.bc | FileCheck %s -check-prefix=B -check-prefix=CN
7+
8+
C-LABEL: @X = global i32 5
9+
CI-LABEL: @X = internal global i32 5
10+
CU-LABEL:@U = global i32 6
11+
CI-LABEL:@U = internal global i32 6
12+
CN-LABEL-NOT:@U
13+
14+
B-LABEL: define void @bar() {
15+
16+
C-LABEL: define i32 @foo()
17+
CI-LABEL: define internal i32 @foo()
18+
19+
CU-LABEL:define i32 @unused() {
20+
CI-LABEL:define internal i32 @unused() {
21+
CN-LABEL-NOT:@unused()

llvm/tools/llvm-link/llvm-link.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ static cl::opt<std::string>
4747
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
4848
cl::value_desc("filename"));
4949

50+
static cl::opt<bool>
51+
Internalize("internalize", cl::desc("Internalize linked symbols"));
52+
53+
static cl::opt<bool>
54+
OnlyNeeded("only-needed", cl::desc("Link only needed symbols"));
55+
5056
static cl::opt<bool>
5157
Force("f", cl::desc("Enable binary output on terminals"));
5258

@@ -114,7 +120,9 @@ static void diagnosticHandler(const DiagnosticInfo &DI) {
114120

115121
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
116122
const cl::list<std::string> &Files,
117-
bool OverrideDuplicateSymbols) {
123+
unsigned Flags) {
124+
// Filter out flags that don't apply to the first file we load.
125+
unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc;
118126
for (const auto &File : Files) {
119127
std::unique_ptr<Module> M = loadFile(argv0, File, Context);
120128
if (!M.get()) {
@@ -130,8 +138,10 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
130138
if (Verbose)
131139
errs() << "Linking in '" << File << "'\n";
132140

133-
if (L.linkInModule(M.get(), OverrideDuplicateSymbols))
141+
if (L.linkInModule(M.get(), ApplicableFlags))
134142
return false;
143+
// All linker flags apply to linking of subsequent files.
144+
ApplicableFlags = Flags;
135145
}
136146

137147
return true;
@@ -149,12 +159,19 @@ int main(int argc, char **argv) {
149159
auto Composite = make_unique<Module>("llvm-link", Context);
150160
Linker L(Composite.get(), diagnosticHandler);
151161

162+
unsigned Flags = Linker::Flags::None;
163+
if (Internalize)
164+
Flags |= Linker::Flags::InternalizeLinkedSymbols;
165+
if (OnlyNeeded)
166+
Flags |= Linker::Flags::LinkOnlyNeeded;
167+
152168
// First add all the regular input files
153-
if (!linkFiles(argv[0], Context, L, InputFilenames, false))
169+
if (!linkFiles(argv[0], Context, L, InputFilenames, Flags))
154170
return 1;
155171

156172
// Next the -override ones.
157-
if (!linkFiles(argv[0], Context, L, OverridingInputs, true))
173+
if (!linkFiles(argv[0], Context, L, OverridingInputs,
174+
Flags | Linker::Flags::OverrideFromSrc))
158175
return 1;
159176

160177
if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;

0 commit comments

Comments
 (0)