Skip to content

Commit df5783b

Browse files
committedAug 28, 2015
COFF: Implement parallel LTO code generation.
This is exposed via a new flag /opt:lldltojobs=N, where N is the number of code generation threads. Differential Revision: http://reviews.llvm.org/D12309 llvm-svn: 246342
1 parent adbcf12 commit df5783b

7 files changed

+89
-37
lines changed
 

‎lld/COFF/Config.h

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ struct Configuration {
9191
// Used for /opt:lldlto=N
9292
unsigned LTOOptLevel = 2;
9393

94+
// Used for /opt:lldltojobs=N
95+
unsigned LTOJobs = 1;
96+
9497
// Used for /merge:from=to (e.g. /merge:.rdata=.text)
9598
std::map<StringRef, StringRef> Merge;
9699

‎lld/COFF/Driver.cpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,14 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
372372
if (StringRef(S).startswith("lldlto=")) {
373373
StringRef OptLevel = StringRef(S).substr(7);
374374
if (OptLevel.getAsInteger(10, Config->LTOOptLevel) ||
375-
Config->LTOOptLevel > 3) {
375+
Config->LTOOptLevel > 3)
376376
error("/opt:lldlto: invalid optimization level: " + OptLevel);
377-
}
377+
continue;
378+
}
379+
if (StringRef(S).startswith("lldltojobs=")) {
380+
StringRef Jobs = StringRef(S).substr(11);
381+
if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0)
382+
error("/opt:lldltojobs: invalid job count: " + Jobs);
378383
continue;
379384
}
380385
if (S != "ref" && S != "icf" && S != "noicf" &&
@@ -594,9 +599,9 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
594599
Symtab.run();
595600
}
596601

597-
// Do LTO by compiling bitcode input files to a native COFF file
598-
// then link that file.
599-
Symtab.addCombinedLTOObject();
602+
// Do LTO by compiling bitcode input files to a set of native COFF files then
603+
// link those files.
604+
Symtab.addCombinedLTOObjects();
600605

601606
// Make sure we have resolved all symbols.
602607
Symtab.reportRemainingUndefines(/*Resolve=*/true);

‎lld/COFF/SymbolTable.cpp

+47-24
Original file line numberDiff line numberDiff line change
@@ -331,21 +331,7 @@ void SymbolTable::printMap(llvm::raw_ostream &OS) {
331331
}
332332
}
333333

