COFF: Don't create unnecessary thunks.
authorPeter Collingbourne <peter@pcc.me.uk>
Thu, 10 May 2018 19:01:28 +0000 (19:01 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Thu, 10 May 2018 19:01:28 +0000 (19:01 +0000)
A thunk is only needed if a relocation points to the undecorated
import name.

Differential Revision: https://reviews.llvm.org/D46673

llvm-svn: 332019

lld/COFF/InputFiles.h
lld/COFF/MarkLive.cpp
lld/COFF/Symbols.cpp
lld/COFF/Writer.cpp
lld/test/COFF/delayimports-armnt.yaml

index e2b7904..9f4db45 100644 (file)
@@ -201,8 +201,7 @@ private:
 // for details about the format.
 class ImportFile : public InputFile {
 public:
-  explicit ImportFile(MemoryBufferRef M)
-      : InputFile(ImportKind, M), Live(!Config->DoGC) {}
+  explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind, M) {}
 
   static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
 
@@ -221,12 +220,15 @@ public:
   Chunk *Location = nullptr;
 
   // We want to eliminate dllimported symbols if no one actually refers them.
-  // This "Live" bit is used to keep track of which import library members
+  // These "Live" bits are used to keep track of which import library members
   // are actually in use.
   //
   // If the Live bit is turned off by MarkLive, Writer will ignore dllimported
-  // symbols provided by this import library member.
-  bool Live;
+  // symbols provided by this import library member. We also track whether the
+  // imported symbol is used separately from whether the thunk is used in order
+  // to avoid creating unnecessary thunks.
+  bool Live = !Config->DoGC;
+  bool ThunkLive = !Config->DoGC;
 };
 
 // Used for LTO.
index d5d6ecf..57ae450 100644 (file)
@@ -48,7 +48,7 @@ void markLive(ArrayRef<Chunk *> Chunks) {
     else if (auto *Sym = dyn_cast<DefinedImportData>(B))
       Sym->File->Live = true;
     else if (auto *Sym = dyn_cast<DefinedImportThunk>(B))
-      Sym->WrappedSym->File->Live = true;
+      Sym->WrappedSym->File->Live = Sym->WrappedSym->File->ThunkLive = true;
   };
 
   // Add GC root chunks.
index fedb337..7c8b7d5 100644 (file)
@@ -58,7 +58,7 @@ bool Symbol::isLive() const {
   if (auto *Imp = dyn_cast<DefinedImportData>(this))
     return Imp->File->Live;
   if (auto *Imp = dyn_cast<DefinedImportThunk>(this))
-    return Imp->WrappedSym->File->Live;
+    return Imp->WrappedSym->File->ThunkLive;
   // Assume any other kind of symbol is live.
   return true;
 }
index 952124a..b14cbb4 100644 (file)
@@ -543,14 +543,10 @@ void Writer::createImportTables() {
     std::string DLL = StringRef(File->DLLName).lower();
     if (Config->DLLOrder.count(DLL) == 0)
       Config->DLLOrder[DLL] = Config->DLLOrder.size();
-  }
-
-  for (ImportFile *File : ImportFile::Instances) {
-    if (!File->Live)
-      continue;
 
     if (DefinedImportThunk *Thunk = File->ThunkSym)
-      TextSec->addChunk(Thunk->getChunk());
+      if (File->ThunkLive)
+        TextSec->addChunk(Thunk->getChunk());
 
     if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) {
       if (!File->ThunkSym)
index 76aa6d4..a080d02 100644 (file)
@@ -20,7 +20,7 @@
 # IMPORT-NEXT:   UnloadDelayImportTable: 0x0
 # IMPORT-NEXT:   Import {
 # IMPORT-NEXT:     Symbol: function (0)
-# IMPORT-NEXT:     Address: 0x401019
+# IMPORT-NEXT:     Address: 0x40100D
 # IMPORT-NEXT:   }
 # IMPORT-NEXT: }
 #
 # BASEREL-NEXT:   }
 # BASEREL-NEXT:   Entry {
 # BASEREL-NEXT:     Type: ARM_MOV32(T)
-# BASEREL-NEXT:     Address: 0x1018
+# BASEREL-NEXT:     Address: 0x1022
 # BASEREL-NEXT:   }
 # BASEREL-NEXT:   Entry {
-# BASEREL-NEXT:     Type: ARM_MOV32(T)
-# BASEREL-NEXT:     Address: 0x102E
+# BASEREL-NEXT:     Type: ABSOLUTE
+# BASEREL-NEXT:     Address: 0x1000
 # BASEREL-NEXT:   }
 # BASEREL-NEXT:   Entry {
 # BASEREL-NEXT:     Type: HIGHLOW
 # BASEREL-NEXT:   }
 # BASEREL-NEXT: ]
 #
-# DISASM:      401018:       43 f2 08 0c     movw r12, #12296
-# DISASM-NEXT: 40101c:       c0 f2 40 0c     movt    r12, #64
-# DISASM-NEXT: 401020:       2d e9 0f 48     push.w  {r0, r1, r2, r3, r11, lr}
-# DISASM-NEXT: 401024:       0d f2 10 0b     addw    r11, sp, #16
-# DISASM-NEXT: 401028:       2d ed 10 0b     vpush   {d0, d1, d2, d3, d4, d5, d6, d7}
-# DISASM-NEXT: 40102c:       61 46           mov     r1, r12
-# DISASM-NEXT: 40102e:       42 f2 00 00     movw r0, #8192
-# DISASM-NEXT: 401032:       c0 f2 40 00     movt    r0, #64
-# DISASM-NEXT: 401036:       ff f7 e3 ff     bl      #-58
-# DISASM-NEXT: 40103a:       84 46           mov     r12, r0
-# DISASM-NEXT: 40103c:       bd ec 10 0b     vpop    {d0, d1, d2, d3, d4, d5, d6, d7}
-# DISASM-NEXT: 401040:       bd e8 0f 48     pop.w   {r0, r1, r2, r3, r11, lr}
-# DISASM-NEXT: 401044:       60 47           bx      r12
+# DISASM:      40100c:       43 f2 08 0c     movw r12, #12296
+# DISASM-NEXT:               c0 f2 40 0c     movt    r12, #64
+# DISASM-NEXT:               2d e9 0f 48     push.w  {r0, r1, r2, r3, r11, lr}
+# DISASM-NEXT:               0d f2 10 0b     addw    r11, sp, #16
+# DISASM-NEXT:               2d ed 10 0b     vpush   {d0, d1, d2, d3, d4, d5, d6, d7}
+# DISASM-NEXT:               61 46           mov     r1, r12
+# DISASM-NEXT:               42 f2 00 00     movw r0, #8192
+# DISASM-NEXT:               c0 f2 40 00     movt    r0, #64
+# DISASM-NEXT:               ff f7 e9 ff     bl      #-46
+# DISASM-NEXT:               84 46           mov     r12, r0
+# DISASM-NEXT:               bd ec 10 0b     vpop    {d0, d1, d2, d3, d4, d5, d6, d7}
+# DISASM-NEXT:               bd e8 0f 48     pop.w   {r0, r1, r2, r3, r11, lr}
+# DISASM-NEXT:               60 47           bx      r12
 
 --- !COFF
 header: