Define DefinedAtom::sectionSize.
Merge::mergeByLargestSection is half-baked since it's defined
in terms of section size, there's no way to get the section size
of an atom.
Currently we work around the issue by traversing the layout edges
to both directions and calculate the sum of all atoms reachable.
I wrote that code but I knew it's hacky. It's even not guaranteed
to work. If you add layout edges before the core linking, it
miscalculates a size.
Also it's of course slow. It's basically a linked list traversal.
In this patch I added DefinedAtom::sectionSize so that we can use
that for mergeByLargestSection. I'm not very happy to add a new
field to DefinedAtom base class, but I think it's legitimate since
mergeByLargestSection is defined for section size, and the section
size is currently just missing.
http://reviews.llvm.org/D7966
llvm-svn: 231290
diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp
index b06cdec..d264cb7 100644
--- a/lld/lib/Core/SymbolTable.cpp
+++ b/lld/lib/Core/SymbolTable.cpp
@@ -133,36 +133,6 @@
return mergeCases[first][second];
}
-static const DefinedAtom *followReference(const DefinedAtom *atom,
- uint32_t kind) {
- for (const Reference *r : *atom)
- if (r->kindNamespace() == Reference::KindNamespace::all &&
- r->kindArch() == Reference::KindArch::all &&
- r->kindValue() == kind)
- return cast<const DefinedAtom>(r->target());
- return nullptr;
-}
-
-static uint64_t getSizeFollowReferences(const DefinedAtom *atom,
- uint32_t kind) {
- uint64_t size = 0;
- for (;;) {
- atom = followReference(atom, kind);
- if (!atom)
- return size;
- size += atom->size();
- }
-}
-
-// Returns the size of the section containing the given atom. Atoms in the same
-// section are connected by layout-before and layout-after edges, so this
-// function traverses them to get the total size of atoms in the same section.
-static uint64_t sectionSize(const DefinedAtom *atom) {
- return atom->size()
- + getSizeFollowReferences(atom, lld::Reference::kindLayoutBefore)
- + getSizeFollowReferences(atom, lld::Reference::kindLayoutAfter);
-}
-
bool SymbolTable::addByName(const Atom &newAtom) {
StringRef name = newAtom.name();
assert(!name.empty());
@@ -198,14 +168,14 @@
useNew = true;
break;
case MCR_Largest: {
- uint64_t existingSize = sectionSize(existingDef);
- uint64_t newSize = sectionSize(newDef);
+ uint64_t existingSize = existingDef->sectionSize();
+ uint64_t newSize = newDef->sectionSize();
useNew = (newSize >= existingSize);
break;
}
case MCR_SameSize: {
- uint64_t existingSize = sectionSize(existingDef);
- uint64_t newSize = sectionSize(newDef);
+ uint64_t existingSize = existingDef->sectionSize();
+ uint64_t newSize = newDef->sectionSize();
if (existingSize == newSize) {
useNew = true;
break;