Skip to content

[JITLink][RISCV] Use hashmap to find PCREL_HI20 edge #78849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 35 additions & 33 deletions llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,38 +133,6 @@ const uint8_t
namespace llvm {
namespace jitlink {

static Expected<const Edge &> getRISCVPCRelHi20(const Edge &E) {
using namespace riscv;
assert((E.getKind() == R_RISCV_PCREL_LO12_I ||
E.getKind() == R_RISCV_PCREL_LO12_S) &&
"Can only have high relocation for R_RISCV_PCREL_LO12_I or "
"R_RISCV_PCREL_LO12_S");

const Symbol &Sym = E.getTarget();
const Block &B = Sym.getBlock();
orc::ExecutorAddrDiff Offset = Sym.getOffset();

struct Comp {
bool operator()(const Edge &Lhs, orc::ExecutorAddrDiff Offset) {
return Lhs.getOffset() < Offset;
}
bool operator()(orc::ExecutorAddrDiff Offset, const Edge &Rhs) {
return Offset < Rhs.getOffset();
}
};

auto Bound =
std::equal_range(B.edges().begin(), B.edges().end(), Offset, Comp{});

for (auto It = Bound.first; It != Bound.second; ++It) {
if (It->getKind() == R_RISCV_PCREL_HI20)
return *It;
}

return make_error<JITLinkError>(
"No HI20 PCREL relocation type be found for LO12 PCREL relocation type");
}

static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
return (Num & (((1ULL << Size) - 1) << Low)) >> Low;
}
Expand All @@ -184,9 +152,43 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
public:
ELFJITLinker_riscv(std::unique_ptr<JITLinkContext> Ctx,
std::unique_ptr<LinkGraph> G, PassConfiguration PassConfig)
: JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {}
: JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {
JITLinkerBase::getPassConfig().PostAllocationPasses.push_back(
[this](LinkGraph &G) { return gatherRISCVPCRelHi20(G); });
}

private:
DenseMap<std::pair<const Block *, orc::ExecutorAddrDiff>, const Edge *>
RelHi20;

Error gatherRISCVPCRelHi20(LinkGraph &G) {
for (Block *B : G.blocks())
for (Edge &E : B->edges())
if (E.getKind() == R_RISCV_PCREL_HI20)
RelHi20[{B, E.getOffset()}] = &E;

return Error::success();
}

Expected<const Edge &> getRISCVPCRelHi20(const Edge &E) const {
using namespace riscv;
assert((E.getKind() == R_RISCV_PCREL_LO12_I ||
E.getKind() == R_RISCV_PCREL_LO12_S) &&
"Can only have high relocation for R_RISCV_PCREL_LO12_I or "
"R_RISCV_PCREL_LO12_S");

const Symbol &Sym = E.getTarget();
const Block &B = Sym.getBlock();
orc::ExecutorAddrDiff Offset = Sym.getOffset();

auto It = RelHi20.find({&B, Offset});
if (It != RelHi20.end())
return *It->second;

return make_error<JITLinkError>("No HI20 PCREL relocation type be found "
"for LO12 PCREL relocation type");
}

Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
using namespace riscv;
using namespace llvm::support;
Expand Down