Skip to content

Commit b068f2f

Browse files
authored
[LLD][COFF] Process bitcode files separately for each symbol table on ARM64X (#123194)
1 parent 9491f75 commit b068f2f

File tree

7 files changed

+108
-39
lines changed

7 files changed

+108
-39
lines changed

lld/COFF/COFFLinkerContext.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ class COFFLinkerContext : public CommonLinkerContext {
5656
std::vector<ObjFile *> objFileInstances;
5757
std::map<std::string, PDBInputFile *> pdbInputFileInstances;
5858
std::vector<ImportFile *> importFileInstances;
59-
std::vector<BitcodeFile *> bitcodeFileInstances;
6059

6160
MergeChunk *mergeChunkInstances[Log2MaxSectionAlignment + 1] = {};
6261

lld/COFF/Driver.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ void LinkerDriver::addFile(InputFile *file) {
218218
<< " linked in after "
219219
"doing LTO compilation.";
220220
}
221-
ctx.bitcodeFileInstances.push_back(f);
221+
f->symtab.bitcodeFileInstances.push_back(f);
222222
} else if (auto *f = dyn_cast<ImportFile>(file)) {
223223
ctx.importFileInstances.push_back(f);
224224
}
@@ -285,7 +285,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
285285
addFile(make<ArchiveFile>(ctx, mbref));
286286
break;
287287
case file_magic::bitcode:
288-
addFile(make<BitcodeFile>(ctx, mbref, "", 0, lazy));
288+
addFile(BitcodeFile::create(ctx, mbref, "", 0, lazy));
289289
break;
290290
case file_magic::coff_object:
291291
case file_magic::coff_import_library:
@@ -374,8 +374,8 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
374374
if (magic == file_magic::coff_object) {
375375
obj = ObjFile::create(ctx, mb);
376376
} else if (magic == file_magic::bitcode) {
377-
obj =
378-
make<BitcodeFile>(ctx, mb, parentName, offsetInArchive, /*lazy=*/false);
377+
obj = BitcodeFile::create(ctx, mb, parentName, offsetInArchive,
378+
/*lazy=*/false);
379379
} else if (magic == file_magic::coff_cl_gl_object) {
380380
Err(ctx) << mb.getBufferIdentifier()
381381
<< ": is not a native COFF file. Recompile without /GL?";
@@ -2571,19 +2571,19 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
25712571
}
25722572
}
25732573

2574-
// If any inputs are bitcode files, the LTO code generator may create
2575-
// references to library functions that are not explicit in the bitcode
2576-
// file's symbol table. If any of those library functions are defined in a
2577-
// bitcode file in an archive member, we need to arrange to use LTO to
2578-
// compile those archive members by adding them to the link beforehand.
2579-
if (!ctx.bitcodeFileInstances.empty()) {
2580-
llvm::Triple TT(
2581-
ctx.bitcodeFileInstances.front()->obj->getTargetTriple());
2582-
for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
2583-
ctx.symtab.addLibcall(s);
2584-
}
2585-
25862574
ctx.forEachSymtab([&](SymbolTable &symtab) {
2575+
// If any inputs are bitcode files, the LTO code generator may create
2576+
// references to library functions that are not explicit in the bitcode
2577+
// file's symbol table. If any of those library functions are defined in
2578+
// a bitcode file in an archive member, we need to arrange to use LTO to
2579+
// compile those archive members by adding them to the link beforehand.
2580+
if (!symtab.bitcodeFileInstances.empty()) {
2581+
llvm::Triple TT(
2582+
symtab.bitcodeFileInstances.front()->obj->getTargetTriple());
2583+
for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
2584+
symtab.addLibcall(s);
2585+
}
2586+
25872587
// Windows specific -- if __load_config_used can be resolved, resolve
25882588
// it.
25892589
if (symtab.findUnderscore("_load_config_used"))
@@ -2639,8 +2639,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26392639
// If we are going to do codegen for link-time optimization, check for
26402640
// unresolvable symbols first, so we don't spend time generating code that
26412641
// will fail to link anyway.
2642-
if (!ctx.bitcodeFileInstances.empty() && !config->forceUnresolved)
2643-
ctx.symtab.reportUnresolvable();
2642+
if (!config->forceUnresolved)
2643+
ctx.forEachSymtab([](SymbolTable &symtab) {
2644+
if (!symtab.bitcodeFileInstances.empty())
2645+
symtab.reportUnresolvable();
2646+
});
26442647
if (errorCount())
26452648
return;
26462649

@@ -2655,7 +2658,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26552658
// link those files (unless -thinlto-index-only was given, in which case we
26562659
// resolve symbols and write indices, but don't generate native code or link).
26572660
ltoCompilationDone = true;
2658-
ctx.symtab.compileBitcodeFiles();
2661+
ctx.forEachSymtab([](SymbolTable &symtab) { symtab.compileBitcodeFiles(); });
26592662

26602663
if (Defined *d =
26612664
dyn_cast_or_null<Defined>(ctx.symtab.findUnderscore("_tls_used")))

lld/COFF/InputFiles.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,10 +1229,15 @@ void ImportFile::parse() {
12291229
}
12301230
}
12311231

1232-
BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
1233-
StringRef archiveName, uint64_t offsetInArchive,
1234-
bool lazy)
1235-
: InputFile(ctx.symtab, BitcodeKind, mb, lazy) {
1232+
BitcodeFile::BitcodeFile(SymbolTable &symtab, MemoryBufferRef mb,
1233+
std::unique_ptr<lto::InputFile> &o, bool lazy)
1234+
: InputFile(symtab, BitcodeKind, mb, lazy) {
1235+
obj.swap(o);
1236+
}
1237+
1238+
BitcodeFile *BitcodeFile::create(COFFLinkerContext &ctx, MemoryBufferRef mb,
1239+
StringRef archiveName,
1240+
uint64_t offsetInArchive, bool lazy) {
12361241
std::string path = mb.getBufferIdentifier().str();
12371242
if (ctx.config.thinLTOIndexOnly)
12381243
path = replaceThinLTOSuffix(mb.getBufferIdentifier(),
@@ -1252,7 +1257,9 @@ BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
12521257
sys::path::filename(path) +
12531258
utostr(offsetInArchive)));
12541259

1255-
obj = check(lto::InputFile::create(mbref));
1260+
std::unique_ptr<lto::InputFile> obj = check(lto::InputFile::create(mbref));
1261+
return make<BitcodeFile>(ctx.getSymtab(getMachineType(obj.get())), mb, obj,
1262+
lazy);
12561263
}
12571264

