Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit a8eaf29

Browse files
author
Hal Finkel
committed
[PowerPC] Use the ABI indirect-call protocol for patchpoints
We used to take the address specified as the direct target of the patchpoint and did no TOC-pointer handling. This, however, as not all that useful, because MCJIT tends to create a lot of modules, and they have their own TOC sections. Thus, to call from the generated code to other generated code, you really need to switch TOC pointers. Make this work as expected, and under ELFv1, tread the address as the function descriptor address so that the correct TOC pointer can be loaded. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242217 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 7a6e343 commit a8eaf29

File tree

5 files changed

+78
-26
lines changed

5 files changed

+78
-26
lines changed

docs/StackMaps.rst

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,10 @@ lowered according to the calling convention specified at the
221221
intrinsic's callsite. Variants of the intrinsic with non-void return
222222
type also return a value according to calling convention.
223223

224-
On PowerPC, note that ``<target>`` must be the actual intended target of
225-
the indirect call. Specifically, even when compiling for the ELF V1 ABI,
226-
``<target>`` is not the function-descriptor address normally used as the C/C++
227-
function-pointer representation. As a result, the call target must be local
228-
because no adjustment or restoration of the TOC pointer (in register r2) will
229-
be performed.
224+
On PowerPC, note that ``<target>`` must be the ABI function pointer for the
225+
intended target of the indirect call. Specifically, when compiling for the
226+
ELF V1 ABI, ``<target>`` is the function-descriptor address normally used as
227+
the C/C++ function-pointer representation.
230228

231229
Requesting zero patch point arguments is valid. In this case, all
232230
variable operands are handled just like

lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,28 +369,70 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
369369
assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
370370
"High 16 bits of call target should be zero.");
371371
unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
372-
EncodedBytes = 6*4;
372+
EncodedBytes = 0;
373373
// Materialize the jump address:
374374
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8)
375375
.addReg(ScratchReg)
376376
.addImm((CallTarget >> 32) & 0xFFFF));
377+
++EncodedBytes;
377378
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC)
378379
.addReg(ScratchReg)
379380
.addReg(ScratchReg)
380381
.addImm(32).addImm(16));
382+
++EncodedBytes;
381383
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8)
382384
.addReg(ScratchReg)
383385
.addReg(ScratchReg)
384386
.addImm((CallTarget >> 16) & 0xFFFF));
387+
++EncodedBytes;
385388
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8)
386389
.addReg(ScratchReg)
387390
.addReg(ScratchReg)
388391
.addImm(CallTarget & 0xFFFF));
389392

393+
// Save the current TOC pointer before the remote call.
394+
int TOCSaveOffset = Subtarget->isELFv2ABI() ? 24 : 40;
395+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::STD)
396+
.addReg(PPC::X2)
397+
.addImm(TOCSaveOffset)
398+
.addReg(PPC::X1));
399+
++EncodedBytes;
400+
401+
402+
// If we're on ELFv1, then we need to load the actual function pointer from
403+
// the function descriptor.
404+
if (!Subtarget->isELFv2ABI()) {
405+
// Load the new TOC pointer and the function address, but not r11
406+
// (needing this is rare, and loading it here would prevent passing it
407+
// via a 'nest' parameter.
408+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
409+
.addReg(PPC::X2)
410+
.addImm(8)
411+
.addReg(ScratchReg));
412+
++EncodedBytes;
413+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
414+
.addReg(ScratchReg)
415+
.addImm(0)
416+
.addReg(ScratchReg));
417+
++EncodedBytes;
418+
}
419+
390420
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8).addReg(ScratchReg));
421+
++EncodedBytes;
391422
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8));
423+
++EncodedBytes;
424+
425+
// Restore the TOC pointer after the call.
426+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
427+
.addReg(PPC::X2)
428+
.addImm(TOCSaveOffset)
429+
.addReg(PPC::X1));
430+
++EncodedBytes;
392431
}
393432

433+
// Each instruction is 4 bytes.
434+
EncodedBytes *= 4;
435+
394436
// Emit padding.
395437
unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
396438
assert(NumBytes >= EncodedBytes &&

test/CodeGen/PowerPC/ppc64-anyregcc.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ target triple = "powerpc64-unknown-linux-gnu"
8282
; CHECK-NEXT: .long 3
8383
define i64 @test() nounwind ssp uwtable {
8484
entry:
85-
call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 0, i32 24, i8* null, i32 2, i32 1, i32 2, i64 3)
85+
call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 0, i32 40, i8* null, i32 2, i32 1, i32 2, i64 3)
8686
ret i64 0
8787
}
8888

