[PATCH] D100835: [WIP][LLD][RISCV] Linker Relaxation
Jessica Clarke via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 20 03:16:35 PDT 2021
jrtc27 added a comment.
Why write your own deleteRanges? I took great care in writing mine to ensure there were no hidden quadratic complexities, but your simpler version has introduced them. Just take mine, unless there is a problem with it nobody's mentioned. Same goes for mutableData being a less efficient version of mine.
I also don't like making this overly target-specific. We should take the time to get the interface right, not just punt on it and shove it all into target-specific code.
================
Comment at: lld/ELF/Arch/RISCV.cpp:617
+
+ Relocation *rel = std::prev(r);
+ if (r->offset != rel->offset)
----------------
Can we not just keep two iterators around? That feels nicer to me than careful +1s everywhere (e.g. it's not immediately obvious this won't crash on the first element until you look at the start point of the loop).
================
Comment at: lld/ELF/Arch/RISCV.cpp:637-638
+ auto &rels = is->relocations;
+ if (rels.empty())
+ continue;
+
----------------
This condition seems unnecessary
================
Comment at: lld/ELF/Arch/RISCV.cpp:686
+ for (auto &rel : is->relocations) {
+ if (rel.type == R_RISCV_ALIGN && rel.addend > 0) {
+ uint64_t pc = is->getVA(rel.offset) - bytesDeleted;
----------------
When would the addend ever be 0? That seems like invalid input.
================
Comment at: lld/ELF/Arch/RISCV.cpp:733-734
+ if (config->relax && !config->relocatable) {
+ // Try to iteratively perform relaxation for up to 5 times.
+ for (int i = 0; i < 5; ++i) {
+ if (!relax())
----------------
Why a limit of 5? It is guaranteed to converge, I don't see why there needs to be a limit, and it'll probably take just 1 or 2 almost all of the time.
================
Comment at: lld/ELF/Arch/RISCV.cpp:740
+
+ relaxAlign();
+}
----------------
Not for relocatable
================
Comment at: lld/ELF/InputSection.cpp:195-196
+ auto it = ranges.begin();
+ for (auto *dr : symbols) {
+ for (auto e = ranges.end(); it != e && it->first < dr->value; ++it)
+ removedBytes += it->second;
----------------
This looks quadratic
================
Comment at: lld/ELF/InputSection.cpp:216-217
+ auto it = ranges.begin();
+ for (auto *dr : symbols) {
+ for (auto e = ranges.end(); it != e && it->first < endOff(dr); ++it)
+ removedBytes += it->second;
----------------
As does this
================
Comment at: lld/ELF/InputSection.cpp:227-228
+ auto it = ranges.begin();
+ for (auto &rel : relocations) {
+ for (auto e = ranges.end(); it != e && it->first < rel.offset; ++it)
+ removedBytes += it->second;
----------------
And this
================
Comment at: lld/ELF/InputSection.h:162
+ MutableArrayRef<uint8_t> mutableData() {
+ if (mutData != data().data()) {
----------------
Make the relevant fields mutable and mark this const, like data()
================
Comment at: lld/ELF/InputSection.h:173
+
+ using DeleteRanges = std::map<uint64_t, uint64_t>;
+ void deleteRanges(const DeleteRanges &deleteRanges);
----------------
std::map seems like a high-overhead way to store what is just a sorted list of intervals.
================
Comment at: lld/ELF/InputSection.h:260
mutable ArrayRef<uint8_t> rawData;
+ uint8_t *mutData;
----------------
Why do we need a whole new pointer when rawData is also being updated?
================
Comment at: lld/ELF/Relocations.cpp:135
+template <RelExpr... Exprs> struct RelExprMaskTester {
+ static inline bool test(RelExpr expr) { return false; }
};
----------------
(a) this is unrelated to the diff
(b) this completely removes the whole point of oneof
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D100835/new/
https://reviews.llvm.org/D100835
More information about the llvm-commits
mailing list