[llvm] r242239 - [PowerPC] Support symbolic targets in patchpoints

Hans Wennborg hans at chromium.org
Wed Jul 15 13:28:07 PDT 2015


Merged in r242325.

Cheers,
Hans

On Tue, Jul 14, 2015 at 8:40 PM, Hal Finkel <hfinkel at anl.gov> wrote:
> 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