[llvm] [JITLink] Add GOT indirection optimization for SystemZ (PR #171919)
Ulrich Weigand via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 12 04:15:12 PST 2025
================
@@ -106,11 +106,51 @@ const char *getEdgeKindName(Edge::Kind R) {
return "RequestGOTAndTransformToDelta32dbl";
case RequestTLSDescInGOTAndTransformToDelta64FromGOT:
return "RequestTLSDescInGOTAndTransformToDelta64FromGOT";
+ case Delta32dblToPtrJumpStubBypassable:
+ return "Delta32dblToPtrJumpStubBypassable";
default:
return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
}
}
+Error optimizeGOTAndStubAccesses(LinkGraph &G) {
+ LLVM_DEBUG(dbgs() << "Optimizing GOT entries and stubs:\n");
+
+ for (auto *B : G.blocks())
+ for (auto &E : B->edges()) {
+ if (E.getKind() == systemz::Delta32dblToPtrJumpStubBypassable) {
+ auto &StubBlock = E.getTarget().getBlock();
+ assert(StubBlock.getSize() == sizeof(Pointer64JumpStubContent) &&
+ "Stub block should be stub sized");
+ assert(StubBlock.edges_size() == 1 &&
+ "Stub block should only have one outgoing edge");
+
+ auto &GOTBlock = StubBlock.edges().begin()->getTarget().getBlock();
+ assert(GOTBlock.getSize() == G.getPointerSize() &&
+ "GOT block should be pointer sized");
+ assert(GOTBlock.edges_size() == 1 &&
+ "GOT block should only have one outgoing edge");
+
+ auto &GOTTarget = GOTBlock.edges().begin()->getTarget();
+ orc::ExecutorAddr EdgeAddr = B->getAddress() + E.getOffset();
+ orc::ExecutorAddr TargetAddr = GOTTarget.getAddress();
+
+ int64_t Displacement = TargetAddr - EdgeAddr;
----------------
uweigand wrote:
I think we need to take the addend into account here. `R_390_PTL32DBL` relocations on a `brasl` instruction usually have an added of 2, as the instruction is a branch relative to the PC at the beginning of the instruction, but the relocation is computed as a delta relative to the field starting at 2 bytes into the instruction. That's why in `applyFixup` we have:
```
case DeltaPLT32dbl: {
int64_t Value = S + A - P;
if (!LLVM_UNLIKELY(isInt<33>(Value)))
return makeTargetOutOfRangeError(G, B, E);
```
where `S` corresponds to `TargetAddr` here and `P` corresponds to `FixupAddr` here, but the `A` is missing. This should be something like:
```
int64_t Displacement = TargetAddr + E.getAddend() - EdgeAddr;
```
https://github.com/llvm/llvm-project/pull/171919
More information about the llvm-commits
mailing list