@@ -104,7 +104,7 @@ entry:
104104
define i64 @property_access1(i8* %obj) nounwind ssp uwtable {
105105
entry:
106106
%f = inttoptr i64 281474417671919 to i8*
107-
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 1, i32 24, i8* %f, i32 1, i8* %obj)
107+
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 1, i32 40, i8* %f, i32 1, i8* %obj)
108108
ret i64 %ret
109109
}
110110

@@ -127,7 +127,7 @@ define i64 @property_access2() nounwind ssp uwtable {
127127
entry:
128128
%obj = alloca i64, align 8
129129
%f = inttoptr i64 281474417671919 to i8*
130-
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 2, i32 24, i8* %f, i32 1, i64* %obj)
130+
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 2, i32 40, i8* %f, i32 1, i64* %obj)
131131
ret i64 %ret
132132
}
133133

@@ -150,7 +150,7 @@ define i64 @property_access3() nounwind ssp uwtable {
150150
entry:
151151
%obj = alloca i64, align 8
152152
%f = inttoptr i64 281474417671919 to i8*
153-
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 3, i32 24, i8* %f, i32 0, i64* %obj)
153+
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 3, i32 40, i8* %f, i32 0, i64* %obj)
154154
ret i64 %ret
155155
}
156156

@@ -232,7 +232,7 @@ entry:
232232
define i64 @anyreg_test1(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
233233
entry:
234234
%f = inttoptr i64 281474417671919 to i8*
235-
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 4, i32 24, i8* %f, i32 13, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
235+
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 4, i32 40, i8* %f, i32 13, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
236236
ret i64 %ret
237237
}
238238

@@ -314,7 +314,7 @@ entry:
314314
define i64 @anyreg_test2(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
315315
entry:
316316
%f = inttoptr i64 281474417671919 to i8*
317-
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 24, i8* %f, i32 8, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
317+
%ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 40, i8* %f, i32 8, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
318318
ret i64 %ret
319319
}
320320

@@ -342,7 +342,7 @@ entry:
342342
; CHECK-NEXT: .long 0
343343
define i64 @patchpoint_spilldef(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
344344
entry:
345-
%result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 12, i32 24, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2)
345+
%result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 12, i32 40, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2)
346346
tail call void asm sideeffect "nop", "~{r0},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r14},~{r15},~{r16},~{r17
347347
},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
348348
ret i64 %result
@@ -384,7 +384,7 @@ define i64 @patchpoint_spillargs(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
384384
entry:
385385
tail call void asm sideeffect "nop", "~{r0},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r14},~{r15},~{r16},~{r17
386386
},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
387-
%result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 13, i32 24, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2, i64 %p3, i64 %p4)
387+
%result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 13, i32 40, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2, i64 %p3, i64 %p4)
388388
ret i64 %result
389389
}
390390

test/CodeGen/PowerPC/ppc64-patchpoint.ll

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,34 @@ entry:
1515
; CHECK-NEXT: rldic 12, 12, 32, 16
1616
; CHECK-NEXT: oris 12, 12, 48879
1717
; CHECK-NEXT: ori 12, 12, 51966
18+
; CHECK-LE-NEXT: std 2, 24(1)
19+
; CHECK-BE-NEXT: std 2, 40(1)
20+
; CHECK-BE-NEXT: ld 2, 8(12)
21+
; CHECK-BE-NEXT: ld 12, 0(12)
1822
; CHECK-NEXT: mtctr 12
1923
; CHECK-NEXT: bctrl
24+
; CHECK-LE-NEXT: ld 2, 24(1)
25+
; CHECK-BE-NEXT: ld 2, 40(1)
2026

2127
; CHECK: li 12, -8531
2228
; CHECK-NEXT: rldic 12, 12, 32, 16
2329
; CHECK-NEXT: oris 12, 12, 48879
2430
; CHECK-NEXT: ori 12, 12, 51967
31+
; CHECK-LE-NEXT: std 2, 24(1)
32+
; CHECK-BE-NEXT: std 2, 40(1)
33+
; CHECK-BE-NEXT: ld 2, 8(12)
34+
; CHECK-BE-NEXT: ld 12, 0(12)
2535
; CHECK-NEXT: mtctr 12
2636
; CHECK-NEXT: bctrl
37+
; CHECK-LE-NEXT: ld 2, 24(1)
38+
; CHECK-BE-NEXT: ld 2, 40(1)
2739

2840
; CHECK: blr
2941

