[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