summaryrefslogtreecommitdiff
path: root/lib/Target/X86
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2013-11-09 01:51:33 +0000
committerJuergen Ributzka <juergen@apple.com>2013-11-09 01:51:33 +0000
commitd4f5a615674aaabeee4e444e708d1fa00a41495e (patch)
tree37ab0cacf3e60a5d6660d7f4b65e64609d29046c /lib/Target/X86
parent999ffb6085a6e24261680b41d4f43ad4ba8fd250 (diff)
downloadllvm-d4f5a615674aaabeee4e444e708d1fa00a41495e.tar.gz
llvm-d4f5a615674aaabeee4e444e708d1fa00a41495e.tar.bz2
llvm-d4f5a615674aaabeee4e444e708d1fa00a41495e.tar.xz
[Stackmap] Materialize the jump address within the patchpoint noop slide.
This patch moves the jump address materialization inside the noop slide. This enables patching of the materialization itself or its complete removal. This patch also adds the ability to define scratch registers that can be used safely by the code called from the patchpoint intrinsic. At least one scratch register is required, because that one is used for the materialization of the jump address. This patch depends on D2009. Differential Revision: http://llvm-reviews.chandlerc.com/D2074 Reviewed by Andy git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194306 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp5
-rw-r--r--lib/Target/X86/X86ISelLowering.h2
-rw-r--r--lib/Target/X86/X86MCInstLower.cpp25
3 files changed, 29 insertions, 3 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 55bfab449a..a8743afce9 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1773,6 +1773,11 @@ X86TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
return CCInfo.CheckReturn(Outs, RetCC_X86);
}
+const uint16_t *X86TargetLowering::getScratchRegisters(CallingConv::ID) const {
+ static const uint16_t ScratchRegs[] = { X86::R11, 0 };
+ return ScratchRegs;
+}
+
SDValue
X86TargetLowering::LowerReturn(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 08dc115de0..07a36f98c2 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -925,6 +925,8 @@ namespace llvm {
const SmallVectorImpl<ISD::OutputArg> &Outs,
LLVMContext &Context) const;
+ virtual const uint16_t *getScratchRegisters(CallingConv::ID CC) const;
+
/// Utility function to emit atomic-load-arith operations (and, or, xor,
/// nand, max, min, umax, umin). It takes the corresponding instruction to
/// expand, the associated machine basic block, and the associated X86
diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp
index fa15114f91..2cc038c889 100644
--- a/lib/Target/X86/X86MCInstLower.cpp
+++ b/lib/Target/X86/X86MCInstLower.cpp
@@ -785,6 +785,7 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer,
!MI.getOperand(0).isImplicit();
unsigned StartIdx = hasDef ? 1 : 0;
#ifndef NDEBUG
+ {
unsigned StartIdx2 = 0, e = MI.getNumOperands();
while (StartIdx2 < e && MI.getOperand(StartIdx2).isReg() &&
MI.getOperand(StartIdx2).isDef() &&
@@ -793,8 +794,20 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer,
assert(StartIdx == StartIdx2 &&
"Unexpected additonal definition in Patchpoint intrinsic.");
+ }
#endif
+ // Find the first scratch register (implicit def and early clobber)
+ unsigned ScratchIdx = StartIdx, e = MI.getNumOperands();
+ while (ScratchIdx < e &&
+ !(MI.getOperand(ScratchIdx).isReg() &&
+ MI.getOperand(ScratchIdx).isDef() &&
+ MI.getOperand(ScratchIdx).isImplicit() &&
+ MI.getOperand(ScratchIdx).isEarlyClobber()))
+ ++ScratchIdx;
+
+ assert(ScratchIdx != e && "No scratch register available");
+
int64_t ID = MI.getOperand(StartIdx).getImm();
assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
@@ -812,10 +825,16 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer,
getStackMapEndMOP(MI.operands_begin(), MI.operands_end()),
isAnyRegCC && hasDef);
- // Emit call. We need to know how many bytes we encoded here.
- unsigned EncodedBytes = 2;
+ // 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.
+ // We conservatively assume that it is 12 bytes and emit in worst case one
+ // extra NOP byte.
+ unsigned EncodedBytes = 12;
+ OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64ri)
+ .addReg(MI.getOperand(ScratchIdx).getReg())
+ .addImm(MI.getOperand(StartIdx + 2).getImm()));
OutStreamer.EmitInstruction(MCInstBuilder(X86::CALL64r)
- .addReg(MI.getOperand(StartIdx + 2).getReg()));
+ .addReg(MI.getOperand(ScratchIdx).getReg()));
// Emit padding.
unsigned NumNOPBytes = MI.getOperand(StartIdx + 1).getImm();