[lld] [RISCV][LLD] Zcmt RISC-V extension in lld (PR #183450)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 8 00:25:43 PDT 2026
================
@@ -1630,3 +1770,89 @@ void elf::mergeRISCVAttributesSections(Ctx &ctx) {
}
void elf::setRISCVTargetInfo(Ctx &ctx) { ctx.target.reset(new RISCV(ctx)); }
+
+TableJumpSection::TableJumpSection(Ctx &ctx)
+ : SyntheticSection(ctx, ".riscv.jvt", SHT_PROGBITS, SHF_ALLOC,
+ /*alignment=*/64) {}
+
+int TableJumpSection::getCMJTEntryIndex(const Symbol *sym) const {
+ auto it = cmjtCandidates.find(sym);
+ return it != cmjtCandidates.end() ? it->second.index : -1;
+}
+
+int TableJumpSection::getCMJALTEntryIndex(const Symbol *sym) const {
+ auto it = cmjaltCandidates.find(sym);
+ return it != cmjaltCandidates.end() ? it->second.index : -1;
+}
+
+void TableJumpSection::addEntry(const Symbol *sym, int saved, bool isCMJT) {
+ auto &candidates = isCMJT ? cmjtCandidates : cmjaltCandidates;
+ candidates.try_emplace(sym, TableJumpEntry{0, -1}).first->second.saved +=
+ saved;
+}
+
+// Sort candidates by code size reduction (descending), truncate to maxSize,
+// drop entries whose reduction doesn't cover a table entry, and assign each
+// survivor a table index starting at baseIdx.
+static void
+selectEntries(Ctx &ctx,
+ llvm::MapVector<const Symbol *, TableJumpEntry> &candidates,
+ uint32_t maxSize, uint32_t baseIdx) {
+ SmallVector<std::pair<const Symbol *, TableJumpEntry>, 0> entries(
+ candidates.begin(), candidates.end());
+ // MapVector iteration is in insertion order, so stable_sort gives a
+ // deterministic ordering keyed on saved bytes descending.
+ llvm::stable_sort(entries, [](const auto &a, const auto &b) {
+ return a.second.saved > b.second.saved;
+ });
+ if (entries.size() > maxSize)
+ entries.resize(maxSize);
+ while (!entries.empty() &&
+ entries.back().second.saved < (int)ctx.arg.wordsize)
+ entries.pop_back();
+
+ candidates.clear();
+ for (auto [i, entry] : llvm::enumerate(entries))
+ candidates[entry.first] = {entry.second.saved, (int)(baseIdx + i)};
+}
+
+void TableJumpSection::finalizeContents() {
+ selectEntries(ctx, cmjtCandidates, maxCMJTEntrySize, /*baseIdx=*/0);
+ selectEntries(ctx, cmjaltCandidates, maxCMJALTEntrySize, startCMJALTEntryIdx);
+
+ int cmjtBenefit = 0, cmjaltBenefit = 0;
+ for (auto &[_, e] : cmjtCandidates)
+ cmjtBenefit += e.saved;
+ for (auto &[_, e] : cmjaltCandidates)
+ cmjaltBenefit += e.saved;
+
+ // cm.jalt forces padding the cm.jt region to startCMJALTEntryIdx entries.
+ // Drop cm.jalt if its benefit doesn't cover the padding plus its own entries.
+ size_t pad = startCMJALTEntryIdx - cmjtCandidates.size();
+ if (cmjaltBenefit < (int)((pad + cmjaltCandidates.size()) * ctx.arg.wordsize))
+ cmjaltCandidates.clear();
+
+ // Give up entirely if cm.jt doesn't reduce code size.
+ if (cmjtBenefit <= (int)(cmjtCandidates.size() * ctx.arg.wordsize)) {
+ Log(ctx) << "table jump relaxation didn't reduce code size";
+ cmjtCandidates.clear();
+ cmjaltCandidates.clear();
+ }
+}
+
+size_t TableJumpSection::getSize() const {
+ if (!cmjaltCandidates.empty())
+ return (startCMJALTEntryIdx + cmjaltCandidates.size()) * ctx.arg.wordsize;
+ return cmjtCandidates.size() * ctx.arg.wordsize;
+}
+
+void TableJumpSection::writeTo(uint8_t *buf) {
+ for (auto *cands : {&cmjtCandidates, &cmjaltCandidates})
+ for (auto &[sym, entry] : *cands) {
+ uint8_t *p = buf + entry.index * ctx.arg.wordsize;
+ if (ctx.arg.is64)
+ write64le(p, sym->getVA(ctx));
----------------
LukeZhuang wrote:
Done
https://github.com/llvm/llvm-project/pull/183450
More information about the llvm-commits
mailing list