3042
%resolveCall2 = inttoptr i64 244837814094590 to i8*
31-
%result = tail call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 2, i32 24, i8* %resolveCall2, i32 4, i64 %p1, i64 %p2, i64 %p3, i64 %p4)
43+
%result = tail call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 2, i32 40, i8* %resolveCall2, i32 4, i64 %p1, i64 %p2, i64 %p3, i64 %p4)
3244
%resolveCall3 = inttoptr i64 244837814094591 to i8*
33-
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 3, i32 24, i8* %resolveCall3, i32 2, i64 %p1, i64 %result)
45+
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 3, i32 40, i8* %resolveCall3, i32 2, i64 %p1, i64 %result)
3446
ret i64 %result
3547
}
3648

@@ -65,13 +77,13 @@ entry:
6577
%tmp81 = inttoptr i64 %tmp80 to i64*
6678
%tmp82 = load i64, i64* %tmp81, align 8
6779
tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 14, i32 8, i64 %arg, i64 %tmp2, i64 %tmp10, i64 %tmp82)
68-
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 15, i32 32, i8* null, i32 3, i64 %arg, i64 %tmp10, i64 %tmp82)
80+
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 15, i32 48, i8* null, i32 3, i64 %arg, i64 %tmp10, i64 %tmp82)
6981
%tmp83 = load i64, i64* %tmp33, align 8
7082
%tmp84 = add i64 %tmp83, -24
7183
%tmp85 = inttoptr i64 %tmp84 to i64*
7284
%tmp86 = load i64, i64* %tmp85, align 8
7385
tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 17, i32 8, i64 %arg, i64 %tmp10, i64 %tmp86)
74-
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 18, i32 32, i8* null, i32 3, i64 %arg, i64 %tmp10, i64 %tmp86)
86+
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 18, i32 48, i8* null, i32 3, i64 %arg, i64 %tmp10, i64 %tmp86)
7587
ret i64 10
7688
}
7789

test/CodeGen/PowerPC/ppc64-stackmap.ll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ target triple = "powerpc64-unknown-linux-gnu"
112112
define void @constantargs() {
113113
entry:
114114
%0 = inttoptr i64 244837814094590 to i8*
115-
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 24, i8* %0, i32 0, i64 65535, i64 65536, i64 4294967295, i64 4294967296)
115+
tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 40, i8* %0, i32 0, i64 65535, i64 65536, i64 4294967295, i64 4294967296)
116116
ret void
117117
}
118118

@@ -160,7 +160,7 @@ entry:
160160
cold:
161161
; OSR patchpoint with 12-byte nop-slide and 2 live vars.
162162
%thunk = inttoptr i64 244837814094590 to i8*
163-
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 24, i8* %thunk, i32 0, i64 %a, i64 %b)
163+
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 40, i8* %thunk, i32 0, i64 %a, i64 %b)
164164
unreachable
165165
ret:
166166
ret void
@@ -176,7 +176,7 @@ ret:
176176
define i64 @propertyRead(i64* %obj) {
177177
entry:
178178
%resolveRead = inttoptr i64 244837814094590 to i8*
179-
%result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 24, i8* %resolveRead, i32 1, i64* %obj)
179+
%result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 40, i8* %resolveRead, i32 1, i64* %obj)
180180
%add = add i64 %result, 3
181181
ret i64 %add
182182
}
@@ -196,7 +196,7 @@ entry:
196196
define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) {
197197
entry:
198198
%resolveWrite = inttoptr i64 244837814094590 to i8*
199-
call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 24, i8* %resolveWrite, i32 2, i64* %obj, i64 %a)
199+
call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 40, i8* %resolveWrite, i32 2, i64* %obj, i64 %a)
200200
ret void
201201
}
202202

@@ -218,7 +218,7 @@ entry:
218218
define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
219219
entry:
220220
%resolveCall = inttoptr i64 244837814094590 to i8*
221-
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 24, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
221+
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 40, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
222222
ret void
223223
}
224224

@@ -240,7 +240,7 @@ entry:
240240
define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
241241
entry:
242242
%resolveCall = inttoptr i64 244837814094590 to i8*
243-
%result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 24, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
243+
%result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 40, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
244244
%add = add i64 %result, 3
245245
ret i64 %add
246246
}
@@ -260,7 +260,7 @@ entry:
260260
; CHECK-NEXT: .short 31
261261
define void @spilledValue(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27) {
262262
entry:
263-
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 24, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27)
263+
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 40, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27)
264264
ret void
265265
}
266266

0 commit comments

Comments
 (0)