12581265
BitcodeFile::~BitcodeFile() = default;
@@ -1329,7 +1336,7 @@ void BitcodeFile::parseLazy() {
13291336
}
13301337
}
13311338

1332-
MachineTypes BitcodeFile::getMachineType() const {
1339+
MachineTypes BitcodeFile::getMachineType(const llvm::lto::InputFile *obj) {
13331340
Triple t(obj->getTargetTriple());
13341341
switch (t.getArch()) {
13351342
case Triple::x86_64:

lld/COFF/InputFiles.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,19 @@ class ImportFile : public InputFile {
386386
// Used for LTO.
387387
class BitcodeFile : public InputFile {
388388
public:
389-
explicit BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
390-
StringRef archiveName, uint64_t offsetInArchive,
391-
bool lazy);
389+
explicit BitcodeFile(SymbolTable &symtab, MemoryBufferRef mb,
390+
std::unique_ptr<llvm::lto::InputFile> &obj, bool lazy);
392391
~BitcodeFile();
392+
393+
static BitcodeFile *create(COFFLinkerContext &ctx, MemoryBufferRef mb,
394+
StringRef archiveName, uint64_t offsetInArchive,
395+
bool lazy);
393396
static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
394397
ArrayRef<Symbol *> getSymbols() { return symbols; }
395-
MachineTypes getMachineType() const override;
398+
MachineTypes getMachineType() const override {
399+
return getMachineType(obj.get());
400+
}
401+
static MachineTypes getMachineType(const llvm::lto::InputFile *obj);
396402
void parseLazy();
397403
std::unique_ptr<llvm::lto::InputFile> obj;
398404

lld/COFF/SymbolTable.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ bool SymbolTable::handleMinGWAutomaticImport(Symbol *sym, StringRef name) {
347347
/// defined symbol imported" diagnostic for symbols in localImports.
348348
/// objFiles and bitcodeFiles (if not nullptr) are used to report where
349349
/// undefined symbols are referenced.
350-
static void reportProblemSymbols(
351-
COFFLinkerContext &ctx, const SmallPtrSetImpl<Symbol *> &undefs,
350+
void SymbolTable::reportProblemSymbols(
351+
const SmallPtrSetImpl<Symbol *> &undefs,
352352
const DenseMap<Symbol *, Symbol *> *localImports, bool needBitcodeFiles) {
353353
// Return early if there is nothing to report (which should be
354354
// the common case).
@@ -392,7 +392,7 @@ static void reportProblemSymbols(
392392
processFile(file, file->getSymbols());
393393

394394
if (needBitcodeFiles)
395-
for (BitcodeFile *file : ctx.bitcodeFileInstances)
395+
for (BitcodeFile *file : bitcodeFileInstances)
396396
processFile(file, file->getSymbols());
397397

398398
for (const UndefinedDiag &undefDiag : undefDiags)
@@ -423,8 +423,7 @@ void SymbolTable::reportUnresolvable() {
423423
undefs.insert(sym);
424424
}
425425

426-
reportProblemSymbols(ctx, undefs,
427-
/* localImports */ nullptr, true);
426+
reportProblemSymbols(undefs, /*localImports=*/nullptr, true);
428427
}
429428

430429
bool SymbolTable::resolveRemainingUndefines() {
@@ -506,8 +505,8 @@ bool SymbolTable::resolveRemainingUndefines() {
506505
}
507506

508507
reportProblemSymbols(
509-
ctx, undefs,
510-
ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, false);
508+
undefs, ctx.config.warnLocallyDefinedImported ? &localImports : nullptr,
509+
false);
511510
return foundLazy;
512511
}
513512

@@ -1124,13 +1123,13 @@ Symbol *SymbolTable::addUndefined(StringRef name) {
11241123
}
11251124

11261125
void SymbolTable::compileBitcodeFiles() {
1127-
if (ctx.bitcodeFileInstances.empty())
1126+
if (bitcodeFileInstances.empty())
11281127
return;
11291128

11301129
llvm::TimeTraceScope timeScope("Compile bitcode");
11311130
ScopedTimer t(ctx.ltoTimer);
11321131
lto.reset(new BitcodeCompiler(ctx));
1133-
for (BitcodeFile *f : ctx.bitcodeFileInstances)
1132+
for (BitcodeFile *f : bitcodeFileInstances)
11341133
lto->add(*f);
11351134
for (InputFile *newObj : lto->compile()) {
11361135
ObjFile *obj = cast<ObjFile>(newObj);

lld/COFF/SymbolTable.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ADT/CachedHashString.h"
1515
#include "llvm/ADT/DenseMap.h"
1616
#include "llvm/ADT/DenseMapInfo.h"
17+
#include "llvm/ADT/SmallPtrSet.h"
1718
#include "llvm/Support/raw_ostream.h"
1819

1920
namespace llvm {
@@ -155,6 +156,8 @@ class SymbolTable {
155156
callback(pair.second);
156157
}
157158

159+
std::vector<BitcodeFile *> bitcodeFileInstances;
160+
158161
DefinedRegular *loadConfigSym = nullptr;
159162
uint32_t loadConfigSize = 0;
160163
void initializeLoadConfig();
@@ -175,6 +178,11 @@ class SymbolTable {
175178
std::unique_ptr<BitcodeCompiler> lto;
176179
std::vector<std::pair<Symbol *, Symbol *>> entryThunks;
177180
llvm::DenseMap<Symbol *, Symbol *> exitThunks;
181+
182+
void
183+
reportProblemSymbols(const llvm::SmallPtrSetImpl<Symbol *> &undefs,
184+
const llvm::DenseMap<Symbol *, Symbol *> *localImports,
185+
bool needBitcodeFiles);
178186
};
179187

180188
std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex);

lld/test/COFF/lto-arm64x.ll

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; REQUIRES: aarch64, x86
2+
; RUN: split-file %s %t.dir && cd %t.dir
3+
4+
; RUN: llvm-as arm64ec.ll -o arm64ec.obj
5+
; RUN: llvm-as aarch64.ll -o aarch64.obj
6+
; RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
7+
; RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
8+
9+
; RUN: lld-link -machine:arm64x aarch64.obj arm64ec.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -out:out.exe -subsystem:console
10+
; RUN: llvm-objdump -d out.exe | FileCheck %s
11+
12+
; CHECK: 0000000140001000 <.text>:
13+
; CHECK-NEXT: 140001000: 52800020 mov w0, #0x1 // =1
14+
; CHECK-NEXT: 140001004: d65f03c0 ret
15+
; CHECK-NEXT: ...
16+
; CHECK-NEXT: 140002000: 00000009 udf #0x9
17+
; CHECK-NEXT: 140002004: 52800040 mov w0, #0x2 // =2
18+
; CHECK-NEXT: 140002008: d65f03c0 ret
19+
20+
; CHECK: 0000000140003000 <.hexpthk>:
21+
; CHECK-NEXT: 140003000: 48 8b c4 movq %rsp, %rax
22+
; CHECK-NEXT: 140003003: 48 89 58 20 movq %rbx, 0x20(%rax)
23+
; CHECK-NEXT: 140003007: 55 pushq %rbp
24+
; CHECK-NEXT: 140003008: 5d popq %rbp
25+
; CHECK-NEXT: 140003009: e9 f6 ef ff ff jmp 0x140002004 <.text+0x1004>
26+
; CHECK-NEXT: 14000300e: cc int3
27+
; CHECK-NEXT: 14000300f: cc int3
28+
29+
#--- arm64ec.ll
30+
31+
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
32+
target triple = "arm64ec-unknown-windows-msvc"
33+
34+
define dso_local i32 @mainCRTStartup() {
35+
entry:
36+
ret i32 2
37+
}
38+
39+
#--- aarch64.ll
40+
41+
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
42+
target triple = "aarch64-unknown-windows-msvc"
43+
44+
define dso_local i32 @mainCRTStartup() {
45+
entry:
46+
ret i32 1
47+
}

0 commit comments

Comments
 (0)