[PATCH] D17529: ELF: Implement ICF.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 23 16:27:23 PST 2016
ruiu marked 3 inline comments as done.
================
Comment at: ELF/ICF.cpp:10
@@ +9,3 @@
+//
+// Identical COMDAT Folding is a feature to merge COMDAT sections not by
+// name (which is regular COMDAT handling) but by contents. If two COMDAT
----------------
rafael wrote:
> On ELF it is possible to merge non COMDAT sections. We can keep the acronym by doing what gold does and calling this Identical *Code* Folding.
Done.
================
Comment at: ELF/ICF.cpp:118
@@ +117,3 @@
+ ELFFile<ELFT> &EObj = S->File->getObj();
+ const Elf_Shdr *RelSec = S->RelocSections[0];
+
----------------
rafael wrote:
> Assert that there only one? Return 0 if there is none?
Done.
================
Comment at: ELF/ICF.cpp:120
@@ +119,3 @@
+
+ if (RelSec->sh_type == SHT_RELA) {
+ auto Rels = EObj.relas(RelSec);
----------------
rafael wrote:
> It might be cleaner to just say RelSec->sh_size/RelSec->sh_entsize;
Done.
================
Comment at: ELF/ICF.cpp:128
@@ +127,3 @@
+
+// Returns a hash value for S. Note that relocation information is not
+// included in the hash value.
----------------
rafael wrote:
> Not exactly true since the number of relocations is included.
>
> Since this is the only use of numRels and it is only used for hashing, how about just using RelSec->sh_size?
Done.
================
Comment at: ELF/ICF.cpp:150
@@ +149,3 @@
+ const Elf_Shdr &H = *S->getSectionHdr();
+ return H.sh_type == SHT_PROGBITS &&
+ (H.sh_flags & SHF_ALLOC) &&
----------------
rafael wrote:
> Why only PROGBITS? OK if it is just to keep it simple for now.
It doesn't have to be PROGBITS only. Removed.
================
Comment at: ELF/ICF.cpp:168
@@ +167,3 @@
+// for new groups.
+template <class ELFT>
+bool ICF<ELFT>::partition(InputSection<ELFT> **Begin, InputSection<ELFT> **End,
----------------
rafael wrote:
> Return true if a new group was created.
>
> This could also return void and have the caller check NextId.
Done.
================
Comment at: ELF/ICF.cpp:232
@@ +231,3 @@
+ const Elf_Shdr *RB = B->RelocSections[0];
+ if (RA->sh_type != RB->sh_type)
+ return false;
----------------
rafael wrote:
> I don't think this is possible.
>
> It is all SHT_RELA or SHT_REL.
Removed.
================
Comment at: ELF/ICF.cpp:247
@@ +246,3 @@
+ A->getSize() == B->getSize() &&
+ A->getAlign() == B->getAlign() &&
+ A->getSectionData() == B->getSectionData();
----------------
rafael wrote:
> It is possible to merge when the alignment is different, we just have to keep the larger one. A fixme for now is fine.
>
Done.
================
Comment at: ELF/ICF.cpp:262
@@ +261,3 @@
+ if (EA - IA != EB - IB)
+ return false;
+ for (; IA != EA; ++IA, ++IB) {
----------------
rafael wrote:
> The same 'if' is in equalsContant. Do you need it here?
Removed.
================
Comment at: ELF/ICF.cpp:268
@@ +267,3 @@
+ continue;
+ if (!SA || !SB)
+ return false;
----------------
rafael wrote:
> If both are null they could still be equal, no?
>
> FIXME for now is fine.
Yes, and in that case the above `if (SA== SB)` should be true, so it should already be covered.
================
Comment at: ELF/ICF.cpp:272
@@ +271,3 @@
+ InputSection<ELFT> *Y = dyn_cast<InputSection<ELFT>>(SB);
+ if (!X || !Y || X->GroupId != Y->GroupId)
+ return false;
----------------
rafael wrote:
> This is also conservatively correct, right?
>
> Two relocations pointing to the string "foobar" in a SHF_MERGE section are equivalent.
I believe the above `if (SA == SB)` should cover most cases already.
================
Comment at: ELF/ICF.cpp:311
@@ +310,3 @@
+ // the same group are consecutive in the vector.
+ std::sort(V.begin(), V.end(),
+ [](InputSection<ELFT> *A, InputSection<ELFT> *B) {
----------------
rafael wrote:
> Do we need stable_sort to make this deterministic?
Done.
================
Comment at: ELF/InputSection.cpp:31
@@ +30,3 @@
+ // If GC is disabled, all sections are considered live by default.
+ Live = Config && !Config->GcSections;
+}
----------------
rafael wrote:
> When is Config null?
`Discarded` section is initialized statically, and when it is initialized, Config is still null.
================
Comment at: ELF/InputSection.cpp:75
@@ -70,3 +74,3 @@
InputSectionBase<ELFT> *
-InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) {
+InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) const {
// Global symbol
----------------
rafael wrote:
> Can you commit the const fixes first?
Done.
================
Comment at: ELF/OutputSections.cpp:1151
@@ -1150,3 +1151,3 @@
InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI);
- if (Target != &InputSection<ELFT>::Discarded && Target->isLive()) {
uint32_t CieOffset = Offset + 4 - ID;
----------------
rafael wrote:
> Can you commit the s/isLife/Life/ change first?
Done.
================
Comment at: ELF/Symbols.h:236
@@ +235,3 @@
+ // If this is null, the symbol is an absolute symbol.
+ InputSectionBase<ELFT> *&Section;
+
----------------
rafael wrote:
> Not sure I follow. Why is this not redundant with the Repl pointer in the section?
In many places we write Sym->Section to get an input section for the symbol. We either update all such occurrences with Sym->Section->Repl, or make Section a reference like this.
http://reviews.llvm.org/D17529
More information about the llvm-commits
mailing list