Skip to content

Commit 7518d38

Browse files
committed
[ELF] De-template LinkerDriver::link. NFC
Replace `f<ELFT>(x)` with `InvokeELFT(f, x)`. The size reduction comes from turning `link` from 4 specializations into 1. My x86-64 lld executable is 26KiB smaller. Reviewed By: ikudrin Differential Revision: https://reviews.llvm.org/D118551
1 parent 16978d8 commit 7518d38

File tree

3 files changed

+33
-27
lines changed

3 files changed

+33
-27
lines changed

lld/ELF/Driver.cpp

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -553,22 +553,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
553553
// values such as a default image base address.
554554
target = getTarget();
555555

556-
switch (config->ekind) {
557-
case ELF32LEKind:
558-
link<ELF32LE>(args);
559-
break;
560-
case ELF32BEKind:
561-
link<ELF32BE>(args);
562-
break;
563-
case ELF64LEKind:
564-
link<ELF64LE>(args);
565-
break;
566-
case ELF64BEKind:
567-
link<ELF64BE>(args);
568-
break;
569-
default:
570-
llvm_unreachable("unknown Config->EKind");
571-
}
556+
link(args);
572557
}
573558

574559
if (config->timeTraceEnabled) {
@@ -2231,7 +2216,7 @@ static uint32_t getAndFeatures() {
22312216

22322217
// Do actual linking. Note that when this function is called,
22332218
// all linker scripts have already been parsed.
2234-
template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
2219+
void LinkerDriver::link(opt::InputArgList &args) {
22352220
llvm::TimeTraceScope timeScope("Link", StringRef("LinkerDriver::Link"));
22362221
// If a --hash-style option was not given, set to a default value,
22372222
// which varies depending on the target.
@@ -2399,7 +2384,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
23992384
//
24002385
// With this the symbol table should be complete. After this, no new names
24012386
// except a few linker-synthesized ones will be added to the symbol table.
2402-
compileBitcodeFiles<ELFT>(skipLinkedOutput);
2387+
invokeELFT(compileBitcodeFiles, skipLinkedOutput);
24032388

24042389
// Symbol resolution finished. Report backward reference problems.
24052390
reportBackrefs();
@@ -2440,7 +2425,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
24402425
llvm::TimeTraceScope timeScope("Strip sections");
24412426
llvm::erase_if(inputSections, [](InputSectionBase *s) {
24422427
if (s->type == SHT_LLVM_SYMPART) {
2443-
readSymbolPartitionSection<ELFT>(s);
2428+
invokeELFT(readSymbolPartitionSection, s);
24442429
return true;
24452430
}
24462431

@@ -2507,10 +2492,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
25072492
inputSections.push_back(createCommentSection());
25082493

25092494
// Split SHF_MERGE and .eh_frame sections into pieces in preparation for garbage collection.
2510-
splitSections<ELFT>();
2495+
invokeELFT(splitSections);
25112496

25122497
// Garbage collection and removal of shared symbols from unused shared objects.
2513-
markLive<ELFT>();
2498+
invokeELFT(markLive);
25142499
demoteSharedSymbols();
25152500

25162501
// Make copies of any input sections that need to be copied into each
@@ -2519,7 +2504,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
25192504

25202505
// Create synthesized sections such as .got and .plt. This is called before
25212506
// processSectionCommands() so that they can be placed by SECTIONS commands.
2522-
createSyntheticSections<ELFT>();
2507+
invokeELFT(createSyntheticSections);
25232508

25242509
// Some input sections that are used for exception handling need to be moved
25252510
// into synthetic sections. Do that now so that they aren't assigned to
@@ -2558,18 +2543,18 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
25582543
// Two input sections with different output sections should not be folded.
25592544
// ICF runs after processSectionCommands() so that we know the output sections.
25602545
if (config->icf != ICFLevel::None) {
2561-
findKeepUniqueSections<ELFT>(args);
2562-
doIcf<ELFT>();
2546+
invokeELFT(findKeepUniqueSections, args);
2547+
invokeELFT(doIcf);
25632548
}
25642549

25652550
// Read the callgraph now that we know what was gced or icfed
25662551
if (config->callGraphProfileSort) {
25672552
if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
25682553
if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
25692554
readCallGraph(*buffer);
2570-
readCallGraphsFromObjectFiles<ELFT>();
2555+
invokeELFT(readCallGraphsFromObjectFiles);
25712556
}
25722557

25732558
// Write the result to the file.
2574-
writeResult<ELFT>();
2559+
invokeELFT(writeResult);
25752560
}

lld/ELF/Driver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class LinkerDriver {
3333
private:
3434
void createFiles(llvm::opt::InputArgList &args);
3535
void inferMachineType();
36-
template <class ELFT> void link(llvm::opt::InputArgList &args);
36+
void link(llvm::opt::InputArgList &args);
3737
template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput);
3838

3939
// True if we are in --whole-archive and --no-whole-archive.

lld/ELF/Target.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,25 @@ inline void write64(void *p, uint64_t v) {
298298
} // namespace elf
299299
} // namespace lld
300300

301+
#ifdef __clang__
302+
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
303+
#endif
304+
#define invokeELFT(f, ...) \
305+
switch (config->ekind) { \
306+
case ELF32LEKind: \
307+
f<ELF32LE>(__VA_ARGS__); \
308+
break; \
309+
case ELF32BEKind: \
310+
f<ELF32BE>(__VA_ARGS__); \
311+
break; \
312+
case ELF64LEKind: \
313+
f<ELF64LE>(__VA_ARGS__); \
314+
break; \
315+
case ELF64BEKind: \
316+
f<ELF64BE>(__VA_ARGS__); \
317+
break; \
318+
default: \
319+
llvm_unreachable("unknown config->ekind"); \
320+
}
321+
301322
#endif

0 commit comments

Comments
 (0)