[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