[lld] r305134 - [ICF] Ignore SHF_GROUP flag when comparing two sections.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 9 17:38:55 PDT 2017


Author: ruiu
Date: Fri Jun  9 19:38:55 2017
New Revision: 305134

URL: http://llvm.org/viewvc/llvm-project?rev=305134&view=rev
Log:
[ICF] Ignore SHF_GROUP flag when comparing two sections.

SHF_GROUP bit doesn't make sense in executables or DSOs, so linkers are
expected to remove that bit from section flags. We did that when we create
output sections.

This patch is to do that earlier than before. Now the flag is dropped when
we instantiate input section objects.

This change improves ICF. Previously, two sections that differ only in
SHF_GROUP flag were not merged, because when the control reached ICF,
the flag was still there. Now the flag is dropped before reaching to ICF,
so the difference is ignored naturally.

This issue was found by pcc.

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

Added:
    lld/trunk/test/ELF/icf-comdat.s
Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/test/ELF/arm-icf-exidx.s

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=305134&r1=305133&r2=305134&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Jun  9 19:38:55 2017
@@ -73,6 +73,16 @@ InputSectionBase::InputSectionBase(Input
   this->Alignment = V;
 }
 
+// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
+// SHF_GROUP is a marker that a section belongs to some comdat group.
+// That flag doesn't make sense in an executable.
+static uint64_t getFlags(uint64_t Flags) {
+  Flags &= ~(uint64_t)SHF_INFO_LINK;
+  if (!Config->Relocatable)
+    Flags &= ~(uint64_t)SHF_GROUP;
+  return Flags;
+}
+
 // GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
 // March 2017) fail to infer section types for sections starting with
 // ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
@@ -95,7 +105,7 @@ template <class ELFT>
 InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File,
                                    const typename ELFT::Shdr *Hdr,
                                    StringRef Name, Kind SectionKind)
-    : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK,
+    : InputSectionBase(File, getFlags(Hdr->sh_flags),
                        getType(Hdr->sh_type, Name), Hdr->sh_entsize,
                        Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
                        getSectionContents(File, Hdr), Name, SectionKind) {

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=305134&r1=305133&r2=305134&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Jun  9 19:38:55 2017
@@ -313,10 +313,6 @@ void OutputSectionFactory::addInputSec(I
     return;
   }
 
-  uint64_t Flags = IS->Flags;
-  if (!Config->Relocatable)
-    Flags &= ~(uint64_t)SHF_GROUP;
-
   if (Sec) {
     if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
       error("incompatible section flags for " + Sec->Name +
@@ -333,9 +329,9 @@ void OutputSectionFactory::addInputSec(I
               "\n>>> output section " + Sec->Name + ": " +
               getELFSectionTypeName(Config->EMachine, Sec->Type));
     }
-    Sec->Flags |= Flags;
+    Sec->Flags |= IS->Flags;
   } else {
-    Sec = make<OutputSection>(OutsecName, IS->Type, Flags);
+    Sec = make<OutputSection>(OutsecName, IS->Type, IS->Flags);
     OutputSections.push_back(Sec);
   }
 

Modified: lld/trunk/test/ELF/arm-icf-exidx.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-icf-exidx.s?rev=305134&r1=305133&r2=305134&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-icf-exidx.s (original)
+++ lld/trunk/test/ELF/arm-icf-exidx.s Fri Jun  9 19:38:55 2017
@@ -19,13 +19,15 @@ g:
  .section .text.h
  .global __aeabi_unwind_cpp_pr0
 __aeabi_unwind_cpp_pr0:
+ nop
  bx lr
 
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT: f:
 // CHECK-NEXT:    11000:        1e ff 2f e1     bx      lr
 // CHECK: __aeabi_unwind_cpp_pr0:
-// CHECK-NEXT:    11004:        1e ff 2f e1     bx      lr
+// CHECK-NEXT:    11004:        00 f0 20 e3     nop
+// CHECK-NEXT:    11008:        1e ff 2f e1     bx      lr
 
 // CHECK: Contents of section .ARM.exidx:
 // CHECK-NEXT:  100d4 2c0f0000 b0b0b080 280f0000 01000000

Added: lld/trunk/test/ELF/icf-comdat.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/icf-comdat.s?rev=305134&view=auto
==============================================================================
--- lld/trunk/test/ELF/icf-comdat.s (added)
+++ lld/trunk/test/ELF/icf-comdat.s Fri Jun  9 19:38:55 2017
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
+
+# CHECK: selected .text.f1
+# CHECK:   removed .text.f2
+
+.globl _start, f1, f2
+_start:
+  ret
+
+.section .text.f1,"ax"
+f1:
+  mov $60, %rax
+  mov $42, %rdi
+  syscall
+
+.section .text.f2,"axG", at progbits,foo,comdat
+f2:
+  mov $60, %rax
+  mov $42, %rdi
+  syscall




More information about the llvm-commits mailing list