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

Commit 445ea38

Browse files
committed
Merging r242239:
------------------------------------------------------------------------ r242239 | hfinkel | 2015-07-14 15:53:11 -0700 (Tue, 14 Jul 2015) | 4 lines [PowerPC] Support symbolic targets in patchpoints Follow-up r235483, with the corresponding support in PPC. We use a regular call for symbolic targets (because they're much cheaper than indirect calls). ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_37@242325 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent abdaa23 commit 445ea38

File tree

2 files changed

+86
-57
lines changed

2 files changed

+86
-57
lines changed

lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -363,71 +363,85 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
363363
SM.recordPatchPoint(MI);
364364
PatchPointOpers Opers(&MI);
365365

366-
int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
367366
unsigned EncodedBytes = 0;
368-
if (CallTarget) {
369-
assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
370-
"High 16 bits of call target should be zero.");
371-
unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
372-
EncodedBytes = 0;
373-
// Materialize the jump address:
374-
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8)
375-
.addReg(ScratchReg)
376-
.addImm((CallTarget >> 32) & 0xFFFF));
377-
++EncodedBytes;
378-
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC)
379-
.addReg(ScratchReg)
380-
.addReg(ScratchReg)
381-
.addImm(32).addImm(16));
382-
++EncodedBytes;
383-
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8)
384-
.addReg(ScratchReg)
385-
.addReg(ScratchReg)
386-
.addImm((CallTarget >> 16) & 0xFFFF));
387-
++EncodedBytes;
388-
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8)
389-
.addReg(ScratchReg)
390-
.addReg(ScratchReg)
391-
.addImm(CallTarget & 0xFFFF));
392-
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)
367+
const MachineOperand &CalleeMO =
368+
Opers.getMetaOper(PatchPointOpers::TargetPos);
369+
370+
if (CalleeMO.isImm()) {
371+
int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
372+
if (CallTarget) {
373+
assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
374+
"High 16 bits of call target should be zero.");
375+
unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
376+
EncodedBytes = 0;
377+
// Materialize the jump address:
378+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8)
379+
.addReg(ScratchReg)
380+
.addImm((CallTarget >> 32) & 0xFFFF));
381+
++EncodedBytes;
382+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC)
383+
.addReg(ScratchReg)
384+
.addReg(ScratchReg)
385+
.addImm(32).addImm(16));
386+
++EncodedBytes;
387+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8)
388+
.addReg(ScratchReg)
389+
.addReg(ScratchReg)
390+
.addImm((CallTarget >> 16) & 0xFFFF));
391+
++EncodedBytes;
392+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8)
393+
.addReg(ScratchReg)
394+
.addReg(ScratchReg)
395+
.addImm(CallTarget & 0xFFFF));
396+
397+
// Save the current TOC pointer before the remote call.
398+
int TOCSaveOffset = Subtarget->isELFv2ABI() ? 24 : 40;
399+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::STD)
409400
.addReg(PPC::X2)
410-
.addImm(8)
401+
.addImm(TOCSaveOffset)
402+
.addReg(PPC::X1));
403+
++EncodedBytes;
404+
405+
406+
// If we're on ELFv1, then we need to load the actual function pointer
407+
// from the function descriptor.
408+
if (!Subtarget->isELFv2ABI()) {
409+
// Load the new TOC pointer and the function address, but not r11
410+
// (needing this is rare, and loading it here would prevent passing it
411+
// via a 'nest' parameter.
412+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
413+
.addReg(PPC::X2)
414+
.addImm(8)
415+
.addReg(ScratchReg));
416+
++EncodedBytes;
417+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
418+
.addReg(ScratchReg)
419+
.addImm(0)
420+
.addReg(ScratchReg));
421+
++EncodedBytes;
422+
}
423+
424+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8)
411425
.addReg(ScratchReg));
412426
++EncodedBytes;
427+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8));
428+
++EncodedBytes;
429+
430+
// Restore the TOC pointer after the call.
413431
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
414-
.addReg(ScratchReg)
415-
.addImm(0)
416-
.addReg(ScratchReg));
432+
.addReg(PPC::X2)
433+
.addImm(TOCSaveOffset)
434+
.addReg(PPC::X1));
417435
++EncodedBytes;
418436
}
437+
} else if (CalleeMO.isGlobal()) {
438+
const GlobalValue *GValue = CalleeMO.getGlobal();
439+
MCSymbol *MOSymbol = getSymbol(GValue);
440+
const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
419441

420-
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8).addReg(ScratchReg));
421-
++EncodedBytes;
422-
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;
442+
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL8_NOP)
443+
.addExpr(SymVar));
444+
EncodedBytes += 2;
431445
}
432446

433447
// Each instruction is 4 bytes.

test/CodeGen/PowerPC/ppc64-patchpoint.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,21 @@ entry:
103103
ret void
104104
}
105105

106+
; Trivial symbolic patchpoint codegen.
107+
108+
declare i64 @foo(i64 %p1, i64 %p2)
109+
define i64 @trivial_symbolic_patchpoint_codegen(i64 %p1, i64 %p2) {
110+
entry:
111+
; CHECK-LABEL: trivial_symbolic_patchpoint_codegen:
112+
; CHECK: bl foo
113+
; CHECK-NEXT: nop
114+
; CHECK-NEXT: nop
115+
; CHECK-NOT: nop
116+
; CHECK: blr
117+
%result = tail call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 9, i32 12, i8* bitcast (i64 (i64, i64)* @foo to i8*), i32 2, i64 %p1, i64 %p2)
118+
ret i64 %result
119+
}
120+
106121
declare void @llvm.experimental.stackmap(i64, i32, ...)
107122
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
108123
declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)

0 commit comments

Comments
 (0)