summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/MC/MCInstBuilder.h6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp28
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp18
-rw-r--r--llvm/lib/Target/X86/X86AsmPrinter.h2
-rw-r--r--llvm/lib/Target/X86/X86MCInstLower.cpp36
-rw-r--r--llvm/test/CodeGen/X86/patchpoint.ll16
6 files changed, 80 insertions, 26 deletions
diff --git a/llvm/include/llvm/MC/MCInstBuilder.h b/llvm/include/llvm/MC/MCInstBuilder.h
index c5acb26eeca..d16f6b5452e 100644
--- a/llvm/include/llvm/MC/MCInstBuilder.h
+++ b/llvm/include/llvm/MC/MCInstBuilder.h
@@ -58,6 +58,12 @@ public:
return *this;
}
+ /// \brief Add an operand.
+ MCInstBuilder &addOperand(const MCOperand &Op) {
+ Inst.addOperand(Op);
+ return *this;
+ }
+
operator MCInst&() {
return Inst;
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index dafbc63dbd0..2b624adac94 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -711,7 +711,7 @@ bool FastISel::selectPatchpoint(const CallInst *I) {
CallingConv::ID CC = I->getCallingConv();
bool IsAnyRegCC = CC == CallingConv::AnyReg;
bool HasDef = !I->getType()->isVoidTy();
- Value *Callee = I->getOperand(PatchPointOpers::TargetPos);
+ Value *Callee = I->getOperand(PatchPointOpers::TargetPos)->stripPointerCasts();
// Get the real number of arguments participating in the call <numArgs>
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NArgPos)) &&
@@ -757,23 +757,25 @@ bool FastISel::selectPatchpoint(const CallInst *I) {
cast<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos));
Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue()));
- // Assume that the callee is a constant address or null pointer.
- // FIXME: handle function symbols in the future.
- uint64_t CalleeAddr;
- if (const auto *C = dyn_cast<IntToPtrInst>(Callee))
- CalleeAddr = cast<ConstantInt>(C->getOperand(0))->getZExtValue();
- else if (const auto *C = dyn_cast<ConstantExpr>(Callee)) {
- if (C->getOpcode() == Instruction::IntToPtr)
- CalleeAddr = cast<ConstantInt>(C->getOperand(0))->getZExtValue();
- else
+ // Add the call target.
+ if (const auto *C = dyn_cast<IntToPtrInst>(Callee)) {
+ uint64_t CalleeConstAddr =
+ cast<ConstantInt>(C->getOperand(0))->getZExtValue();
+ Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr));
+ } else if (const auto *C = dyn_cast<ConstantExpr>(Callee)) {
+ if (C->getOpcode() == Instruction::IntToPtr) {
+ uint64_t CalleeConstAddr =
+ cast<ConstantInt>(C->getOperand(0))->getZExtValue();
+ Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr));
+ } else
llvm_unreachable("Unsupported ConstantExpr.");
+ } else if (const auto *GV = dyn_cast<GlobalValue>(Callee)) {
+ Ops.push_back(MachineOperand::CreateGA(GV, 0));
} else if (isa<ConstantPointerNull>(Callee))
- CalleeAddr = 0;
+ Ops.push_back(MachineOperand::CreateImm(0));
else
llvm_unreachable("Unsupported callee address.");
- Ops.push_back(MachineOperand::CreateImm(CalleeAddr));
-
// Adjust <numArgs> to account for any arguments that have been passed on
// the stack instead.
unsigned NumCallRegArgs = IsAnyRegCC ? NumArgs : CLI.OutRegs.size();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 746a9efaa4d..2c813138f84 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7001,7 +7001,16 @@ void SelectionDAGBuilder::visitPatchpoint(ImmutableCallSite CS,
CallingConv::ID CC = CS.getCallingConv();
bool IsAnyRegCC = CC == CallingConv::AnyReg;
bool HasDef = !CS->getType()->isVoidTy();
- SDValue Callee = getValue(CS->getOperand(2)); // <target>
+ SDValue Callee = getValue(CS->getOperand(PatchPointOpers::TargetPos));
+
+ // Handle immediate and symbolic callees.
+ if (auto* ConstCallee = dyn_cast<ConstantSDNode>(Callee))
+ Callee = DAG.getIntPtrConstant(ConstCallee->getZExtValue(),
+ /*isTarget=*/true);
+ else if (auto* SymbolicCallee = dyn_cast<GlobalAddressSDNode>(Callee))
+ Callee = DAG.getTargetGlobalAddress(SymbolicCallee->getGlobal(),
+ SDLoc(SymbolicCallee),
+ SymbolicCallee->getValueType(0));
// Get the real number of arguments participating in the call <numArgs>
SDValue NArgVal = getValue(CS.getArgument(PatchPointOpers::NArgPos));
@@ -7041,11 +7050,8 @@ void SelectionDAGBuilder::visitPatchpoint(ImmutableCallSite CS,
Ops.push_back(DAG.getTargetConstant(
cast<ConstantSDNode>(NBytesVal)->getZExtValue(), MVT::i32));
- // Assume that the Callee is a constant address.
- // FIXME: handle function symbols in the future.
- Ops.push_back(
- DAG.getIntPtrConstant(cast<ConstantSDNode>(Callee)->getZExtValue(),
- /*isTarget=*/true));
+ // Add the callee.
+ Ops.push_back(Callee);
// Adjust <numArgs> to account for any arguments that have been passed on the
// stack instead.
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h
index d101b8ca0e4..9c6c683608b 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.h
+++ b/llvm/lib/Target/X86/X86AsmPrinter.h
@@ -81,7 +81,7 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
void InsertStackMapShadows(MachineFunction &MF);
void LowerSTACKMAP(const MachineInstr &MI);
- void LowerPATCHPOINT(const MachineInstr &MI);
+ void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index cd3076d0b1c..98dc376ed6a 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -867,7 +867,8 @@ void X86AsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
// Lower a patchpoint of the form:
// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
-void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI) {
+void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
+ X86MCInstLower &MCIL) {
assert(Subtarget->is64Bit() && "Patchpoint currently only supports X86-64");
SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo());
@@ -877,8 +878,29 @@ void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI) {
PatchPointOpers opers(&MI);
unsigned ScratchIdx = opers.getNextScratchIdx();
unsigned EncodedBytes = 0;
- int64_t CallTarget = opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
- if (CallTarget) {
+ const MachineOperand &CalleeMO =
+ opers.getMetaOper(PatchPointOpers::TargetPos);
+
+ // Check for null target. If target is non-null (i.e. is non-zero or is
+ // symbolic) then emit a call.
+ if (!(CalleeMO.isImm() && !CalleeMO.getImm())) {
+ MCOperand CalleeMCOp;
+ switch (CalleeMO.getType()) {
+ default:
+ /// FIXME: Add a verifier check for bad callee types.
+ llvm_unreachable("Unrecognized callee operand type.");
+ case MachineOperand::MO_Immediate:
+ if (CalleeMO.getImm())
+ CalleeMCOp = MCOperand::CreateImm(CalleeMO.getImm());
+ break;
+ case MachineOperand::MO_ExternalSymbol:
+ case MachineOperand::MO_GlobalAddress:
+ CalleeMCOp =
+ MCIL.LowerSymbolOperand(CalleeMO,
+ MCIL.GetSymbolFromOperand(CalleeMO));
+ break;
+ }
+
// Emit MOV to materialize the target address and the CALL to target.
// This is encoded with 12-13 bytes, depending on which register is used.
unsigned ScratchReg = MI.getOperand(ScratchIdx).getReg();
@@ -886,10 +908,12 @@ void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI) {
EncodedBytes = 13;
else
EncodedBytes = 12;
- EmitAndCountInstruction(MCInstBuilder(X86::MOV64ri).addReg(ScratchReg)
- .addImm(CallTarget));
+
+ EmitAndCountInstruction(
+ MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).addOperand(CalleeMCOp));
EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
}
+
// Emit padding.
unsigned NumBytes = opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
assert(NumBytes >= EncodedBytes &&
@@ -1091,7 +1115,7 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
return LowerSTACKMAP(*MI);
case TargetOpcode::PATCHPOINT:
- return LowerPATCHPOINT(*MI);
+ return LowerPATCHPOINT(*MI, MCInstLowering);
case X86::MORESTACK_RET:
EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
diff --git a/llvm/test/CodeGen/X86/patchpoint.ll b/llvm/test/CodeGen/X86/patchpoint.ll
index eda13fd1e24..82b15c36c2b 100644
--- a/llvm/test/CodeGen/X86/patchpoint.ll
+++ b/llvm/test/CodeGen/X86/patchpoint.ll
@@ -21,6 +21,22 @@ entry:
ret i64 %result
}
+; 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: movabsq $_foo, %r11
+; CHECK-NEXT: callq *%r11
+; CHECK-NEXT: xchgw %ax, %ax
+; CHECK: retq
+ %result = tail call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 9, i32 15, i8* bitcast (i64 (i64, i64)* @foo to i8*), i32 2, i64 %p1, i64 %p2)
+ ret i64 %result
+}
+
+
; Caller frame metadata with stackmaps. This should not be optimized
; as a leaf function.
;
OpenPOWER on IntegriCloud