[PATCH] D65242: [ELF] More dynamic relocation packing
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 29 01:05:04 PDT 2019
Looks like Phabricator is having a problem, so I'll review this patch in
emai.
On Thu, Jul 25, 2019 at 6:10 AM Vic Yang via Phabricator <
reviews at reviews.llvm.org> wrote:
> 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;
> + });
>
A r_info consists of a symbol offset and a relocation type. If I understand
correctly, you basically want to sort symbols by symbol offset -- am I
correct? If so, maybe you want to make it explicit by sorting only by
symbol offset?
I also found this comment little bit confusing -- the 2nd line and after
that it explains the cost of something, but what is the cost? Or, first of
all, why do you want to sort relocations by r_info? I'd explain that first.
+ 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 --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190729/9874d3e4/attachment.html>
More information about the llvm-commits
mailing list