Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -8064,6 +8064,68 @@ format that can be written out by a compiler runtime and consumed via the ``llvm-profdata`` tool. +'``llvm.lightweight_setjmp``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + declare i32 @llvm.lightweight_setjmp(i8* ) + +Overview: +""""""""" + +Saves the program counter to second machine word in the given buffer. It should +be used in combination with '``llvm.frameaddress``' and '``llvm.stacksave``' to +prepare a buffer that can be used by '``llvm.lightweight_longjmp``'. The +intrinsics return value is 0 when it is first executed or is read from the +buffer when '``llvm.lightweight_longjmp``' is executed. + +This intrinsic is a lightweight version of '``setjmp``' as known from libc. The +same restrictions apply: The values of local variables which are not accessed +through volatile loads and stores are not preserved. + +The format of the buffer is modeled after the '``__builtin_setjmp``' intrinsic +as found in gcc. The intrinsic is only implement by few targets and is intended +to be used by compiler runtime libraries to provide exception handling support. + +Arguments: +"""""""""" + +The argument is a pointer to a buffer that can hold five target machine words. +The intrinsic stores the program counter in the second word and may store +target specific information in the fifth word. + +'``llvm.lightweight_longjmp``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + declare void @llvm.lightweight_longjmp(i8* ) + +Overview: +""""""""" + +Sets the values of the frame pointer, program counter and stack pointer to the +values found in the given buffer. The fourth value in the buffer will become +the return value of the '``llvm.lightweight_setjmp``' that was used to set the +program counter in the buffer. + +This intrinsic is only implemented by few targets and is intended to be used by +compiler runtime libraries to provide exception handling support. + +Arguments: +"""""""""" + +The argument is a pointer to a buffer that holds five target machine words. +The words contain in this order: frame pointer, program counter, stack pointer, +return value and target specific information. + Standard C Library Intrinsics ----------------------------- Index: include/llvm/CodeGen/ISDOpcodes.h =================================================================== --- include/llvm/CodeGen/ISDOpcodes.h +++ include/llvm/CodeGen/ISDOpcodes.h @@ -93,17 +93,17 @@ /// execution to HANDLER. Many platform-related details also :) EH_RETURN, - /// RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) - /// This corresponds to the eh.sjlj.setjmp intrinsic. + /// RESULT, OUTCHAIN = EH_LIGHTWEIGHT_SETJMP(INCHAIN, buffer) + /// This corresponds to the lightweight_setjmp intrinsic. /// It takes an input chain and a pointer to the jump buffer as inputs /// and returns an outchain. - EH_SJLJ_SETJMP, + LIGHTWEIGHT_SETJMP, - /// OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) - /// This corresponds to the eh.sjlj.longjmp intrinsic. + /// OUTCHAIN = EH_LIGHTWEIGHT_LONGJMP(INCHAIN, buffer) + /// This corresponds to the lightweight_longjmp intrinsic. /// It takes an input chain and a pointer to the jump buffer as inputs /// and returns an outchain. - EH_SJLJ_LONGJMP, + LIGHTWEIGHT_LONGJMP, /// OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) /// The target initializes the dispatch table here. Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -304,6 +304,9 @@ llvm_i32_ty, llvm_i32_ty], []>; +def int_lightweight_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], []>; +def int_lightweight_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>; + //===------------------- Standard C Library Intrinsics --------------------===// // @@ -437,8 +440,6 @@ def int_eh_sjlj_callsite : Intrinsic<[], [llvm_i32_ty]>; } def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>; -def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; -def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>; def int_eh_sjlj_setup_dispatch : Intrinsic<[], []>; //===---------------- Generic Variable Attribute Intrinsics----------------===// Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1249,9 +1249,9 @@ case ISD::MERGE_VALUES: case ISD::EH_RETURN: case ISD::FRAME_TO_ARGS_OFFSET: - case ISD::EH_SJLJ_SETJMP: - case ISD::EH_SJLJ_LONGJMP: case ISD::EH_SJLJ_SETUP_DISPATCH: + case ISD::LIGHTWEIGHT_SETJMP: + case ISD::LIGHTWEIGHT_LONGJMP: // These operations lie about being legal: when they claim to be legal, // they should actually be expanded. Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); @@ -2884,12 +2884,12 @@ case ISD::EH_LABEL: case ISD::PREFETCH: case ISD::VAEND: - case ISD::EH_SJLJ_LONGJMP: + case ISD::LIGHTWEIGHT_LONGJMP: // If the target didn't expand these, there's nothing to do, so just // preserve the chain and be done. Results.push_back(Node->getOperand(0)); break; - case ISD::EH_SJLJ_SETJMP: + case ISD::LIGHTWEIGHT_SETJMP: // If the target didn't expand this, just return 'zero' and preserve the // chain. Results.push_back(DAG.getConstant(0, dl, MVT::i32)); Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4330,18 +4330,18 @@ MFI->setFunctionContextIndex(FI); return nullptr; } - case Intrinsic::eh_sjlj_setjmp: { + case Intrinsic::lightweight_setjmp: { SDValue Ops[2]; Ops[0] = getRoot(); Ops[1] = getValue(I.getArgOperand(0)); - SDValue Op = DAG.getNode(ISD::EH_SJLJ_SETJMP, sdl, + SDValue Op = DAG.getNode(ISD::LIGHTWEIGHT_SETJMP, sdl, DAG.getVTList(MVT::i32, MVT::Other), Ops); setValue(&I, Op.getValue(0)); DAG.setRoot(Op.getValue(1)); return nullptr; } - case Intrinsic::eh_sjlj_longjmp: { - DAG.setRoot(DAG.getNode(ISD::EH_SJLJ_LONGJMP, sdl, MVT::Other, + case Intrinsic::lightweight_longjmp: { + DAG.setRoot(DAG.getNode(ISD::LIGHTWEIGHT_LONGJMP, sdl, MVT::Other, getRoot(), getValue(I.getArgOperand(0)))); return nullptr; } Index: lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -100,9 +100,9 @@ case ISD::WRITE_REGISTER: return "WRITE_REGISTER"; case ISD::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET"; case ISD::EH_RETURN: return "EH_RETURN"; - case ISD::EH_SJLJ_SETJMP: return "EH_SJLJ_SETJMP"; - case ISD::EH_SJLJ_LONGJMP: return "EH_SJLJ_LONGJMP"; case ISD::EH_SJLJ_SETUP_DISPATCH: return "EH_SJLJ_SETUP_DISPATCH"; + case ISD::LIGHTWEIGHT_SETJMP: return "LIGHTWEIGHT_SETJMP"; + case ISD::LIGHTWEIGHT_LONGJMP: return "LIGHTWEIGHT_LONGJMP"; case ISD::ConstantPool: return "ConstantPool"; case ISD::TargetIndex: return "TargetIndex"; case ISD::ExternalSymbol: return "ExternalSymbol"; Index: lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- lib/Target/ARM/ARMAsmPrinter.cpp +++ lib/Target/ARM/ARMAsmPrinter.cpp @@ -1626,9 +1626,9 @@ } break; } - case ARM::t2Int_eh_sjlj_setjmp: - case ARM::t2Int_eh_sjlj_setjmp_nofp: - case ARM::tInt_eh_sjlj_setjmp: { + case ARM::t2Int_lightweight_setjmp: + case ARM::t2Int_lightweight_setjmp_nofp: + case ARM::tInt_lightweight_setjmp: { // Two incoming args: GPR:$src, GPR:$val // mov $val, pc // adds $val, #7 @@ -1696,8 +1696,8 @@ return; } - case ARM::Int_eh_sjlj_setjmp_nofp: - case ARM::Int_eh_sjlj_setjmp: { + case ARM::Int_lightweight_setjmp_nofp: + case ARM::Int_lightweight_setjmp: { // Two incoming args: GPR:$src, GPR:$val // add $val, pc, #8 // str $val, [$src, #+4] @@ -1756,7 +1756,7 @@ .addReg(0)); return; } - case ARM::Int_eh_sjlj_longjmp: { + case ARM::Int_lightweight_longjmp: { // ldr sp, [$src, #8] // ldr $scratch, [$src, #4] // ldr r7, [$src] @@ -1794,7 +1794,7 @@ .addReg(0)); return; } - case ARM::tInt_eh_sjlj_longjmp: { + case ARM::tInt_lightweight_longjmp: { // ldr $scratch, [$src, #8] // mov sp, $scratch // ldr $scratch, [$src, #4] Index: lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseInstrInfo.cpp +++ lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -634,16 +634,16 @@ // If this machine instr is a constant pool entry, its size is recorded as // operand #2. return MI->getOperand(2).getImm(); - case ARM::Int_eh_sjlj_longjmp: + case ARM::Int_lightweight_longjmp: return 16; - case ARM::tInt_eh_sjlj_longjmp: + case ARM::tInt_lightweight_longjmp: return 10; - case ARM::Int_eh_sjlj_setjmp: - case ARM::Int_eh_sjlj_setjmp_nofp: + case ARM::Int_lightweight_setjmp: + case ARM::Int_lightweight_setjmp_nofp: return 20; - case ARM::tInt_eh_sjlj_setjmp: - case ARM::t2Int_eh_sjlj_setjmp: - case ARM::t2Int_eh_sjlj_setjmp_nofp: + case ARM::tInt_lightweight_setjmp: + case ARM::t2Int_lightweight_setjmp: + case ARM::t2Int_lightweight_setjmp_nofp: return 12; case ARM::SPACE: return MI->getOperand(1).getImm(); Index: lib/Target/ARM/ARMISelLowering.h =================================================================== --- lib/Target/ARM/ARMISelLowering.h +++ lib/Target/ARM/ARMISelLowering.h @@ -77,8 +77,8 @@ VMOVRRD, // double to two gprs. VMOVDRR, // Two gprs to double. - EH_SJLJ_SETJMP, // SjLj exception handling setjmp. - EH_SJLJ_LONGJMP, // SjLj exception handling longjmp. + LIGHTWEIGHT_SETJMP, // __builtin_setjmp + LIGHTWEIGHT_LONGJMP, // __builtin_longjmp EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch. TC_RETURN, // Tail call return pseudo. @@ -463,8 +463,8 @@ SDLoc dl, SelectionDAG &DAG, const CCValAssign &VA, ISD::ArgFlagsTy Flags) const; - SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerLIGHTWEIGHT_SETJMP(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerLIGHTWEIGHT_LONGJMP(SDValue Op, SelectionDAG &DAG) const; SDValue LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const; Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -830,8 +830,8 @@ // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); - setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom); - setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom); + setOperationAction(ISD::LIGHTWEIGHT_SETJMP, MVT::i32, Custom); + setOperationAction(ISD::LIGHTWEIGHT_LONGJMP, MVT::Other, Custom); setOperationAction(ISD::EH_SJLJ_SETUP_DISPATCH, MVT::Other, Custom); if (Subtarget->isTargetDarwin()) setLibcallName(RTLIB::UNWIND_RESUME, "_Unwind_SjLj_Resume"); @@ -1049,8 +1049,8 @@ case ARMISD::VMOVRRD: return "ARMISD::VMOVRRD"; case ARMISD::VMOVDRR: return "ARMISD::VMOVDRR"; - case ARMISD::EH_SJLJ_SETJMP: return "ARMISD::EH_SJLJ_SETJMP"; - case ARMISD::EH_SJLJ_LONGJMP:return "ARMISD::EH_SJLJ_LONGJMP"; + case ARMISD::LIGHTWEIGHT_SETJMP: return "ARMISD::LIGHTWEIGHT_SETJMP"; + case ARMISD::LIGHTWEIGHT_LONGJMP: return "ARMISD::LIGHTWEIGHT_LONGJMP"; case ARMISD::TC_RETURN: return "ARMISD::TC_RETURN"; @@ -2665,19 +2665,22 @@ } SDValue -ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const { +ARMTargetLowering::LowerLIGHTWEIGHT_SETJMP(SDValue Op, SelectionDAG &DAG) + const { SDLoc dl(Op); SDValue Val = DAG.getConstant(0, dl, MVT::i32); - return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, + return DAG.getNode(ARMISD::LIGHTWEIGHT_SETJMP, dl, DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0), Op.getOperand(1), Val); } SDValue -ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const { +ARMTargetLowering::LowerLIGHTWEIGHT_LONGJMP(SDValue Op, SelectionDAG &DAG) + const { SDLoc dl(Op); - return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0), - Op.getOperand(1), DAG.getConstant(0, dl, MVT::i32)); + return DAG.getNode(ARMISD::LIGHTWEIGHT_LONGJMP, dl, MVT::Other, + Op.getOperand(0), Op.getOperand(1), + DAG.getConstant(0, dl, MVT::i32)); } SDValue ARMTargetLowering::LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, @@ -6391,8 +6394,8 @@ case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); - case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); - case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); + case ISD::LIGHTWEIGHT_SETJMP: return LowerLIGHTWEIGHT_SETJMP(Op, DAG); + case ISD::LIGHTWEIGHT_LONGJMP: return LowerLIGHTWEIGHT_LONGJMP(Op, DAG); case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG, Subtarget); @@ -7547,11 +7550,11 @@ return BB; } - case ARM::Int_eh_sjlj_setjmp: - case ARM::Int_eh_sjlj_setjmp_nofp: - case ARM::tInt_eh_sjlj_setjmp: - case ARM::t2Int_eh_sjlj_setjmp: - case ARM::t2Int_eh_sjlj_setjmp_nofp: + case ARM::Int_lightweight_setjmp: + case ARM::Int_lightweight_setjmp_nofp: + case ARM::tInt_lightweight_setjmp: + case ARM::t2Int_lightweight_setjmp: + case ARM::t2Int_lightweight_setjmp_nofp: return BB; case ARM::Int_eh_sjlj_setup_dispatch: Index: lib/Target/ARM/ARMInstrInfo.td =================================================================== --- lib/Target/ARM/ARMInstrInfo.td +++ lib/Target/ARM/ARMInstrInfo.td @@ -56,9 +56,11 @@ SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; -def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>, - SDTCisInt<2>]>; -def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>; +def SDT_ARMLIGHTWEIGHT_Setjmp : SDTypeProfile<1, 2, + [SDTCisInt<0>, SDTCisPtrTy<1>, + SDTCisInt<2>]>; +def SDT_ARMLIGHTWEIGHT_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, + SDTCisInt<1>]>; def SDT_ARMEH_SJLJ_SetupDispatch: SDTypeProfile<0, 0, []>; def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>; @@ -158,12 +160,12 @@ def ARMsube : SDNode<"ARMISD::SUBE", SDTBinaryArithWithFlagsInOut>; def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; -def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", - SDT_ARMEH_SJLJ_Setjmp, - [SDNPHasChain, SDNPSideEffect]>; -def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", - SDT_ARMEH_SJLJ_Longjmp, - [SDNPHasChain, SDNPSideEffect]>; +def ARMlightweight_setjmp: SDNode<"ARMISD::LIGHTWEIGHT_SETJMP", + SDT_ARMLIGHTWEIGHT_Setjmp, + [SDNPHasChain, SDNPSideEffect]>; +def ARMlightweight_longjmp: SDNode<"ARMISD::LIGHTWEIGHT_LONGJMP", + SDT_ARMLIGHTWEIGHT_Longjmp, + [SDNPHasChain, SDNPSideEffect]>; def ARMeh_sjlj_setup_dispatch: SDNode<"ARMISD::EH_SJLJ_SETUP_DISPATCH", SDT_ARMEH_SJLJ_SetupDispatch, [SDNPHasChain, SDNPSideEffect]>; @@ -5257,7 +5259,7 @@ } //===----------------------------------------------------------------------===// -// SJLJ Exception handling intrinsics +// lightweight_setjmp/lightweight_longjmp intrinsics. // eh_sjlj_setjmp() is an instruction sequence to store the return // address and save #0 in R0 for the non-longjmp case. // Since by its nature we may be coming from some other function to get @@ -5276,28 +5278,28 @@ [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ], hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { - def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), - NoItinerary, - [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, - Requires<[IsARM, HasVFP2]>; + def Int_lightweight_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), + NoItinerary, + [(set R0, (ARMlightweight_setjmp GPR:$src, GPR:$val))]>, + Requires<[IsARM, HasVFP2]>; } let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { - def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), - NoItinerary, - [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, - Requires<[IsARM, NoVFP]>; + def Int_lightweight_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), + NoItinerary, + [(set R0, (ARMlightweight_setjmp GPR:$src, GPR:$val))]>, + Requires<[IsARM, NoVFP]>; } // FIXME: Non-IOS version(s) let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, Defs = [ R7, LR, SP ] in { -def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch), - NoItinerary, - [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, - Requires<[IsARM]>; +def Int_lightweight_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch), + NoItinerary, + [(ARMlightweight_longjmp GPR:$src, GPR:$scratch)]>, + Requires<[IsARM]>; } let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in Index: lib/Target/ARM/ARMInstrThumb.td =================================================================== --- lib/Target/ARM/ARMInstrThumb.td +++ lib/Target/ARM/ARMInstrThumb.td @@ -1288,18 +1288,18 @@ let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R12, CPSR ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in -def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val), - AddrModeNone, 0, NoItinerary, "","", - [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>; +def tInt_lightweight_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val), + AddrModeNone, 0, NoItinerary, "","", + [(set R0, (ARMlightweight_setjmp tGPR:$src, tGPR:$val))]>; // FIXME: Non-IOS version(s) let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1, Defs = [ R7, LR, SP ] in -def tInt_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch), - AddrModeNone, 0, IndexModeNone, - Pseudo, NoItinerary, "", "", - [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, - Requires<[IsThumb]>; +def tInt_lightweight_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch), + AddrModeNone, 0, IndexModeNone, + Pseudo, NoItinerary, "", "", + [(ARMlightweight_longjmp GPR:$src, GPR:$scratch)]>, + Requires<[IsThumb]>; //===----------------------------------------------------------------------===// // Non-Instruction Patterns Index: lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- lib/Target/ARM/ARMInstrThumb2.td +++ lib/Target/ARM/ARMInstrThumb2.td @@ -3464,37 +3464,39 @@ (t2STLEXH GPR:$Rt, addr_offset_none:$addr)>; //===----------------------------------------------------------------------===// -// SJLJ Exception handling intrinsics -// eh_sjlj_setjmp() is an instruction sequence to store the return +// lightweight_setjmp/lightweight_longjmp +// lightweight_setjmp() is an instruction sequence to store the return // address and save #0 in R0 for the non-longjmp case. // Since by its nature we may be coming from some other function to get // here, and we're using the stack frame for the containing function to // save/restore registers, we can't keep anything live in regs across -// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon -// when we get here from a longjmp(). We force everything out of registers -// except for our own input by listing the relevant registers in Defs. By -// doing so, we also cause the prologue/epilogue code to actively preserve -// all of the callee-saved resgisters, which is exactly what we want. +// the lightweight_setjmp(), else it will almost certainly have been tromped +// upon when we get here from a longjmp(). We force everything out of +// registers except for our own input by listing the relevant registers in +// Defs. By doing so, we also cause the prologue/epilogue code to actively +// preserve all of the callee-saved resgisters, which is exactly what we want. // $val is a scratch register for our use. let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, Q0, Q1, Q2, Q3, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in { - def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), - AddrModeNone, 0, NoItinerary, "", "", - [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, - Requires<[IsThumb2, HasVFP2]>; + def t2Int_lightweight_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), + AddrModeNone, 0, NoItinerary, "", "", + [(set R0, (ARMlightweight_setjmp tGPR:$src, tGPR:$val))]>, + Requires<[IsThumb2, HasVFP2]>; } let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in { - def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), - AddrModeNone, 0, NoItinerary, "", "", - [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, - Requires<[IsThumb2, NoVFP]>; + def t2Int_lightweight_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, + tGPR:$val), + AddrModeNone, 0, NoItinerary, "", + "", + [(set R0, (ARMlightweight_setjmp tGPR:$src, tGPR:$val))]>, + Requires<[IsThumb2, NoVFP]>; } Index: lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- lib/Target/X86/X86ISelDAGToDAG.cpp +++ lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1379,8 +1379,8 @@ Parent->getOpcode() != ISD::INTRINSIC_W_CHAIN && // unaligned loads, fixme Parent->getOpcode() != ISD::INTRINSIC_VOID && // nontemporal stores Parent->getOpcode() != X86ISD::TLSCALL && // Fixme - Parent->getOpcode() != X86ISD::EH_SJLJ_SETJMP && // setjmp - Parent->getOpcode() != X86ISD::EH_SJLJ_LONGJMP) { // longjmp + Parent->getOpcode() != X86ISD::LIGHTWEIGHT_SETJMP && // setjmp + Parent->getOpcode() != X86ISD::LIGHTWEIGHT_LONGJMP) { // longjmp unsigned AddrSpace = cast(Parent)->getPointerInfo().getAddrSpace(); // AddrSpace 256 -> GS, 257 -> FS. Index: lib/Target/X86/X86ISelLowering.h =================================================================== --- lib/Target/X86/X86ISelLowering.h +++ lib/Target/X86/X86ISelLowering.h @@ -258,11 +258,11 @@ // Exception Handling helpers. EH_RETURN, - // SjLj exception handling setjmp. - EH_SJLJ_SETJMP, + /// lightweight_setjmp intrinsic. + LIGHTWEIGHT_SETJMP, - // SjLj exception handling longjmp. - EH_SJLJ_LONGJMP, + /// lightweight_longjmp intrinsic. + LIGHTWEIGHT_LONGJMP, /// Tail call return. See X86TargetLowering::LowerCall for /// the list of operands. @@ -977,8 +977,8 @@ SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const; SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; - SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; - SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerLIGHTWEIGHT_SETJMP(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerLIGHTWEIGHT_LONGJMP(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) const; SDValue LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) const; @@ -1061,11 +1061,11 @@ MachineBasicBlock *emitLoweredTLSAddr(MachineInstr *MI, MachineBasicBlock *BB) const; - MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr *MI, - MachineBasicBlock *MBB) const; + MachineBasicBlock *emitLightweightSetJmp(MachineInstr *MI, + MachineBasicBlock *MBB) const; - MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr *MI, - MachineBasicBlock *MBB) const; + MachineBasicBlock *emitLightweightLongJmp(MachineInstr *MI, + MachineBasicBlock *MBB) const; MachineBasicBlock *emitFMA3Instr(MachineInstr *MI, MachineBasicBlock *MBB) const; Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -421,14 +421,12 @@ setOperationAction(ISD::SETCC , MVT::i64 , Custom); } setOperationAction(ISD::EH_RETURN , MVT::Other, Custom); - // NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support - // SjLj exception handling but a light-weight setjmp/longjmp replacement to - // support continuation, user-level threading, and etc.. As a result, no - // other SjLj exception interfaces are implemented and please don't build - // your own exception handling based on them. - // LLVM/Clang supports zero-cost DWARF exception handling. - setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom); - setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom); + // These intrinsics are a light-weight setjmp/longjmp replacement to support + // continuation, user-level threading, and etc.. Note: that this is not enough + // for SjLj exception handling as the other intrinsics for this are not + // implemented; Consider using the zero-cost DWARF exception handling instead. + setOperationAction(ISD::LIGHTWEIGHT_SETJMP, MVT::i32, Custom); + setOperationAction(ISD::LIGHTWEIGHT_LONGJMP, MVT::Other, Custom); // Darwin ABI issue. setOperationAction(ISD::ConstantPool , MVT::i32 , Custom); @@ -15699,18 +15697,18 @@ DAG.getRegister(StoreAddrReg, PtrVT)); } -SDValue X86TargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op, - SelectionDAG &DAG) const { +SDValue X86TargetLowering::LowerLIGHTWEIGHT_SETJMP(SDValue Op, + SelectionDAG &DAG) const { SDLoc DL(Op); - return DAG.getNode(X86ISD::EH_SJLJ_SETJMP, DL, + return DAG.getNode(X86ISD::LIGHTWEIGHT_SETJMP, DL, DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0), Op.getOperand(1)); } -SDValue X86TargetLowering::lowerEH_SJLJ_LONGJMP(SDValue Op, - SelectionDAG &DAG) const { +SDValue X86TargetLowering::LowerLIGHTWEIGHT_LONGJMP(SDValue Op, + SelectionDAG &DAG) const { SDLoc DL(Op); - return DAG.getNode(X86ISD::EH_SJLJ_LONGJMP, DL, MVT::Other, + return DAG.getNode(X86ISD::LIGHTWEIGHT_LONGJMP, DL, MVT::Other, Op.getOperand(0), Op.getOperand(1)); } @@ -17534,8 +17532,9 @@ return LowerFRAME_TO_ARGS_OFFSET(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG); - case ISD::EH_SJLJ_SETJMP: return lowerEH_SJLJ_SETJMP(Op, DAG); - case ISD::EH_SJLJ_LONGJMP: return lowerEH_SJLJ_LONGJMP(Op, DAG); + case ISD::LIGHTWEIGHT_SETJMP: return LowerLIGHTWEIGHT_SETJMP(Op, DAG); + case ISD::LIGHTWEIGHT_LONGJMP: + return LowerLIGHTWEIGHT_LONGJMP(Op, DAG); case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG); case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG); case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG); @@ -17872,8 +17871,8 @@ case X86ISD::TLSADDR: return "X86ISD::TLSADDR"; case X86ISD::TLSBASEADDR: return "X86ISD::TLSBASEADDR"; case X86ISD::TLSCALL: return "X86ISD::TLSCALL"; - case X86ISD::EH_SJLJ_SETJMP: return "X86ISD::EH_SJLJ_SETJMP"; - case X86ISD::EH_SJLJ_LONGJMP: return "X86ISD::EH_SJLJ_LONGJMP"; + case X86ISD::LIGHTWEIGHT_SETJMP: return "X86ISD::LIGHTWEIGHT_SETJMP"; + case X86ISD::LIGHTWEIGHT_LONGJMP: return "X86ISD::LIGHTWEIGHT_LONGJMP"; case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN"; case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN"; case X86ISD::FNSTCW16m: return "X86ISD::FNSTCW16m"; @@ -19122,8 +19121,8 @@ } MachineBasicBlock * -X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI, - MachineBasicBlock *MBB) const { +X86TargetLowering::emitLightweightSetJmp(MachineInstr *MI, + MachineBasicBlock *MBB) const { DebugLoc DL = MI->getDebugLoc(); MachineFunction *MF = MBB->getParent(); const TargetInstrInfo *TII = Subtarget->getInstrInfo(); @@ -19271,8 +19270,8 @@ } MachineBasicBlock * -X86TargetLowering::emitEHSjLjLongJmp(MachineInstr *MI, - MachineBasicBlock *MBB) const { +X86TargetLowering::emitLightweightLongJmp(MachineInstr *MI, + MachineBasicBlock *MBB) const { DebugLoc DL = MI->getDebugLoc(); MachineFunction *MF = MBB->getParent(); const TargetInstrInfo *TII = Subtarget->getInstrInfo(); @@ -19594,13 +19593,13 @@ case X86::VAARG_64: return EmitVAARG64WithCustomInserter(MI, BB); - case X86::EH_SjLj_SetJmp32: - case X86::EH_SjLj_SetJmp64: - return emitEHSjLjSetJmp(MI, BB); + case X86::Lightweight_SetJmp32: + case X86::Lightweight_SetJmp64: + return emitLightweightSetJmp(MI, BB); - case X86::EH_SjLj_LongJmp32: - case X86::EH_SjLj_LongJmp64: - return emitEHSjLjLongJmp(MI, BB); + case X86::Lightweight_LongJmp32: + case X86::Lightweight_LongJmp64: + return emitLightweightLongJmp(MI, BB); case TargetOpcode::STATEPOINT: // As an implementation detail, STATEPOINT shares the STACKMAP format at Index: lib/Target/X86/X86InstrCompiler.td =================================================================== --- lib/Target/X86/X86InstrCompiler.td +++ lib/Target/X86/X86InstrCompiler.td @@ -174,23 +174,23 @@ let hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in { - def EH_SjLj_SetJmp32 : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$buf), - "#EH_SJLJ_SETJMP32", - [(set GR32:$dst, (X86eh_sjlj_setjmp addr:$buf))]>, - Requires<[Not64BitMode]>; - def EH_SjLj_SetJmp64 : I<0, Pseudo, (outs GR32:$dst), (ins i64mem:$buf), - "#EH_SJLJ_SETJMP64", - [(set GR32:$dst, (X86eh_sjlj_setjmp addr:$buf))]>, - Requires<[In64BitMode]>; + def Lightweight_SetJmp32 : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$buf), + "#LIGHTWEIGHT_SETJMP32", + [(set GR32:$dst, (X86lightweight_setjmp addr:$buf))]>, + Requires<[Not64BitMode]>; + def Lightweight_SetJmp64 : I<0, Pseudo, (outs GR32:$dst), (ins i64mem:$buf), + "#LIGHTWEIGHT_SETJMP64", + [(set GR32:$dst, (X86lightweight_setjmp addr:$buf))]>, + Requires<[In64BitMode]>; let isTerminator = 1 in { - def EH_SjLj_LongJmp32 : I<0, Pseudo, (outs), (ins i32mem:$buf), - "#EH_SJLJ_LONGJMP32", - [(X86eh_sjlj_longjmp addr:$buf)]>, - Requires<[Not64BitMode]>; - def EH_SjLj_LongJmp64 : I<0, Pseudo, (outs), (ins i64mem:$buf), - "#EH_SJLJ_LONGJMP64", - [(X86eh_sjlj_longjmp addr:$buf)]>, - Requires<[In64BitMode]>; + def Lightweight_LongJmp32 : I<0, Pseudo, (outs), (ins i32mem:$buf), + "#LIGHTWEIGHT_LONGJMP32", + [(X86lightweight_longjmp addr:$buf)]>, + Requires<[Not64BitMode]>; + def Lightweight_LongJmp64 : I<0, Pseudo, (outs), (ins i64mem:$buf), + "#LIGHTWEIGHT_LONGJMP64", + [(X86lightweight_longjmp addr:$buf)]>, + Requires<[In64BitMode]>; } } } // SchedRW Index: lib/Target/X86/X86InstrInfo.td =================================================================== --- lib/Target/X86/X86InstrInfo.td +++ lib/Target/X86/X86InstrInfo.td @@ -207,13 +207,13 @@ def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, [SDNPHasChain]>; -def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP", - SDTypeProfile<1, 1, [SDTCisInt<0>, - SDTCisPtrTy<1>]>, - [SDNPHasChain, SDNPSideEffect]>; -def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP", - SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>, - [SDNPHasChain, SDNPSideEffect]>; +def X86lightweight_setjmp : SDNode<"X86ISD::LIGHTWEIGHT_SETJMP", + SDTypeProfile<1, 1, [SDTCisInt<0>, + SDTCisPtrTy<1>]>, + [SDNPHasChain, SDNPSideEffect]>; +def X86lightweight_longjmp : SDNode<"X86ISD::LIGHTWEIGHT_LONGJMP", + SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>, + [SDNPHasChain, SDNPSideEffect]>; def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;