[llvm] r242239 - [PowerPC] Support symbolic targets in patchpoints
Hal Finkel
hfinkel at anl.gov
Tue Jul 14 20:40:52 PDT 2015
Hi Hans,
It seems this missed the release branch by a few minutes, but I'd like to get it in. It is a small low-risk improvement to patchpoints on PowerPC that makes them much more useful (and is a companion to r242217, which did make the branch), which will help us get user feedback on the feature. As code owner, I approve.
Thanks again,
Hal
----- Original Message -----
> From: "Hal Finkel" <hfinkel at anl.gov>
> To: llvm-commits at cs.uiuc.edu
> Sent: Tuesday, July 14, 2015 5:53:11 PM
> Subject: [llvm] r242239 - [PowerPC] Support symbolic targets in patchpoints
>
> Author: hfinkel
> Date: Tue Jul 14 17:53:11 2015
> New Revision: 242239
>
> URL: http://llvm.org/viewvc/llvm-project?rev=242239&view=rev
> Log:
> [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).
>
> Modified:
> llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
> llvm/trunk/test/CodeGen/PowerPC/ppc64-patchpoint.ll
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=242239&r1=242238&r2=242239&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Jul 14
> 17:53:11 2015
> @@ -363,71 +363,85 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCSt
> SM.recordPatchPoint(MI);
> PatchPointOpers Opers(&MI);
>
> - int64_t CallTarget =
> Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
> unsigned EncodedBytes = 0;
> - if (CallTarget) {
> - assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
> - "High 16 bits of call target should be zero.");
> - unsigned ScratchReg =
> MI.getOperand(Opers.getNextScratchIdx()).getReg();
> - EncodedBytes = 0;
> - // Materialize the jump address:
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8)
> - .addReg(ScratchReg)
> - .addImm((CallTarget >> 32) &
> 0xFFFF));
> - ++EncodedBytes;
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC)
> - .addReg(ScratchReg)
> - .addReg(ScratchReg)
> - .addImm(32).addImm(16));
> - ++EncodedBytes;
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8)
> - .addReg(ScratchReg)
> - .addReg(ScratchReg)
> - .addImm((CallTarget >> 16) &
> 0xFFFF));
> - ++EncodedBytes;
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8)
> - .addReg(ScratchReg)
> - .addReg(ScratchReg)
> - .addImm(CallTarget & 0xFFFF));
> -
> - // Save the current TOC pointer before the remote call.
> - int TOCSaveOffset = Subtarget->isELFv2ABI() ? 24 : 40;
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::STD)
> - .addReg(PPC::X2)
> - .addImm(TOCSaveOffset)
> - .addReg(PPC::X1));
> - ++EncodedBytes;
> -
> -
> - // 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
> - // via a 'nest' parameter.
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
> + 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.");
> + unsigned ScratchReg =
> MI.getOperand(Opers.getNextScratchIdx()).getReg();
> + EncodedBytes = 0;
> + // Materialize the jump address:
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8)
> + .addReg(ScratchReg)
> + .addImm((CallTarget >> 32) &
> 0xFFFF));
> + ++EncodedBytes;
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC)
> + .addReg(ScratchReg)
> + .addReg(ScratchReg)
> + .addImm(32).addImm(16));
> + ++EncodedBytes;
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8)
> + .addReg(ScratchReg)
> + .addReg(ScratchReg)
> + .addImm((CallTarget >> 16) &
> 0xFFFF));
> + ++EncodedBytes;
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8)
> + .addReg(ScratchReg)
> + .addReg(ScratchReg)
> + .addImm(CallTarget & 0xFFFF));
> +
> + // Save the current TOC pointer before the remote call.
> + int TOCSaveOffset = Subtarget->isELFv2ABI() ? 24 : 40;
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::STD)
> .addReg(PPC::X2)
> - .addImm(8)
> + .addImm(TOCSaveOffset)
> + .addReg(PPC::X1));
> + ++EncodedBytes;
> +
> +
> + // 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
> + // via a 'nest' parameter.
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
> + .addReg(PPC::X2)
> + .addImm(8)
> + .addReg(ScratchReg));
> + ++EncodedBytes;
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
> + .addReg(ScratchReg)
> + .addImm(0)
> + .addReg(ScratchReg));
> + ++EncodedBytes;
> + }
> +
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8)
> .addReg(ScratchReg));
> ++EncodedBytes;
> + EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8));
> + ++EncodedBytes;
> +
> + // Restore the TOC pointer after the call.
> EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
> - .addReg(ScratchReg)
> - .addImm(0)
> - .addReg(ScratchReg));
> + .addReg(PPC::X2)
> + .addImm(TOCSaveOffset)
> + .addReg(PPC::X1));
> ++EncodedBytes;
> }
> -
> - EmitToStreamer(OutStreamer,
> MCInstBuilder(PPC::MTCTR8).addReg(ScratchReg));
> - ++EncodedBytes;
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8));
> - ++EncodedBytes;
> -
> - // Restore the TOC pointer after the call.
> - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LD)
> - .addReg(PPC::X2)
> - .addImm(TOCSaveOffset)
> - .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.
>
> Modified: llvm/trunk/test/CodeGen/PowerPC/ppc64-patchpoint.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc64-patchpoint.ll?rev=242239&r1=242238&r2=242239&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/PowerPC/ppc64-patchpoint.ll (original)
> +++ llvm/trunk/test/CodeGen/PowerPC/ppc64-patchpoint.ll Tue Jul 14
> 17:53:11 2015
> @@ -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,
> ...)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the llvm-commits
mailing list