Commit c4b6274d authored by Hans Wennborg's avatar Hans Wennborg
Browse files

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).
------------------------------------------------------------------------

llvm-svn: 242325
parent 284f6ec1
Loading
Loading
Loading
Loading
+71 −57
Original line number Diff line number Diff line
@@ -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;
+15 −0
Original line number Diff line number Diff line
@@ -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, ...)