[lld] 7518d38 - [ELF] De-template LinkerDriver::link. NFC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 1 09:48:01 PST 2022


Author: Fangrui Song
Date: 2022-02-01T09:47:56-08:00
New Revision: 7518d38f0aa23d6a259753a2cbf8885ca6a58020

URL: https://github.com/llvm/llvm-project/commit/7518d38f0aa23d6a259753a2cbf8885ca6a58020
DIFF: https://github.com/llvm/llvm-project/commit/7518d38f0aa23d6a259753a2cbf8885ca6a58020.diff

LOG: [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

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/Driver.h
    lld/ELF/Target.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 716523cf158f0..406571e4e9fd5 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -553,22 +553,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
     // values such as a default image base address.
     target = getTarget();
 
-    switch (config->ekind) {
-    case ELF32LEKind:
-      link<ELF32LE>(args);
-      break;
-    case ELF32BEKind:
-      link<ELF32BE>(args);
-      break;
-    case ELF64LEKind:
-      link<ELF64LE>(args);
-      break;
-    case ELF64BEKind:
-      link<ELF64BE>(args);
-      break;
-    default:
-      llvm_unreachable("unknown Config->EKind");
-    }
+    link(args);
   }
 
   if (config->timeTraceEnabled) {
@@ -2231,7 +2216,7 @@ static uint32_t getAndFeatures() {
 
 // Do actual linking. Note that when this function is called,
 // all linker scripts have already been parsed.
-template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
+void LinkerDriver::link(opt::InputArgList &args) {
   llvm::TimeTraceScope timeScope("Link", StringRef("LinkerDriver::Link"));
   // If a --hash-style option was not given, set to a default value,
   // which varies depending on the target.
@@ -2399,7 +2384,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   //
   // With this the symbol table should be complete. After this, no new names
   // except a few linker-synthesized ones will be added to the symbol table.
-  compileBitcodeFiles<ELFT>(skipLinkedOutput);
+  invokeELFT(compileBitcodeFiles, skipLinkedOutput);
 
   // Symbol resolution finished. Report backward reference problems.
   reportBackrefs();
@@ -2440,7 +2425,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
     llvm::TimeTraceScope timeScope("Strip sections");
     llvm::erase_if(inputSections, [](InputSectionBase *s) {
       if (s->type == SHT_LLVM_SYMPART) {
-        readSymbolPartitionSection<ELFT>(s);
+        invokeELFT(readSymbolPartitionSection, s);
         return true;
       }
 
@@ -2507,10 +2492,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
     inputSections.push_back(createCommentSection());
 
   // Split SHF_MERGE and .eh_frame sections into pieces in preparation for garbage collection.
-  splitSections<ELFT>();
+  invokeELFT(splitSections);
 
   // Garbage collection and removal of shared symbols from unused shared objects.
-  markLive<ELFT>();
+  invokeELFT(markLive);
   demoteSharedSymbols();
 
   // 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) {
 
   // Create synthesized sections such as .got and .plt. This is called before
   // processSectionCommands() so that they can be placed by SECTIONS commands.
-  createSyntheticSections<ELFT>();
+  invokeELFT(createSyntheticSections);
 
   // Some input sections that are used for exception handling need to be moved
   // into synthetic sections. Do that now so that they aren't assigned to
@@ -2558,8 +2543,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // Two input sections with 
diff erent output sections should not be folded.
   // ICF runs after processSectionCommands() so that we know the output sections.
   if (config->icf != ICFLevel::None) {
-    findKeepUniqueSections<ELFT>(args);
-    doIcf<ELFT>();
+    invokeELFT(findKeepUniqueSections, args);
+    invokeELFT(doIcf);
   }
 
   // Read the callgraph now that we know what was gced or icfed
@@ -2567,9 +2552,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
     if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
       if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
         readCallGraph(*buffer);
-    readCallGraphsFromObjectFiles<ELFT>();
+    invokeELFT(readCallGraphsFromObjectFiles);
   }
 
   // Write the result to the file.
-  writeResult<ELFT>();
+  invokeELFT(writeResult);
 }

diff  --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index b8cbb3b19268f..510ca626c6d17 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -33,7 +33,7 @@ class LinkerDriver {
 private:
   void createFiles(llvm::opt::InputArgList &args);
   void inferMachineType();
-  template <class ELFT> void link(llvm::opt::InputArgList &args);
+  void link(llvm::opt::InputArgList &args);
   template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput);
 
   // True if we are in --whole-archive and --no-whole-archive.

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index f7b947ec3aa28..15330b2be258b 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -298,4 +298,25 @@ inline void write64(void *p, uint64_t v) {
 } // namespace elf
 } // namespace lld
 
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
+#endif
+#define invokeELFT(f, ...)                                                     \
+  switch (config->ekind) {                                                     \
+  case ELF32LEKind:                                                            \
+    f<ELF32LE>(__VA_ARGS__);                                                   \
+    break;                                                                     \
+  case ELF32BEKind:                                                            \
+    f<ELF32BE>(__VA_ARGS__);                                                   \
+    break;                                                                     \
+  case ELF64LEKind:                                                            \
+    f<ELF64LE>(__VA_ARGS__);                                                   \
+    break;                                                                     \
+  case ELF64BEKind:                                                            \
+    f<ELF64BE>(__VA_ARGS__);                                                   \
+    break;                                                                     \
+  default:                                                                     \
+    llvm_unreachable("unknown config->ekind");                                 \
+  }
+
 #endif


        


More information about the llvm-commits mailing list