diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 5 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86MCInstLower.cpp | 25 |
5 files changed, 44 insertions, 7 deletions
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 1ca200dc8b..253aad59f1 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -728,10 +728,14 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, const MCInstrDesc &II = TII->get(Opc); unsigned NumResults = CountResults(Node); unsigned NumDefs = II.getNumDefs(); + const uint16_t *ScratchRegs = NULL; // Handle PATCHPOINT specially and then use the generic code. - if (Opc == TargetOpcode::PATCHPOINT) + if (Opc == TargetOpcode::PATCHPOINT) { + unsigned CC = Node->getConstantOperandVal(4); NumDefs = NumResults; + ScratchRegs = TLI->getScratchRegisters((CallingConv::ID) CC); + } unsigned NumImpUses = 0; unsigned NodeOperands = @@ -767,6 +771,12 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, AddOperand(MIB, Node->getOperand(i), i-NumSkip+NumDefs, &II, VRBaseMap, /*IsDebug=*/false, IsClone, IsCloned); + // Add scratch registers as implicit def and early clobber + if (ScratchRegs) + for (unsigned i = 0; ScratchRegs[i]; ++i) + MIB.addReg(ScratchRegs[i], RegState::ImplicitDefine | + RegState::EarlyClobber); + // Transfer all of the memory reference descriptions of this instruction. MIB.setMemRefs(cast<MachineSDNode>(Node)->memoperands_begin(), cast<MachineSDNode>(Node)->memoperands_end()); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 913f517d85..98e067ebd4 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6832,7 +6832,7 @@ void SelectionDAGBuilder::visitPatchpoint(const CallInst &CI) { // [Args...], // [live variables...]) - unsigned CC = CI.getCallingConv(); + CallingConv::ID CC = CI.getCallingConv(); bool isAnyRegCC = CC == CallingConv::AnyReg; bool hasDef = !CI.getType()->isVoidTy(); SDValue Callee = getValue(CI.getOperand(2)); // <target> @@ -6876,7 +6876,8 @@ void SelectionDAGBuilder::visitPatchpoint(const CallInst &CI) { } // Assume that the Callee is a constant address. Ops.push_back( - DAG.getIntPtrConstant(cast<ConstantSDNode>(Callee)->getZExtValue())); + DAG.getIntPtrConstant(cast<ConstantSDNode>(Callee)->getZExtValue(), + /*isTarget=*/true)); // Adjust <numArgs> to account for any arguments that have been passed on the // stack instead. @@ -6886,7 +6887,7 @@ void SelectionDAGBuilder::visitPatchpoint(const CallInst &CI) { Ops.push_back(DAG.getTargetConstant(NumCallRegArgs, MVT::i32)); // Add the calling convention - Ops.push_back(DAG.getTargetConstant(CC, MVT::i32)); + Ops.push_back(DAG.getTargetConstant((unsigned)CC, MVT::i32)); // Add the arguments we omitted previously. The register allocator should // place these in any free register. 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(); |