[lld] r340555 - COFF: Implement safe ICF on rodata using address-significance tables.
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 23 10:44:42 PDT 2018
Author: pcc
Date: Thu Aug 23 10:44:42 2018
New Revision: 340555
URL: http://llvm.org/viewvc/llvm-project?rev=340555&view=rev
Log:
COFF: Implement safe ICF on rodata using address-significance tables.
Differential Revision: https://reviews.llvm.org/D51050
Added:
lld/trunk/test/COFF/Inputs/icf-safe.s
lld/trunk/test/COFF/icf-safe.s
Modified:
lld/trunk/COFF/Chunks.h
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/ICF.cpp
lld/trunk/COFF/InputFiles.cpp
lld/trunk/COFF/InputFiles.h
Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=340555&r1=340554&r2=340555&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Thu Aug 23 10:44:42 2018
@@ -114,6 +114,10 @@ protected:
public:
// The offset from beginning of the output section. The writer sets a value.
uint64_t OutputSectionOff = 0;
+
+ // Whether this section needs to be kept distinct from other sections during
+ // ICF. This is set by the driver using address-significance tables.
+ bool KeepUnique = false;
};
// A chunk corresponding a section of an input file.
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=340555&r1=340554&r2=340555&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Thu Aug 23 10:44:42 2018
@@ -32,6 +32,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TarWriter.h"
@@ -741,6 +742,46 @@ static void parseOrderFile(StringRef Arg
}
}
+static void markAddrsig(Symbol *S) {
+ if (auto *D = dyn_cast_or_null<Defined>(S))
+ if (Chunk *C = D->getChunk())
+ C->KeepUnique = true;
+}
+
+static void findKeepUniqueSections() {
+ // Exported symbols could be address-significant in other executables or DSOs,
+ // so we conservatively mark them as address-significant.
+ for (Export &R : Config->Exports)
+ markAddrsig(R.Sym);
+
+ // Visit the address-significance table in each object file and mark each
+ // referenced symbol as address-significant.
+ for (ObjFile *Obj : ObjFile::Instances) {
+ ArrayRef<Symbol *> Syms = Obj->getSymbols();
+ if (Obj->AddrsigSec) {
+ ArrayRef<uint8_t> Contents;
+ Obj->getCOFFObj()->getSectionContents(Obj->AddrsigSec, Contents);
+ const uint8_t *Cur = Contents.begin();
+ while (Cur != Contents.end()) {
+ unsigned Size;
+ const char *Err;
+ uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err);
+ if (Err)
+ fatal(toString(Obj) + ": could not decode addrsig section: " + Err);
+ if (SymIndex >= Syms.size())
+ fatal(toString(Obj) + ": invalid symbol index in addrsig section");
+ markAddrsig(Syms[SymIndex]);
+ Cur += Size;
+ }
+ } else {
+ // If an object file does not have an address-significance table,
+ // conservatively mark all of its symbols as address-significant.
+ for (Symbol *S : Syms)
+ markAddrsig(S);
+ }
+ }
+}
+
void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// If the first command line argument is "/lib", link.exe acts like lib.exe.
// We call our own implementation of lib.exe that understands bitcode files.
@@ -1452,8 +1493,10 @@ void LinkerDriver::link(ArrayRef<const c
markLive(Symtab->getChunks());
// Identify identical COMDAT sections to merge them.
- if (Config->DoICF)
+ if (Config->DoICF) {
+ findKeepUniqueSections();
doICF(Symtab->getChunks());
+ }
// Write the result.
writeResult();
Modified: lld/trunk/COFF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=340555&r1=340554&r2=340555&view=diff
==============================================================================
--- lld/trunk/COFF/ICF.cpp (original)
+++ lld/trunk/COFF/ICF.cpp Thu Aug 23 10:44:42 2018
@@ -93,7 +93,11 @@ bool ICF::isEligible(SectionChunk *C) {
return true;
// So are vtables.
- return C->Sym && C->Sym->getName().startswith("??_7");
+ if (C->Sym && C->Sym->getName().startswith("??_7"))
+ return true;
+
+ // Anything else not in an address-significance table is eligible.
+ return !C->KeepUnique;
}
// Split an equivalence class into smaller classes.
Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=340555&r1=340554&r2=340555&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Thu Aug 23 10:44:42 2018
@@ -161,6 +161,11 @@ SectionChunk *ObjFile::readSection(uint3
return nullptr;
}
+ if (Name == ".llvm_addrsig") {
+ AddrsigSec = Sec;
+ return nullptr;
+ }
+
// Object files may have DWARF debug info or MS CodeView debug info
// (or both).
//
Modified: lld/trunk/COFF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.h?rev=340555&r1=340554&r2=340555&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.h (original)
+++ lld/trunk/COFF/InputFiles.h Thu Aug 23 10:44:42 2018
@@ -145,6 +145,8 @@ public:
// if we are not producing a PDB.
llvm::pdb::DbiModuleDescriptorBuilder *ModuleDBI = nullptr;
+ const coff_section *AddrsigSec = nullptr;
+
private:
void initializeChunks();
void initializeSymbols();
Added: lld/trunk/test/COFF/Inputs/icf-safe.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/icf-safe.s?rev=340555&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/icf-safe.s (added)
+++ lld/trunk/test/COFF/Inputs/icf-safe.s Thu Aug 23 10:44:42 2018
@@ -0,0 +1,9 @@
+.section .rdata,"dr",one_only,non_addrsig1
+.globl non_addrsig1
+non_addrsig1:
+.byte 3
+
+.section .rdata,"dr",one_only,non_addrsig2
+.globl non_addrsig2
+non_addrsig2:
+.byte 3
Added: lld/trunk/test/COFF/icf-safe.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/icf-safe.s?rev=340555&view=auto
==============================================================================
--- lld/trunk/test/COFF/icf-safe.s (added)
+++ lld/trunk/test/COFF/icf-safe.s Thu Aug 23 10:44:42 2018
@@ -0,0 +1,36 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o %t1.obj
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-win32 %S/Inputs/icf-safe.s -o %t2.obj
+# RUN: lld-link /dll /noentry /out:%t.dll /verbose /opt:noref,icf %t1.obj %t2.obj 2>&1 | FileCheck %s
+# RUN: lld-link /dll /noentry /out:%t.dll /verbose /opt:noref,icf /export:g3 /export:g4 %t1.obj %t2.obj 2>&1 | FileCheck --check-prefix=EXPORT %s
+
+# CHECK-NOT: Selected
+# CHECK: Selected g3
+# CHECK-NEXT: Removed g4
+# CHECK-NOT: Removed
+# CHECK-NOT: Selected
+
+# EXPORT-NOT: Selected
+
+.section .rdata,"dr",one_only,g1
+.globl g1
+g1:
+.byte 1
+
+.section .rdata,"dr",one_only,g2
+.globl g2
+g2:
+.byte 1
+
+.section .rdata,"dr",one_only,g3
+.globl g3
+g3:
+.byte 2
+
+.section .rdata,"dr",one_only,g4
+.globl g4
+g4:
+.byte 2
+
+.addrsig
+.addrsig_sym g1
+.addrsig_sym g2
More information about the llvm-commits
mailing list