summaryrefslogtreecommitdiff
path: root/lld/COFF/ICF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/COFF/ICF.cpp')
-rw-r--r--lld/COFF/ICF.cpp21
1 files changed, 12 insertions, 9 deletions
diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp
index c821569e3457..1b33634b63d6 100644
--- a/lld/COFF/ICF.cpp
+++ b/lld/COFF/ICF.cpp
@@ -21,7 +21,6 @@
#include "Chunks.h"
#include "Symbols.h"
#include "lld/Common/ErrorHandler.h"
-#include "lld/Common/Threads.h"
#include "lld/Common/Timer.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/Debug.h"
@@ -127,15 +126,19 @@ void ICF::segregate(size_t begin, size_t end, bool constant) {
// Returns true if two sections' associative children are equal.
bool ICF::assocEquals(const SectionChunk *a, const SectionChunk *b) {
- auto childClasses = [&](const SectionChunk *sc) {
- std::vector<uint32_t> classes;
- for (const SectionChunk &c : sc->children())
- if (!c.getSectionName().startswith(".debug") &&
- c.getSectionName() != ".gfids$y" && c.getSectionName() != ".gljmp$y")
- classes.push_back(c.eqClass[cnt % 2]);
- return classes;
+ // Ignore associated metadata sections that don't participate in ICF, such as
+ // debug info and CFGuard metadata.
+ auto considerForICF = [](const SectionChunk &assoc) {
+ StringRef Name = assoc.getSectionName();
+ return !(Name.startswith(".debug") || Name == ".gfids$y" ||
+ Name == ".gljmp$y");
};
- return childClasses(a) == childClasses(b);
+ auto ra = make_filter_range(a->children(), considerForICF);
+ auto rb = make_filter_range(b->children(), considerForICF);
+ return std::equal(ra.begin(), ra.end(), rb.begin(), rb.end(),
+ [&](const SectionChunk &ia, const SectionChunk &ib) {
+ return ia.eqClass[cnt % 2] == ib.eqClass[cnt % 2];
+ });
}
// Compare "non-moving" part of two sections, namely everything