[lld] r240590 - COFF: Move code for ICF from Writer.cpp to ICF.cpp.

Rui Ueyama ruiu at google.com
Wed Jun 24 13:40:03 PDT 2015


Author: ruiu
Date: Wed Jun 24 15:40:03 2015
New Revision: 240590

URL: http://llvm.org/viewvc/llvm-project?rev=240590&view=rev
Log:
COFF: Move code for ICF from Writer.cpp to ICF.cpp.

Added:
    lld/trunk/COFF/ICF.cpp
Modified:
    lld/trunk/COFF/CMakeLists.txt
    lld/trunk/COFF/Writer.cpp
    lld/trunk/COFF/Writer.h

Modified: lld/trunk/COFF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/CMakeLists.txt?rev=240590&r1=240589&r2=240590&view=diff
==============================================================================
--- lld/trunk/COFF/CMakeLists.txt (original)
+++ lld/trunk/COFF/CMakeLists.txt Wed Jun 24 15:40:03 2015
@@ -7,6 +7,7 @@ add_llvm_library(lldCOFF
   DLL.cpp
   Driver.cpp
   DriverUtils.cpp
+  ICF.cpp
   InputFiles.cpp
   ModuleDef.cpp
   SymbolTable.cpp

Added: lld/trunk/COFF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=240590&view=auto
==============================================================================
--- lld/trunk/COFF/ICF.cpp (added)
+++ lld/trunk/COFF/ICF.cpp Wed Jun 24 15:40:03 2015
@@ -0,0 +1,61 @@
+//===- ICF.cpp ------------------------------------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements ICF (Identical COMDAT Folding)
+//
+//===----------------------------------------------------------------------===//
+
+#include "Chunks.h"
+#include <tuple>
+#include <unordered_set>
+#include <vector>
+
+namespace lld {
+namespace coff {
+namespace {
+
+struct Hasher {
+  size_t operator()(const SectionChunk *C) const { return C->getHash(); }
+};
+
+struct Equals {
+  bool operator()(const SectionChunk *A, const SectionChunk *B) const {
+    return A->equals(B);
+  }
+};
+
+} // anonymous namespace
+
+// Merge identical COMDAT sections.
+// Two sections are considered as identical when their section headers,
+// contents and relocations are all the same.
+void doICF(const std::vector<Chunk *> &Chunks) {
+  std::unordered_set<SectionChunk *, Hasher, Equals> Set;
+  bool removed = false;
+  for (Chunk *C : Chunks) {
+    if (!C->isCOMDAT() || !C->isLive())
+      continue;
+    auto *SC = reinterpret_cast<SectionChunk *>(C);
+    auto P = Set.insert(SC);
+    bool Inserted = P.second;
+    if (Inserted)
+      continue;
+    SectionChunk *Existing = *P.first;
+    SC->replaceWith(Existing);
+    removed = true;
+  }
+  // By merging sections, two relocations that originally pointed to
+  // different locations can now point to the same location.
+  // So, repeat the process until a convegence is obtained.
+  if (removed)
+    doICF(Chunks);
+}
+
+} // namespace coff
+} // namespace lld

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=240590&r1=240589&r2=240590&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Jun 24 15:40:03 2015
@@ -41,6 +41,7 @@ namespace coff {
 // The main function of the writer.
 std::error_code Writer::write(StringRef OutputPath) {
   markLive();
+  dedupCOMDATs();
   createSections();
   createImportTables();
   createExportTable();
@@ -127,36 +128,13 @@ struct Equals {
 };
 
 // Merge identical COMDAT sections.
-// Two sections are considered as identical when their section headers,
-// contents and relocations are all the same.
 void Writer::dedupCOMDATs() {
-  std::vector<SectionChunk *> V;
-  for (Chunk *C : Symtab->getChunks())
-    if (C->isCOMDAT() && C->isLive())
-      V.push_back(reinterpret_cast<SectionChunk *>(C));
-
-  std::unordered_set<SectionChunk *, Hasher, Equals> Set;
-  bool removed = false;
-  for (SectionChunk *C : V) {
-    auto P = Set.insert(C);
-    if (P.second)
-      continue;
-    SectionChunk *Existing = *P.first;
-    C->replaceWith(Existing);
-    removed = true;
-  }
-  // By merging sections, two relocations that originally pointed to
-  // different locations can now point to the same location.
-  // So, repeat the process until a convegence is obtained.
-  if (removed)
-    dedupCOMDATs();
+  if (Config->ICF)
+    doICF(Symtab->getChunks());
 }
 
 // Create output section objects and add them to OutputSections.
 void Writer::createSections() {
-  if (Config->ICF)
-    dedupCOMDATs();
-
   // First, bin chunks by name.
   std::map<StringRef, std::vector<Chunk *>> Map;
   for (Chunk *C : Symtab->getChunks()) {

Modified: lld/trunk/COFF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.h?rev=240590&r1=240589&r2=240590&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.h (original)
+++ lld/trunk/COFF/Writer.h Wed Jun 24 15:40:03 2015
@@ -24,6 +24,9 @@ namespace coff {
 // and permissions (writable, readable or executable).
 const uint32_t PermMask = 0xFF0000F0;
 
+// Implemented in ICF.cpp.
+void doICF(const std::vector<Chunk *> &Chunks);
+
 // OutputSection represents a section in an output file. It's a
 // container of chunks. OutputSection and Chunk are 1:N relationship.
 // Chunks cannot belong to more than one OutputSections. The writer
@@ -76,6 +79,7 @@ public:
 
 private:
   void markLive();
+  void dedupCOMDATs();
   void createSections();
   void createImportTables();
   void createExportTable();
@@ -89,7 +93,6 @@ private:
 
   OutputSection *findSection(StringRef Name);
   OutputSection *createSection(StringRef Name);
-  void dedupCOMDATs();
   void addBaserels(OutputSection *Dest);
   void addBaserelBlocks(OutputSection *Dest, std::vector<uint32_t> &V);
 





More information about the llvm-commits mailing list