summaryrefslogtreecommitdiffstats
path: root/lld/ELF/ICF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/ICF.cpp')
-rw-r--r--lld/ELF/ICF.cpp52
1 files changed, 25 insertions, 27 deletions
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 8dace92fe97..db802fd5868 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -102,11 +102,11 @@ private:
bool constantEq(ArrayRef<RelTy> RelsA, ArrayRef<RelTy> RelsB);
template <class RelTy>
- bool variableEq(const InputSection<ELFT> *A, ArrayRef<RelTy> RelsA,
- const InputSection<ELFT> *B, ArrayRef<RelTy> RelsB);
+ bool variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
+ const InputSection *B, ArrayRef<RelTy> RelsB);
- bool equalsConstant(const InputSection<ELFT> *A, const InputSection<ELFT> *B);
- bool equalsVariable(const InputSection<ELFT> *A, const InputSection<ELFT> *B);
+ bool equalsConstant(const InputSection *A, const InputSection *B);
+ bool equalsVariable(const InputSection *A, const InputSection *B);
size_t findBoundary(size_t Begin, size_t End);
@@ -115,7 +115,7 @@ private:
void forEachClass(std::function<void(size_t, size_t)> Fn);
- std::vector<InputSection<ELFT> *> Sections;
+ std::vector<InputSection *> Sections;
// We repeat the main loop while `Repeat` is true.
std::atomic<bool> Repeat;
@@ -154,12 +154,12 @@ private:
// Returns a hash value for S. Note that the information about
// relocation targets is not included in the hash value.
-template <class ELFT> static uint32_t getHash(InputSection<ELFT> *S) {
+template <class ELFT> static uint32_t getHash(InputSection *S) {
return hash_combine(S->Flags, S->template getSize<ELFT>(), S->NumRelocations);
}
// Returns true if section S is subject of ICF.
-template <class ELFT> static bool isEligible(InputSection<ELFT> *S) {
+template <class ELFT> static bool isEligible(InputSection *S) {
// .init and .fini contains instructions that must be executed to
// initialize and finalize the process. They cannot and should not
// be merged.
@@ -181,13 +181,13 @@ void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) {
while (Begin < End) {
// Divide [Begin, End) into two. Let Mid be the start index of the
// second group.
- auto Bound = std::stable_partition(
- Sections.begin() + Begin + 1, Sections.begin() + End,
- [&](InputSection<ELFT> *S) {
- if (Constant)
- return equalsConstant(Sections[Begin], S);
- return equalsVariable(Sections[Begin], S);
- });
+ auto Bound =
+ std::stable_partition(Sections.begin() + Begin + 1,
+ Sections.begin() + End, [&](InputSection *S) {
+ if (Constant)
+ return equalsConstant(Sections[Begin], S);
+ return equalsVariable(Sections[Begin], S);
+ });
size_t Mid = Bound - Sections.begin();
// Now we split [Begin, End) into [Begin, Mid) and [Mid, End) by
@@ -221,8 +221,7 @@ bool ICF<ELFT>::constantEq(ArrayRef<RelTy> RelsA, ArrayRef<RelTy> RelsB) {
// Compare "non-moving" part of two InputSections, namely everything
// except relocation targets.
template <class ELFT>
-bool ICF<ELFT>::equalsConstant(const InputSection<ELFT> *A,
- const InputSection<ELFT> *B) {
+bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||
A->template getSize<ELFT>() != B->template getSize<ELFT>() ||
A->Data != B->Data)
@@ -237,8 +236,8 @@ bool ICF<ELFT>::equalsConstant(const InputSection<ELFT> *A,
// relocations point to the same section in terms of ICF.
template <class ELFT>
template <class RelTy>
-bool ICF<ELFT>::variableEq(const InputSection<ELFT> *A, ArrayRef<RelTy> RelsA,
- const InputSection<ELFT> *B, ArrayRef<RelTy> RelsB) {
+bool ICF<ELFT>::variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
+ const InputSection *B, ArrayRef<RelTy> RelsB) {
auto Eq = [&](const RelTy &RA, const RelTy &RB) {
// The two sections must be identical.
SymbolBody &SA = A->template getFile<ELFT>()->getRelocTargetSym(RA);
@@ -258,8 +257,8 @@ bool ICF<ELFT>::variableEq(const InputSection<ELFT> *A, ArrayRef<RelTy> RelsA,
return !DA->Section && !DB->Section;
// Or the two sections must be in the same equivalence class.
- auto *X = dyn_cast<InputSection<ELFT>>(DA->Section);
- auto *Y = dyn_cast<InputSection<ELFT>>(DB->Section);
+ auto *X = dyn_cast<InputSection>(DA->Section);
+ auto *Y = dyn_cast<InputSection>(DB->Section);
if (!X || !Y)
return false;
@@ -276,8 +275,7 @@ bool ICF<ELFT>::variableEq(const InputSection<ELFT> *A, ArrayRef<RelTy> RelsA,
// Compare "moving" part of two InputSections, namely relocation targets.
template <class ELFT>
-bool ICF<ELFT>::equalsVariable(const InputSection<ELFT> *A,
- const InputSection<ELFT> *B) {
+bool ICF<ELFT>::equalsVariable(const InputSection *A, const InputSection *B) {
if (A->AreRelocsRela)
return variableEq(A, A->template relas<ELFT>(), B,
B->template relas<ELFT>());
@@ -339,19 +337,19 @@ void ICF<ELFT>::forEachClass(std::function<void(size_t, size_t)> Fn) {
template <class ELFT> void ICF<ELFT>::run() {
// Collect sections to merge.
for (InputSectionBase *Sec : Symtab<ELFT>::X->Sections)
- if (auto *S = dyn_cast<InputSection<ELFT>>(Sec))
- if (isEligible(S))
+ if (auto *S = dyn_cast<InputSection>(Sec))
+ if (isEligible<ELFT>(S))
Sections.push_back(S);
// Initially, we use hash values to partition sections.
- for (InputSection<ELFT> *S : Sections)
+ for (InputSection *S : Sections)
// Set MSB to 1 to avoid collisions with non-hash IDs.
- S->Class[0] = getHash(S) | (1 << 31);
+ S->Class[0] = getHash<ELFT>(S) | (1 << 31);
// From now on, sections in Sections vector are ordered so that sections
// in the same equivalence class are consecutive in the vector.
std::stable_sort(Sections.begin(), Sections.end(),
- [](InputSection<ELFT> *A, InputSection<ELFT> *B) {
+ [](InputSection *A, InputSection *B) {
return A->Class[0] < B->Class[0];
});
OpenPOWER on IntegriCloud