[llvm-commits] [llvm] r71610 - in /llvm/trunk: include/llvm/CodeGen/MachineFunction.h include/llvm/Intrinsics.td lib/CodeGen/MachineFunction.cpp lib/CodeGen/PrologEpilogInserter.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/ARMInstrInfo.cpp lib/Target/ARM/ARMInstrInfo.td

Evan Cheng evan.cheng at apple.com
Tue May 12 18:36:47 PDT 2009


Thanks Jim. But can you pick better names than builtinsetjmp /  
longjmp? These are not really setjmp / longjmp.

Evan

On May 12, 2009, at 4:59 PM, Jim Grosbach wrote:

> Author: grosbach
> Date: Tue May 12 18:59:14 2009
> New Revision: 71610
>
> URL: http://llvm.org/viewvc/llvm-project?rev=71610&view=rev
> Log:
> Add support for GCC compatible builtin setjmp and longjmp  
> intrinsics. This is
> a supporting preliminary patch for GCC-compatible SjLJ exception  
> handling. Note that these intrinsics are not designed to be invoked  
> directly by the user, but
> rather used by the front-end as target hooks for exception handling.
>
>
> Modified:
>    llvm/trunk/include/llvm/CodeGen/MachineFunction.h
>    llvm/trunk/include/llvm/Intrinsics.td
>    llvm/trunk/lib/CodeGen/MachineFunction.cpp
>    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
>    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>    llvm/trunk/lib/Target/ARM/ARMISelLowering.h
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
>
> Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Tue May 12  
> 18:59:14 2009
> @@ -70,6 +70,10 @@
>   const Function *Fn;
>   const TargetMachine &Target;
>
> +  // HasBuiltinSetjmp - true if the function uses builtin_setjmp.  
> Used to
> +  // adjust callee-saved register tracking.
> +  bool HasBuiltinSetjmp;
> +
>   // RegInfo - Information about each register in use in the function.
>   MachineRegisterInfo *RegInfo;
>
> @@ -123,6 +127,14 @@
>   ///
>   const TargetMachine &getTarget() const { return Target; }
>
> +  /// doesHaveBuiltinSetjmp - Return whether this function uses  
> builtin_setjmp
> +  ///
> +  bool doesHaveBuiltinSetjmp() const { return HasBuiltinSetjmp; }
> +
> +  /// setHasBuiltinSetjmp - Mark whether this function uses  
> builtin_setjmp
> +  ///
> +  void setHasBuiltinSetjmp (bool flag) { HasBuiltinSetjmp = flag; }
> +
>   /// getRegInfo - Return information about the registers currently  
> in use.
>   ///
>   MachineRegisterInfo &getRegInfo() { return *RegInfo; }
>
> Modified: llvm/trunk/include/llvm/Intrinsics.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/Intrinsics.td (original)
> +++ llvm/trunk/include/llvm/Intrinsics.td Tue May 12 18:59:14 2009
> @@ -299,6 +299,11 @@
>
> def int_eh_dwarf_cfa  : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
>
> +let Properties = [IntrNoMem] in {
> +def int_builtinsetjmp  : Intrinsic<[llvm_i32_ty],  [llvm_ptr_ty]>;
> +def int_builtinlongjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty,  
> llvm_i32_ty]>;
> +}
> +
> //===---------------- Generic Variable Attribute  
> Intrinsics----------------===//
> //
> def int_var_annotation : Intrinsic<[llvm_void_ty],
>
> Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original)
> +++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Tue May 12 18:59:14  
> 2009
> @@ -121,6 +121,7 @@
>                   MachineRegisterInfo(*TM.getRegisterInfo());
>   else
>     RegInfo = 0;
> +  HasBuiltinSetjmp = false;
>   MFInfo = 0;
>   FrameInfo = new (Allocator.Allocate<MachineFrameInfo>())
>                   MachineFrameInfo(*TM.getFrameInfo());
>
> Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)
> +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Tue May 12  
> 18:59:14 2009
> @@ -180,7 +180,7 @@
>   std::vector<CalleeSavedInfo> CSI;
>   for (unsigned i = 0; CSRegs[i]; ++i) {
>     unsigned Reg = CSRegs[i];
> -    if (Fn.getRegInfo().isPhysRegUsed(Reg)) {
> +    if (Fn.getRegInfo().isPhysRegUsed(Reg) ||  
> Fn.doesHaveBuiltinSetjmp()) {
>         // If the reg is modified, save it!
>       CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i]));
>     } else {
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp  
> (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue  
> May 12 18:59:14 2009
> @@ -3849,6 +3849,12 @@
>   case Intrinsic::longjmp:
>     return "_longjmp"+!TLI.usesUnderscoreLongJmp();
>     break;
> +  case Intrinsic::builtinsetjmp:
> +    // Mark this function has using builtin_setjmp so context gets  
> preserved
> +    DAG.getMachineFunction().setHasBuiltinSetjmp(true);
> +    // Turn it into a target intrinsic node for the codegen
> +    visitTargetIntrinsic(I, Intrinsic);
> +    return 0;
>   case Intrinsic::memcpy: {
>     SDValue Op1 = getValue(I.getOperand(1));
>     SDValue Op2 = getValue(I.getOperand(2));
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue May 12  
> 18:59:14 2009
> @@ -1035,14 +1035,19 @@
>   return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
> }
>
> -static SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG  
> &DAG) {
> +SDValue
> +ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG  
> &DAG) {
>   MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
>   unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))- 
> >getZExtValue();
> +  DebugLoc dl = Op.getDebugLoc();
>   switch (IntNo) {
>   default: return SDValue();    // Don't custom lower most intrinsics.
>   case Intrinsic::arm_thread_pointer:
> -      return DAG.getNode(ARMISD::THREAD_POINTER,  
> DebugLoc::getUnknownLoc(),
> -                         PtrVT);
> +      return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
> +  case Intrinsic::builtinsetjmp:
> +      SDValue Res = DAG.getNode(ARMISD::BUILTIN_SETJMP, dl, MVT::i32,
> +                         Op.getOperand(1));
> +      return Res;
>   }
> }
>
> @@ -1431,6 +1436,20 @@
>   return DAG.getNode(ARMISD::CNEG, dl, VT, AbsVal, AbsVal, ARMCC,  
> CCR, Cmp);
> }
>
> +SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG  
> &DAG) {
> +  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
> +  MFI->setFrameAddressIsTaken(true);
> +  MVT VT = Op.getValueType();
> +  DebugLoc dl = Op.getDebugLoc();  // FIXME probably not meaningful
> +  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))- 
> >getZExtValue();
> +  unsigned FrameReg = (Subtarget->isThumb() || Subtarget- 
> >useThumbBacktraces())
> +    ? ARM::R7 : ARM::R11;
> +  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,  
> FrameReg, VT);
> +  while (Depth--)
> +    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,  
> NULL, 0);
> +  return FrameAddr;
> +}
> +
> SDValue
> ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,  
> DebugLoc dl,
>                                            SDValue Chain,
> @@ -1612,7 +1631,7 @@
>   case ISD::FCOPYSIGN:     return LowerFCOPYSIGN(Op, DAG);
>   case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
>   case ISD::RETURNADDR:    break;
> -  case ISD::FRAMEADDR:     break;
> +  case ISD::FRAMEADDR:     return LowerFRAMEADDR(Op, DAG);
>   case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op,  
> DAG);
>   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op,  
> DAG);
>   case ISD::BIT_CONVERT:   return ExpandBIT_CONVERT(Op.getNode(),  
> DAG);
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Tue May 12 18:59:14  
> 2009
> @@ -64,6 +64,9 @@
>       FMRRD,        // double to two gprs.
>       FMDRR,         // Two gprs to double.
>
> +      BUILTIN_SETJMP,   // exception handling setjmp
> +      BUILTIN_LONGJMP,  // exception handling longjmp
> +
>       THREAD_POINTER
>     };
>   }
> @@ -154,6 +157,7 @@
>     SDNode *LowerCallResult(SDValue Chain, SDValue InFlag,  
> CallSDNode *TheCall,
>                             unsigned CallingConv, SelectionDAG &DAG);
>     SDValue LowerCALL(SDValue Op, SelectionDAG &DAG);
> +    SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG);
> @@ -165,6 +169,7 @@
>     SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG);
> +    SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG);
>
>     SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
>                                       SDValue Chain,
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Tue May 12 18:59:14  
> 2009
> @@ -991,6 +991,7 @@
>       // If this machine instr is a constant pool entry, its size is  
> recorded as
>       // operand #2.
>       return MI->getOperand(2).getImm();
> +    case ARM::Int_builtin_setjmp: return 12;
>     case ARM::BR_JTr:
>     case ARM::BR_JTm:
>     case ARM::BR_JTadd:
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=71610&r1=71609&r2=71610&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue May 12 18:59:14 2009
> @@ -40,6 +40,7 @@
>                                           SDTCisPtrTy<1>,  
> SDTCisVT<2, i32>]>;
>
> def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
> +def SDT_ARMBuiltinSetjmp : SDTypeProfile<1, 1, [SDTCisInt<0>,  
> SDTCisPtrTy<1>]>;
>
> // Node definitions.
> def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
> @@ -84,6 +85,7 @@
> def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp,  
> [SDNPInFlag ]>;
>
> def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER",  
> SDT_ARMThreadPointer>;
> +def ARMbuiltin_setjmp: SDNode<"ARMISD::BUILTIN_SETJMP",  
> SDT_ARMBuiltinSetjmp>;
>
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> // ARM Instruction Predicate Definitions.
> @@ -1266,6 +1268,27 @@
> }
>
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +// SJLJ Exception handling intrinsics
> +//   setjmp() is a three 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 setjmp(), else it will almost certainly have been tromped  
> upon
> +//   when we get here from a longjmp(). We force everthing out of  
> registers
> +//   except for our own input by listing the relevant registers in  
> Defs.
> +let Defs =
> +  [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR,
> +    D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14,  
> D15 ] in {
> +  def Int_builtin_setjmp : XI<(outs), (ins GPR:$src),
> +                               AddrModeNone, SizeSpecial,  
> IndexModeNone, Pseudo,
> +                               "add r0, pc, #4\n\t"
> +                               "str r0, [$src, #+4]\n\t"
> +                               "mov r0, #0 @ setjmp", "",
> +                               [(set R0, (ARMbuiltin_setjmp GPR: 
> $src))]>;
> +}
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> // Non-Instruction Patterns
> //
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list