[PATCH] D65242: [ELF] More dynamic relocation packing
Vic Yang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 24 14:10:40 PDT 2019
victoryang created this revision.
victoryang added a reviewer: ruiu.
Herald added subscribers: llvm-commits, mgrang, MaskRay, kristof.beyls, arichardson, javed.absar, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
Currently, with Android dynamic relocation packing, only relative
relocations are grouped together. This patch implements similar
packing for non-relative relocations.
The implementation groups non-relative relocations with the same
r_info. By requiring a minimum group size of 3, this achieves
smaller relocation sections. Linking libmonochrome in Chromium for
Android, targeting ARM32, I see a .rel.dyn of size 127697 bytes, as
compared to 150532 bytes without this change.
Grouping by r_info also allows the runtime dynamic linker to implement
an 1-entry cache to reduce the number of symbol lookup required. Such
a cache would hit 11167 times for libmonochrome, as compared to 4107
times without this change.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D65242
Files:
lld/ELF/SyntheticSections.cpp
Index: lld/ELF/SyntheticSections.cpp
===================================================================
--- lld/ELF/SyntheticSections.cpp
+++ lld/ELF/SyntheticSections.cpp
@@ -1679,6 +1679,35 @@
relativeGroups.emplace_back(std::move(group));
}
+ // Sort by r_info first so that we can group relocations with the same r_info.
+ // The cost of each group varies based on r_info, but we can approximate the
+ // cost analysis by the number of values encoded. Each group adds 3 values to
+ // be encoded, and each relocation in a group encodes one less value, so we
+ // only group relocations if there are 3 or more of them with the same r_info.
+ llvm::sort(nonRelatives, [](const Elf_Rela &a, const Elf_Rela &b) {
+ return a.r_info < b.r_info;
+ });
+
+ std::vector<Elf_Rela> ungroupedNonRelatives;
+ std::vector<std::vector<Elf_Rela>> nonRelativeGroups;
+ for (auto i = nonRelatives.begin(), e = nonRelatives.end(); i != e;) {
+ std::vector<Elf_Rela> group;
+ do {
+ group.push_back(*i++);
+ } while (i != e && (i - 1)->r_info == i->r_info);
+
+ if (group.size() < 3)
+ ungroupedNonRelatives.insert(ungroupedNonRelatives.end(), group.begin(),
+ group.end());
+ else
+ nonRelativeGroups.emplace_back(std::move(group));
+ }
+
+ // Sort ungrouped relocations by offset to minimize the encoded length.
+ llvm::sort(ungroupedNonRelatives, [](const Elf_Rela &a, const Elf_Rela &b) {
+ return a.r_offset < b.r_offset;
+ });
+
unsigned hasAddendIfRela =
config->isRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
@@ -1733,14 +1762,26 @@
}
}
- // Finally the non-relative relocations.
- llvm::sort(nonRelatives, [](const Elf_Rela &a, const Elf_Rela &b) {
- return a.r_offset < b.r_offset;
- });
- if (!nonRelatives.empty()) {
- add(nonRelatives.size());
+ // Grouped non-relatives.
+ for (std::vector<Elf_Rela> &g : nonRelativeGroups) {
+ add(g.size());
+ add(RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
+ add(g[0].r_info);
+ for (Elf_Rela &r : g) {
+ add(r.r_offset - offset);
+ offset = r.r_offset;
+ if (config->isRela) {
+ add(r.r_addend - addend);
+ addend = r.r_addend;
+ }
+ }
+ }
+
+ // Finally the ungrouped non-relative relocations.
+ if (!ungroupedNonRelatives.empty()) {
+ add(ungroupedNonRelatives.size());
add(hasAddendIfRela);
- for (Elf_Rela &r : nonRelatives) {
+ for (Elf_Rela &r : ungroupedNonRelatives) {
add(r.r_offset - offset);
offset = r.r_offset;
add(r.r_info);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65242.211598.patch
Type: text/x-patch
Size: 2601 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190724/a9f4412f/attachment.bin>
More information about the llvm-commits
mailing list