llvm.org GIT mirror llvm / 36397f5
Support for trampolines, except for X86 codegen which is still under discussion. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40549 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 13 years ago
20 changed file(s) with 253 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
199199
  • 'llvm.memory.barrier' Intrinsic
  • 200200
    201201
    202
  • Trampoline Intrinsics
  • 203
    204
  • 'llvm.init.trampoline' Intrinsic
  • 205
  • 'llvm.adjust.trampoline' Intrinsic
  • 206
    207
    202208
  • General intrinsics
  • 203209
    204210
  • 51225128
    51235129
    51245130
    5131 Trampoline Intrinsics
    5132
    5133
    5134
    5135

    5136 These intrinsics make it possible to excise one parameter, marked with
    5137 the nest attribute, from a function. The result is a callable
    5138 function pointer lacking the nest parameter - the caller does not need
    5139 to provide a value for it. Instead, the value to use is stored in
    5140 advance in a "trampoline", a block of memory usually allocated
    5141 on the stack, which also contains code to splice the nest value into the
    5142 argument list. This is used to implement the GCC nested function address
    5143 extension.
    5144

    5145

    5146 For example, if the function is
    5147 i32 f(i8* nest %c, i32 %x, i32 %y) then the resulting function
    5148 pointer has signature i32 (i32, i32)*. It can be created as follows:
    5149
    
                      
                    
    5150 %tramp1 = alloca [10 x i8], align 4 ; size and alignment only correct for X86
    5151 %tramp = getelementptr [10 x i8]* %tramp1, i32 0, i32 0
    5152 call void @llvm.init.trampoline( i8* %tramp, i8* bitcast (i32 (i8* nest , i32, i32)* @f to i8*), i8* %nval )
    5153 %adj = call i8* @llvm.adjust.trampoline( i8* %tramp )
    5154 %fp = bitcast i8* %adj to i32 (i32, i32)*
    5155
    5156 The call %val = call i32 %fp( i32 %x, i32 %y ) is then equivalent to
    5157 %val = call i32 %f( i8* %nval, i32 %x, i32 %y ).
    5158

    5159

    5160 Trampolines are currently only supported on the X86 architecture.
    5161

    5162
    5163
    5164
    5165
    5166 'llvm.init.trampoline' Intrinsic
    5167
    5168
    5169
    Syntax:
    5170
    
                      
                    
    5171 declare void @llvm.init.trampoline(i8* <tramp>, i8* <func>, i8* <nval>)
    5172
    5173
    Overview:
    5174

    5175 This initializes the memory pointed to by tramp as a trampoline.
    5176

    5177
    Arguments:
    5178

    5179 The llvm.init.trampoline intrinsic takes three arguments, all
    5180 pointers. The tramp argument must point to a sufficiently large
    5181 and sufficiently aligned block of memory; this memory is written to by the
    5182 intrinsic. Currently LLVM provides no help in determining just how big and
    5183 aligned the memory needs to be. The func argument must hold a
    5184 function bitcast to an i8*.
    5185

    5186
    Semantics:
    5187

    5188 The block of memory pointed to by tramp is filled with target
    5189 dependent code, turning it into a function.
    5190 The new function's signature is the same as that of func with
    5191 any arguments marked with the nest attribute removed. At most
    5192 one such nest argument is allowed, and it must be of pointer
    5193 type. Calling the new function is equivalent to calling func
    5194 with the same argument list, but with nval used for the missing
    5195 nest argument.
    5196

    5197
    5198
    5199
    5200
    5201 'llvm.adjust.trampoline' Intrinsic
    5202
    5203
    5204
    Syntax:
    5205
    
                      
                    
    5206 declare i8* @llvm.adjust.trampoline(i8* <tramp>)
    5207
    5208
    Overview:
    5209

    5210 This intrinsic returns a function pointer suitable for executing
    5211 the trampoline code pointed to by tramp.
    5212

    5213
    Arguments:
    5214

    5215 The llvm.adjust.trampoline takes one argument, a pointer to a
    5216 trampoline initialized by the
    5217 'llvm.init.trampoline' intrinsic.
    5218

    5219
    Semantics:
    5220

    5221 A function pointer that can be used to execute the trampoline code in
    5222 tramp is returned. The returned value should be bitcast to an
    5223 appropriate function pointer type
    5224 before being called.
    5225

    5226
    5227
    5228
    5229
    51255230 General Intrinsics
    51265231
    51275232
    6565 StructReturnOffs = 3,
    6666 ByVal = 1<<4, ///< Struct passed by value
    6767 ByValOffs = 4,
    68 Nest = 1<<5, ///< Parameter is nested function static chain
    69 NestOffs = 5,
    6870 OrigAlignment = 0x1F<<27,
    6971 OrigAlignmentOffs = 27
    7072 };
    527529 // number, then a column then a file id (provided by MachineModuleInfo.) It
    528530 // produces a token chain as output.
    529531 DEBUG_LOC,
    530
    532
    533 // ADJUST_TRAMP - This corresponds to the adjust_trampoline intrinsic.
    534 // It takes a value as input and returns a value as output.
    535 ADJUST_TRAMP,
    536
    537 // TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
    538 // It takes as input a token chain, the pointer to the trampoline,
    539 // the pointer to the nested function, the pointer to pass for the
    540 // 'nest' parameter, a SRCVALUE for the trampoline and another for
    541 // the nested function (allowing targets to access the original
    542 // Function*). It produces a token chain as output.
    543 TRAMPOLINE,
    544
    531545 // BUILTIN_OP_END - This must be the last enum value in this list.
    532546 BUILTIN_OP_END
    533547 };
    246246 llvm_ptr_ty, llvm_i32_ty],
    247247 [], "llvm.var.annotation">;
    248248
    249 //===------------------------ Trampoline Intrinsics -----------------------===//
    250 //
    251 def int_init_trampoline : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
    252 llvm_ptr_ty], []>,
    253 GCCBuiltin<"__builtin_init_trampoline">;
    254 def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty], [IntrNoMem]>,
    255 GCCBuiltin<"__builtin_adjust_trampoline">;
    256
    249257 //===----------------------------------------------------------------------===//
    250258 // Target-specific intrinsics
    251259 //===----------------------------------------------------------------------===//
    2929 /// @brief Function parameter attributes.
    3030 enum Attributes {
    3131 None = 0, ///< No attributes have been set
    32 ZExt = 1 << 0, ///< zero extended before/after call
    33 SExt = 1 << 1, ///< sign extended before/after call
    34 NoReturn = 1 << 2, ///< mark the function as not returning
    35 InReg = 1 << 3, ///< force argument to be passed in register
    36 StructRet = 1 << 4, ///< hidden pointer to structure to return
    32 ZExt = 1 << 0, ///< Zero extended before/after call
    33 SExt = 1 << 1, ///< Sign extended before/after call
    34 NoReturn = 1 << 2, ///< Mark the function as not returning
    35 InReg = 1 << 3, ///< Force argument to be passed in register
    36 StructRet = 1 << 4, ///< Hidden pointer to structure to return
    3737 NoUnwind = 1 << 5, ///< Function doesn't unwind stack
    38 NoAlias = 1 << 6, ///< Considered to not alias after call.
    39 ByVal = 1 << 7 ///< Pass structure by value
    38 NoAlias = 1 << 6, ///< Considered to not alias after call
    39 ByVal = 1 << 7, ///< Pass structure by value
    40 Nest = 1 << 8 ///< Nested function static chain
    4041 };
    4142
    4243 }
    811811 bool isZExt;
    812812 bool isInReg;
    813813 bool isSRet;
    814
    815 ArgListEntry():isSExt(false), isZExt(false), isInReg(false), isSRet(false) { };
    814 bool isNest;
    815
    816 ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
    817 isSRet(false), isNest(false) { };
    816818 };
    817819 typedef std::vector ArgListTy;
    818820 virtual std::pair
    232232 noreturn { return NORETURN; }
    233233 noalias { return NOALIAS; }
    234234 byval { return BYVAL; }
    235 nest { return NEST; }
    235236
    236237 void { RET_TY(Type::VoidTy, VOID); }
    237238 float { RET_TY(Type::FloatTy, FLOAT); }
    11001100 %token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
    11011101
    11021102 // Function Attributes
    1103 %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL
    1103 %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
    11041104
    11051105 // Visibility Styles
    11061106 %token DEFAULT HIDDEN PROTECTED
    12281228 | INREG { $$ = ParamAttr::InReg; }
    12291229 | SRET { $$ = ParamAttr::StructRet; }
    12301230 | NOALIAS { $$ = ParamAttr::NoAlias; }
    1231 | BYVAL { $$ = ParamAttr::ByVal; }
    1231 | BYVAL { $$ = ParamAttr::ByVal; }
    1232 | NEST { $$ = ParamAttr::Nest; }
    12321233 ;
    12331234
    12341235 OptParamAttrs : /* empty */ { $$ = ParamAttr::None; }
    31533153 }
    31543154 break;
    31553155 }
    3156 break;
    3157 }
    3158 case ISD::ADJUST_TRAMP: {
    3159 Tmp1 = LegalizeOp(Node->getOperand(0));
    3160 switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
    3161 default: assert(0 && "This action is not supported yet!");
    3162 case TargetLowering::Custom:
    3163 Result = DAG.UpdateNodeOperands(Result, Tmp1);
    3164 Result = TLI.LowerOperation(Result, DAG);
    3165 if (Result.Val) break;
    3166 // FALL THROUGH
    3167 case TargetLowering::Expand:
    3168 Result = Tmp1;
    3169 break;
    3170 }
    3171 break;
    3172 }
    3173 case ISD::TRAMPOLINE: {
    3174 SDOperand Ops[6];
    3175 for (unsigned i = 0; i != 6; ++i)
    3176 Ops[i] = LegalizeOp(Node->getOperand(i));
    3177 Result = DAG.UpdateNodeOperands(Result, Ops, 6);
    3178 // The only option for this node is to custom lower it.
    3179 Result = TLI.LowerOperation(Result, DAG);
    3180 assert(Result.Val && "Should always custom lower!");
    31563181 break;
    31573182 }
    31583183 }
    35123512 case ISD::LOCATION: return "location";
    35133513 case ISD::DEBUG_LOC: return "debug_loc";
    35143514
    3515 // Trampolines
    3516 case ISD::ADJUST_TRAMP: return "adjust_tramp";
    3517 case ISD::TRAMPOLINE: return "trampoline";
    3518
    35153519 case ISD::CONDCODE:
    35163520 switch (cast(this)->get()) {
    35173521 default: assert(0 && "Unknown setcc condition!");
    28622862 case Intrinsic::var_annotation:
    28632863 // Discard annotate attributes
    28642864 return 0;
    2865
    2866 case Intrinsic::adjust_trampoline: {
    2867 SDOperand Arg = getValue(I.getOperand(1));
    2868 setValue(&I, DAG.getNode(ISD::ADJUST_TRAMP, TLI.getPointerTy(), Arg));
    2869 return 0;
    2870 }
    2871
    2872 case Intrinsic::init_trampoline: {
    2873 const Function *F =
    2874 cast(IntrinsicInst::StripPointerCasts(I.getOperand(2)));
    2875
    2876 SDOperand Ops[6];
    2877 Ops[0] = getRoot();
    2878 Ops[1] = getValue(I.getOperand(1));
    2879 Ops[2] = getValue(I.getOperand(2));
    2880 Ops[3] = getValue(I.getOperand(3));
    2881 Ops[4] = DAG.getSrcValue(I.getOperand(1));
    2882 Ops[5] = DAG.getSrcValue(F);
    2883
    2884 DAG.setRoot(DAG.getNode(ISD::TRAMPOLINE, MVT::Other, Ops, 6));
    2885 return 0;
    2886 }
    28652887 }
    28662888 }
    28672889
    28912913 Entry.isZExt = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ZExt);
    28922914 Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg);
    28932915 Entry.isSRet = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet);
    2916 Entry.isNest = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest);
    28942917 Args.push_back(Entry);
    28952918 }
    28962919
    38263849 Flags |= ISD::ParamFlags::StructReturn;
    38273850 if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal))
    38283851 Flags |= ISD::ParamFlags::ByVal;
    3852 if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest))
    3853 Flags |= ISD::ParamFlags::Nest;
    38293854 Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
    38303855
    38313856 switch (getTypeAction(VT)) {
    39443969 Flags |= ISD::ParamFlags::InReg;
    39453970 if (Args[i].isSRet)
    39463971 Flags |= ISD::ParamFlags::StructReturn;
    3972 if (Args[i].isNest)
    3973 Flags |= ISD::ParamFlags::Nest;
    39473974 Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
    39483975
    39493976 switch (getTypeAction(VT)) {
    189189 setOperationAction(ISD::MEMSET , MVT::Other, Expand);
    190190 setOperationAction(ISD::MEMCPY , MVT::Other, Custom);
    191191 setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
    192
    192
    193 if (Subtarget->isThumb())
    194 setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Custom);
    195 else
    196 setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
    197
    193198 // Use the default implementation.
    194199 setOperationAction(ISD::VASTART , MVT::Other, Expand);
    195200 setOperationAction(ISD::VAARG , MVT::Other, Expand);
    14121417 return Chain;
    14131418 }
    14141419
    1420 SDOperand ARMTargetLowering::LowerADJUST_TRAMP(SDOperand Op,
    1421 SelectionDAG &DAG) {
    1422 // Thumb trampolines should be entered in thumb mode, so set the bottom bit
    1423 // of the address.
    1424 return DAG.getNode(ISD::OR, MVT::i32, Op.getOperand(0),
    1425 DAG.getConstant(1, MVT::i32));
    1426 }
    1427
    14151428 SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
    14161429 switch (Op.getOpcode()) {
    14171430 default: assert(0 && "Don't know how to custom lower this!"); abort();
    14431456 case ISD::FRAMEADDR: break;
    14441457 case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
    14451458 case ISD::MEMCPY: return LowerMEMCPY(Op, DAG);
    1459 case ISD::ADJUST_TRAMP: return LowerADJUST_TRAMP(Op, DAG);
    14461460 }
    14471461 return SDOperand();
    14481462 }
    137137 SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
    138138 SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);
    139139 SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG);
    140 SDOperand LowerADJUST_TRAMP(SDOperand Op, SelectionDAG &DAG);
    140141 };
    141142 }
    142143
    122122 setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
    123123 setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom);
    124124 setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
    125
    126 setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
    127 setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand);
    125128
    126129 setOperationAction(ISD::VASTART, MVT::Other, Custom);
    127130 setOperationAction(ISD::VAEND, MVT::Other, Expand);
    9595 setOperationAction(ISD::ROTL , MVT::i64 , Expand);
    9696 setOperationAction(ISD::ROTR , MVT::i64 , Expand);
    9797 setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev
    98
    99 setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand);
    98100
    99101 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
    100102 setOperationAction(ISD::VAARG , MVT::Other, Custom);
    100100 // Use the default for now
    101101 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
    102102 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
    103
    104 setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
    103105
    104106 setStackPointerRegisterToSaveRestore(Mips::SP);
    105107 computeRegisterProperties();
    168168
    169169 // RET must be custom lowered, to meet ABI requirements
    170170 setOperationAction(ISD::RET , MVT::Other, Custom);
    171
    171
    172 setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
    173 setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand);
    174
    172175 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
    173176 setOperationAction(ISD::VASTART , MVT::Other, Custom);
    174177
    214214
    215215 // RET must be custom lowered, to meet ABI requirements
    216216 setOperationAction(ISD::RET , MVT::Other, Custom);
    217
    217
    218 setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
    219
    218220 // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
    219221 setOperationAction(ISD::VASTART , MVT::Other, Custom);
    220222 // VAARG needs to be lowered to not do unaligned accesses for doubles.
    4444 /// the specified action.
    4545 class CCIfInReg : CCIf<"ArgFlags & ISD::ParamFlags::InReg", A> {}
    4646
    47 /// CCIfNest - If this argument is marked with the 'nest' attribute, apply
    48 /// the specified action.
    49 class CCIfNest : CCIf<"ArgFlags & ISD::ParamFlags::Nest", A> {}
    50
    4751 /// CCIfNotVarArg - If the current function is not vararg - apply the action
    4852 class CCIfNotVarArg : CCIf<"!State.isVarArg()", A> {}
    4953
    104104 Result += "sret ";
    105105 if (Attrs & ParamAttr::ByVal)
    106106 Result += "byval ";
    107 if (Attrs & ParamAttr::Nest)
    108 Result += "nest ";
    107109 return Result;
    108110 }
    109111
    360360
    361361 if (const ParamAttrsList *Attrs = FT->getParamAttrs()) {
    362362 unsigned Idx = 1;
    363 bool SawNest = false;
    363364
    364365 Assert1(!Attrs->paramHasAttr(0, ParamAttr::ByVal),
    365366 "Attribute ByVal should not apply to functions!", &F);
    367368 "Attribute SRet should not apply to functions!", &F);
    368369 Assert1(!Attrs->paramHasAttr(0, ParamAttr::InReg),
    369370 "Attribute InReg should not apply to functions!", &F);
    371 Assert1(!Attrs->paramHasAttr(0, ParamAttr::Nest),
    372 "Attribute Nest should not apply to functions!", &F);
    370373
    371374 for (FunctionType::param_iterator I = FT->param_begin(),
    372375 E = FT->param_end(); I != E; ++I, ++Idx) {
    388391 cast(FT->getParamType(Idx-1));
    389392 Assert1(isa(Ty->getElementType()),
    390393 "Attribute ByVal should only apply to pointer to structs!", &F);
    394 }
    395
    396 if (Attrs->paramHasAttr(Idx, ParamAttr::Nest)) {
    397 Assert1(!SawNest, "More than one parameter has attribute Nest!", &F);
    398 SawNest = true;
    399
    400 Assert1(isa(FT->getParamType(Idx-1)),
    401 "Attribute Nest should only apply to Pointer type!", &F);
    402 Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::ByVal),
    403 "Attributes Nest and ByVal are incompatible!", &F);
    404 Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::InReg),
    405 "Attributes Nest and InReg are incompatible!", &F);
    406 Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::StructRet),
    407 "Attributes Nest and StructRet are incompatible!", &F);
    391408 }
    392409
    393410 Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoReturn),