Skip to content

Commit 11a02de

Browse files
author
Kai Luo
committed
[JITLink][PowerPC] Change method to check if a symbol is external to current object
After PrePrunePass `claimOrExternalizeWeakAndCommonSymbols`, a defined symbol might become external. So determine a function call is external or not when building the linkgraph is not accurate. This largely affects updating TOC pointer on PowerPC. TOC pointer is supposed to be the same in one object file(if no mulitple TOC appears) and is updated when control flow transferred to another object file. This patch defers checking a function call is external or not, in `buildTables_ELF_ppc64` which is a PostPrunePass. This patch fixes failures when `jitlink -orc-runtime=/path/to/libort_rt.a` is used. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D155925
1 parent cdffaac commit 11a02de

File tree

4 files changed

+36
-36
lines changed

4 files changed

+36
-36
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,18 @@ enum EdgeKind_ppc64 : Edge::Kind {
3636
CallBranchDelta,
3737
// Need to restore r2 after the bl, suggesting the bl is followed by a nop.
3838
CallBranchDeltaRestoreTOC,
39-
// Need PLT call stub using TOC, TOC pointer is not saved before branching.
40-
RequestPLTCallStub,
41-
// Need PLT call stub using TOC, TOC pointer is saved before branching.
42-
RequestPLTCallStubSaveTOC,
43-
// Need PLT call stub without using TOC.
44-
RequestPLTCallStubNoTOC,
39+
// Request calling function with TOC.
40+
RequestCall,
41+
// Request calling function without TOC.
42+
RequestCallNoTOC,
4543
};
4644

4745
enum PLTCallStubKind {
46+
// Setup function entry(r12) and long branch to target using TOC.
4847
LongBranch,
48+
// Save TOC pointer, setup function entry and long branch to target using TOC.
4949
LongBranchSaveR2,
50+
// Setup function entry(r12) and long branch to target without using TOC.
5051
LongBranchNoTOC,
5152
};
5253

@@ -141,8 +142,7 @@ class TOCTableManager : public TableManager<TOCTableManager<Endianness>> {
141142
case TOCDelta16DS:
142143
case TOCDelta16LODS:
143144
case CallBranchDeltaRestoreTOC:
144-
case RequestPLTCallStub:
145-
case RequestPLTCallStubSaveTOC:
145+
case RequestCall:
146146
// Create TOC section if TOC relocation, PLT or GOT is used.
147147
getOrCreateTOCSection(G);
148148
return false;
@@ -174,14 +174,25 @@ class PLTTableManager : public TableManager<PLTTableManager<Endianness>> {
174174
static StringRef getSectionName() { return "$__STUBS"; }
175175

176176
bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
177+
bool isExternal = E.getTarget().isExternal();
177178
Edge::Kind K = E.getKind();
178-
if (K == ppc64::RequestPLTCallStubSaveTOC && E.getTarget().isExternal()) {
179-
E.setKind(ppc64::CallBranchDeltaRestoreTOC);
180-
this->StubKind = LongBranchSaveR2;
181-
E.setTarget(this->getEntryForTarget(G, E.getTarget()));
179+
if (K == ppc64::RequestCall) {
180+
if (isExternal) {
181+
E.setKind(ppc64::CallBranchDeltaRestoreTOC);
182+
this->StubKind = LongBranchSaveR2;
183+
E.setTarget(this->getEntryForTarget(G, E.getTarget()));
184+
// We previously set branching to local entry. Now reverse that
185+
// operation.
186+
E.setAddend(0);
187+
} else
188+
// TODO: There are cases a local function call need a call stub.
189+
// 1. Caller uses TOC, the callee doesn't, need a r2 save stub.
190+
// 2. Caller doesn't use TOC, the callee does, need a r12 setup stub.
191+
// 3. Branching target is out of range.
192+
E.setKind(ppc64::CallBranchDelta);
182193
return true;
183194
}
184-
if (K == ppc64::RequestPLTCallStubNoTOC && E.getTarget().isExternal()) {
195+
if (K == ppc64::RequestCallNoTOC) {
185196
E.setKind(ppc64::CallBranchDelta);
186197
this->StubKind = LongBranchNoTOC;
187198
E.setTarget(this->getEntryForTarget(G, E.getTarget()));

llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -217,23 +217,14 @@ class ELFLinkGraphBuilder_ppc64
217217
Kind = ppc64::Delta32;
218218
break;
219219
case ELF::R_PPC64_REL24_NOTOC:
220-
case ELF::R_PPC64_REL24: {
221-
bool isLocal = !GraphSymbol->isExternal();
222-
if (isLocal) {
223-
// TODO: There are cases a local function call need a call stub.
224-
// 1. Caller uses TOC, the callee doesn't, need a r2 save stub.
225-
// 2. Caller doesn't use TOC, the callee does, need a r12 setup stub.
226-
// FIXME: For a local call, we might need a thunk if branch target is
227-
// out of range.
228-
Kind = ppc64::CallBranchDelta;
229-
// Branch to local entry.
230-
Addend += ELF::decodePPC64LocalEntryOffset((*ObjSymbol)->st_other);
231-
} else {
232-
Kind = ELFReloc == ELF::R_PPC64_REL24 ? ppc64::RequestPLTCallStubSaveTOC
233-
: ppc64::RequestPLTCallStubNoTOC;
234-
}
220+
Kind = ppc64::RequestCallNoTOC;
221+
break;
222+
case ELF::R_PPC64_REL24:
223+
Kind = ppc64::RequestCall;
224+
assert(Addend == 0 && "Addend is expected to be 0 for a function call");
225+
// We assume branching to local entry, will reverse the addend if not.
226+
Addend = ELF::decodePPC64LocalEntryOffset((*ObjSymbol)->st_other);
235227
break;
236-
}
237228
case ELF::R_PPC64_REL64:
238229
Kind = ppc64::Delta64;
239230
break;

llvm/lib/ExecutionEngine/JITLink/ppc64.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,10 @@ const char *getEdgeKindName(Edge::Kind K) {
8888
return "CallBranchDelta";
8989
case CallBranchDeltaRestoreTOC:
9090
return "CallBranchDeltaRestoreTOC";
91-
case RequestPLTCallStub:
92-
return "RequestPLTCallStub";
93-
case RequestPLTCallStubSaveTOC:
94-
return "RequestPLTCallStubSaveTOC";
95-
case RequestPLTCallStubNoTOC:
96-
return "RequestPLTCallStubNoTOC";
91+
case RequestCall:
92+
return "RequestCall";
93+
case RequestCallNoTOC:
94+
return "RequestCallNoTOC";
9795
default:
9896
return getGenericEdgeKindName(static_cast<Edge::Kind>(K));
9997
}

llvm/test/ExecutionEngine/JITLink/ppc64/external_weak.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# CHECK: External symbols:
1212
# CHECK: {{.*}} linkage: weak, scope: default, dead - foo
1313
# CHECK: section .text:
14-
# CHECK: {{.*}} kind = CallBranchDelta, target = foo
14+
# CHECK: {{.*}} kind = CallBranchDeltaRestoreTOC, target = addressable@{{.*}}
1515
# `foo` is weak in both relocatable files. `foo` is resolved to the one
1616
# defined in `%t/external_weak.o`. So calling `foo` in `%t/external_weak_main.o`
1717
# is expected to be an external function call.

0 commit comments

Comments
 (0)