[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/trunk@242239 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel
2015-07-14 22:53:11 +00:00
parent 96b5986e38
commit a67262f6bc
2 changed files with 85 additions and 56 deletions

View File

@@ -363,8 +363,12 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
SM.recordPatchPoint(MI);
PatchPointOpers Opers(&MI);
int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
unsigned EncodedBytes = 0;
const MachineOperand &CalleeMO =
Opers.getMetaOper(PatchPointOpers::TargetPos);
if (CalleeMO.isImm()) {
int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
if (CallTarget) {
assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
"High 16 bits of call target should be zero.");
@@ -399,8 +403,8 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
++EncodedBytes;
// If we're on ELFv1, then we need to load the actual function pointer from
// the function descriptor.
// If we're on ELFv1, then we need to load the actual function pointer
// from the function descriptor.
if (!Subtarget->isELFv2ABI()) {
// Load the new TOC pointer and the function address, but not r11
// (needing this is rare, and loading it here would prevent passing it
@@ -417,7 +421,8 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
++EncodedBytes;
}
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8).addReg(ScratchReg));
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8)
.addReg(ScratchReg));
++EncodedBytes;
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8));
++EncodedBytes;
@@ -429,6 +434,15 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
.addReg(PPC::X1));
++EncodedBytes;
}
} else if (CalleeMO.isGlobal()) {
const GlobalValue *GValue = CalleeMO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL8_NOP)
.addExpr(SymVar));
EncodedBytes += 2;
}
// Each instruction is 4 bytes.
EncodedBytes *= 4;

View File

@@ -103,6 +103,21 @@ entry:
ret void
}
; Trivial symbolic patchpoint codegen.
declare i64 @foo(i64 %p1, i64 %p2)
define i64 @trivial_symbolic_patchpoint_codegen(i64 %p1, i64 %p2) {
entry:
; CHECK-LABEL: trivial_symbolic_patchpoint_codegen:
; CHECK: bl foo
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NOT: nop
; CHECK: blr
%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)
ret i64 %result
}
declare void @llvm.experimental.stackmap(i64, i32, ...)
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)