llvm.org GIT mirror llvm / 2e50b8a
Enable variable arguments support for intrinsics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193766 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 7 years ago
5 changed file(s) with 81 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
7676 /// getIntrinsicInfoTableEntries.
7777 struct IITDescriptor {
7878 enum IITDescriptorKind {
79 Void, MMX, Metadata, Half, Float, Double,
79 Void, VarArg, MMX, Metadata, Half, Float, Double,
8080 Integer, Vector, Pointer, Struct,
8181 Argument, ExtendVecArgument, TruncVecArgument
8282 } Kind;
453453 IIT_EXTEND_VEC_ARG = 23,
454454 IIT_TRUNC_VEC_ARG = 24,
455455 IIT_ANYPTR = 25,
456 IIT_V1 = 26
456 IIT_V1 = 26,
457 IIT_VARARG = 27
457458 };
458459
459460
466467 switch (Info) {
467468 case IIT_Done:
468469 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0));
470 return;
471 case IIT_VARARG:
472 OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));
469473 return;
470474 case IIT_MMX:
471475 OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
612616
613617 switch (D.Kind) {
614618 case IITDescriptor::Void: return Type::getVoidTy(Context);
619 case IITDescriptor::VarArg: return Type::getVoidTy(Context);
615620 case IITDescriptor::MMX: return Type::getX86_MMXTy(Context);
616621 case IITDescriptor::Metadata: return Type::getMetadataTy(Context);
617622 case IITDescriptor::Half: return Type::getHalfTy(Context);
320320 bool VerifyIntrinsicType(Type *Ty,
321321 ArrayRef &Infos,
322322 SmallVectorImpl &ArgTys);
323 bool VerifyIntrinsicIsVarArg(bool isVarArg,
324 ArrayRef &Infos);
323325 bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
324326 void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
325327 bool isFunction, const Value *V);
21342136
21352137 switch (D.Kind) {
21362138 case IITDescriptor::Void: return !Ty->isVoidTy();
2139 case IITDescriptor::VarArg: return true;
21372140 case IITDescriptor::MMX: return !Ty->isX86_MMXTy();
21382141 case IITDescriptor::Metadata: return !Ty->isMetadataTy();
21392142 case IITDescriptor::Half: return !Ty->isHalfTy();
21982201 llvm_unreachable("unhandled");
21992202 }
22002203
2204 /// \brief Verify if the intrinsic has variable arguments.
2205 /// This method is intended to be called after all the fixed arguments have been
2206 /// verified first.
2207 ///
2208 /// This method returns true on error and does not print an error message.
2209 bool
2210 Verifier::VerifyIntrinsicIsVarArg(bool isVarArg,
2211 ArrayRef &Infos) {
2212 using namespace Intrinsic;
2213
2214 // If there are no descriptors left, then it can't be a vararg.
2215 if (Infos.empty())
2216 return isVarArg ? true : false;
2217
2218 // There should be only one descriptor remaining at this point.
2219 if (Infos.size() != 1)
2220 return true;
2221
2222 // Check and verify the descriptor.
2223 IITDescriptor D = Infos.front();
2224 Infos = Infos.slice(1);
2225 if (D.Kind == IITDescriptor::VarArg)
2226 return isVarArg ? false : true;
2227
2228 return true;
2229 }
2230
22012231 /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
22022232 ///
22032233 void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
22082238 // Verify that the intrinsic prototype lines up with what the .td files
22092239 // describe.
22102240 FunctionType *IFTy = IF->getFunctionType();
2211 Assert1(!IFTy->isVarArg(), "Intrinsic prototypes are not varargs", IF);
2241 bool IsVarArg = IFTy->isVarArg();
22122242
22132243 SmallVector Table;
22142244 getIntrinsicInfoTableEntries(ID, Table);
22202250 for (unsigned i = 0, e = IFTy->getNumParams(); i != e; ++i)
22212251 Assert1(!VerifyIntrinsicType(IFTy->getParamType(i), TableRef, ArgTys),
22222252 "Intrinsic has incorrect argument type!", IF);
2253
2254 // Verify if the intrinsic call matches the vararg property.
2255 if (IsVarArg)
2256 Assert1(!VerifyIntrinsicIsVarArg(IsVarArg, TableRef),
2257 "Intrinsic was not defined with variable arguments!", IF);
2258 else
2259 Assert1(!VerifyIntrinsicIsVarArg(IsVarArg, TableRef),
2260 "Callsite was not defined with variable arguments!", IF);
2261
2262 // All descriptors should be absorbed by now.
22232263 Assert1(TableRef.empty(), "Intrinsic has too few arguments!", IF);
22242264
22252265 // Now that we have the intrinsic ID and the actual argument types (and we
0 // RUN: llvm-tblgen -gen-intrinsic %s | FileCheck %s
1
2 class IntrinsicProperty;
3
4 class ValueType {
5 string Namespace = "MVT";
6 int Size = size;
7 int Value = value;
8 }
9
10 class LLVMType {
11 ValueType VT = vt;
12 }
13
14 class Intrinsic param_types = []> {
15 string LLVMName = name;
16 bit isTarget = 0;
17 string TargetPrefix = "";
18 list RetTypes = [];
19 list ParamTypes = param_types;
20 list Properties = [];
21 }
22
23 // isVoid needs to match the definition in ValueTypes.td
24 def isVoid : ValueType<0, 56>; // Produces no value
25 def llvm_vararg_ty : LLVMType; // this means vararg here
26
27 // CHECK: /* 0 */ 0, 27, 0,
28 def int_foo : Intrinsic<"llvm.foo", [llvm_vararg_ty]>;
260260 IIT_EXTEND_VEC_ARG = 23,
261261 IIT_TRUNC_VEC_ARG = 24,
262262 IIT_ANYPTR = 25,
263 IIT_V1 = 26
263 IIT_V1 = 26,
264 IIT_VARARG = 27
264265 };
265266
266267
287288 case MVT::x86mmx: return Sig.push_back(IIT_MMX);
288289 // MVT::OtherVT is used to mean the empty struct type here.
289290 case MVT::Other: return Sig.push_back(IIT_EMPTYSTRUCT);
291 // MVT::isVoid is used to represent varargs here.
292 case MVT::isVoid: return Sig.push_back(IIT_VARARG);
290293 }
291294 }
292295