334-
void SymbolTable::addCombinedLTOObject() {
335-
if (BitcodeFiles.empty())
336-
return;
337-
338-
// Diagnose any undefined symbols early, but do not resolve weak externals,
339-
// as resolution breaks the invariant that each Symbol points to a unique
340-
// SymbolBody, which we rely on to replace DefinedBitcode symbols correctly.
341-
reportRemainingUndefines(/*Resolve=*/false);
342-
343-
// Create an object file and add it to the symbol table by replacing any
344-
// DefinedBitcode symbols with the definitions in the object file.
345-
LTOCodeGenerator CG;
346-
CG.setOptLevel(Config->LTOOptLevel);
347-
ObjectFile *Obj = createLTOObject(&CG);
348-
334+
void SymbolTable::addCombinedLTOObject(ObjectFile *Obj) {
349335
for (SymbolBody *Body : Obj->getSymbols()) {
350336
if (!Body->isExternal())
351337
continue;
@@ -371,6 +357,25 @@ void SymbolTable::addCombinedLTOObject() {
371357
if (Comp < 0)
372358
Sym->Body = Body;
373359
}
360+
}
361+
362+
void SymbolTable::addCombinedLTOObjects() {
363+
if (BitcodeFiles.empty())
364+
return;
365+
366+
// Diagnose any undefined symbols early, but do not resolve weak externals,
367+
// as resolution breaks the invariant that each Symbol points to a unique
368+
// SymbolBody, which we rely on to replace DefinedBitcode symbols correctly.
369+
reportRemainingUndefines(/*Resolve=*/false);
370+
371+
// Create an object file and add it to the symbol table by replacing any
372+
// DefinedBitcode symbols with the definitions in the object file.
373+
LTOCodeGenerator CG;
374+
CG.setOptLevel(Config->LTOOptLevel);
375+
std::vector<ObjectFile *> Objs = createLTOObjects(&CG);
376+
377+
for (ObjectFile *Obj : Objs)
378+
addCombinedLTOObject(Obj);
374379

375380
size_t NumBitcodeFiles = BitcodeFiles.size();
376381
run();
@@ -379,8 +384,8 @@ void SymbolTable::addCombinedLTOObject() {
379384
}
380385

381386
// Combine and compile bitcode files and then return the result
382-
// as a regular COFF object file.
383-
ObjectFile *SymbolTable::createLTOObject(LTOCodeGenerator *CG) {
387+
// as a vector of regular COFF object files.
388+
std::vector<ObjectFile *> SymbolTable::createLTOObjects(LTOCodeGenerator *CG) {
384389
// All symbols referenced by non-bitcode objects must be preserved.
385390
for (ObjectFile *File : ObjectFiles)
386391
for (SymbolBody *Body : File->getSymbols())
@@ -406,14 +411,32 @@ ObjectFile *SymbolTable::createLTOObject(LTOCodeGenerator *CG) {
406411
CG->addModule(BitcodeFiles[I]->getModule());
407412

408413
std::string ErrMsg;
409-
LTOMB = CG->compile(false, false, false, ErrMsg); // take MB ownership
410-
if (!LTOMB)
414+
if (!CG->optimize(false, false, false, ErrMsg))
415+
error(ErrMsg);
416+
417+
Objs.resize(Config->LTOJobs);
418+
// Use std::list to avoid invalidation of pointers in OSPtrs.
419+
std::list<raw_svector_ostream> OSs;
420+
std::vector<raw_pwrite_stream *> OSPtrs;
421+
for (SmallVector<char, 0> &Obj : Objs) {
422+
OSs.emplace_back(Obj);
423+
OSPtrs.push_back(&OSs.back());
424+
}
425+
426+
if (!CG->compileOptimized(OSPtrs, ErrMsg))
411427
error(ErrMsg);
412-
auto *Obj = new ObjectFile(LTOMB->getMemBufferRef());
413-
Files.emplace_back(Obj);
414-
ObjectFiles.push_back(Obj);
415-
Obj->parse();
416-
return Obj;
428+
429+
std::vector<ObjectFile *> ObjFiles;
430+
for (SmallVector<char, 0> &Obj : Objs) {
431+
auto *ObjFile = new ObjectFile(
432+
MemoryBufferRef(StringRef(Obj.data(), Obj.size()), "<LTO object>"));
433+
Files.emplace_back(ObjFile);
434+
ObjectFiles.push_back(ObjFile);
435+
ObjFile->parse();
436+
ObjFiles.push_back(ObjFile);
437+
}
438+
439+
return ObjFiles;
417440
}
418441

419442
} // namespace coff

‎lld/COFF/SymbolTable.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ class SymbolTable {
6868
// Print a layout map to OS.
6969
void printMap(llvm::raw_ostream &OS);
7070

71-
// Build a COFF object representing the combined contents of BitcodeFiles
72-
// and add it to the symbol table. Called after all files are added and
73-
// before the writer writes results to a file.
74-
void addCombinedLTOObject();
71+
// Build a set of COFF objects representing the combined contents of
72+
// BitcodeFiles and add them to the symbol table. Called after all files are
73+
// added and before the writer writes results to a file.
74+
void addCombinedLTOObjects();
7575

7676
// The writer needs to handle DLL import libraries specially in
7777
// order to create the import descriptor table.
@@ -98,7 +98,8 @@ class SymbolTable {
9898
StringRef findByPrefix(StringRef Prefix);
9999

100100
void addMemberFile(Lazy *Body);
101-
ObjectFile *createLTOObject(llvm::LTOCodeGenerator *CG);
101+
void addCombinedLTOObject(ObjectFile *Obj);
102+
std::vector<ObjectFile *> createLTOObjects(llvm::LTOCodeGenerator *CG);
102103

103104
llvm::DenseMap<StringRef, Symbol *> Symtab;
104105

@@ -107,7 +108,7 @@ class SymbolTable {
107108
std::vector<InputFile *> ObjectQueue;
108109

109110
std::vector<BitcodeFile *> BitcodeFiles;
110-
std::unique_ptr<MemoryBuffer> LTOMB;
111+
std::vector<SmallVector<char, 0>> Objs;
111112
llvm::BumpPtrAllocator Alloc;
112113
};
113114

‎lld/test/COFF/lto-parallel.ll

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llvm-as -o %t.obj %s
2+
; RUN: lld-link /out:%t.exe /entry:foo /include:bar /opt:lldltojobs=2 /subsystem:console /lldmap:%t.map %t.obj
3+
; RUN: FileCheck %s < %t.map
4+
5+
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
6+
target triple = "x86_64-pc-windows-msvc"
7+
8+
; CHECK: <lto object>:
9+
; CHECK: foo
10+
define void @foo() {
11+
call void @bar()
12+
ret void
13+
}
14+
15+
; CHECK: <lto object>:
16+
; CHECK: bar
17+
define void @bar() {
18+
call void @foo()
19+
ret void
20+
}

‎lld/test/COFF/weak-external.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# RUN: lld-link /out:%t2.exe /entry:g /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj
55
# RUN: FileCheck %s < %t2.map
66

7-
# CHECK: lto-llvm{{.*}}:
7+
# CHECK: <lto object>:
88
# CHECK-NOT: :
99
# CHECK: {{ g$}}
1010

‎lld/test/COFF/weak-external3.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# RUN: lld-link /out:%t2.exe /entry:f /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj
66
# RUN: FileCheck --check-prefix=CHECK2 %s < %t2.map
77

8-
# CHECK1: lto-llvm{{.*}}:
8+
# CHECK1: <lto object>:
99
# CHECK1-NOT: :
1010
# CHECK1: {{ g$}}
1111

0 commit comments

Comments
 (0)
Please sign in to comment.