From 46aaf69e37287a9696b6cc5c49d10d0937ff052b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 17 May 2012 04:30:58 +0000 Subject: [PATCH] strengthen the intrinsic descriptor stuff to be able to handle sin, cos and other intrinsics that use passed-in arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156977 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/Function.cpp | 31 +++++--- utils/TableGen/IntrinsicEmitter.cpp | 117 +++++++++++++++------------- 2 files changed, 84 insertions(+), 64 deletions(-) diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index eb5ffb38c81..9aa7d0eadeb 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -361,11 +361,13 @@ std::string Intrinsic::getName(ID id, ArrayRef Tys) { #include "llvm/Intrinsics.gen" #undef GET_INTRINSTIC_GENERATOR_GLOBAL -static Type *DecodeFixedType(unsigned &TableVal, LLVMContext &Context) { +static Type *DecodeFixedType(unsigned &TableVal, ArrayRef Tys, + LLVMContext &Context) { unsigned Nibble = TableVal & 0xF; TableVal >>= 4; switch ((IIT_Info)Nibble) { + default: assert(0 && "Unknown argument type!"); case IIT_Done: return Type::getVoidTy(Context); case IIT_I1: return Type::getInt1Ty(Context); case IIT_I8: return Type::getInt8Ty(Context); @@ -374,13 +376,23 @@ static Type *DecodeFixedType(unsigned &TableVal, LLVMContext &Context) { case IIT_I64: return Type::getInt64Ty(Context); case IIT_F32: return Type::getFloatTy(Context); case IIT_F64: return Type::getDoubleTy(Context); - case IIT_V2: return VectorType::get(DecodeFixedType(TableVal, Context), 2); - case IIT_V4: return VectorType::get(DecodeFixedType(TableVal, Context), 4); - case IIT_V8: return VectorType::get(DecodeFixedType(TableVal, Context), 8); - case IIT_V16: return VectorType::get(DecodeFixedType(TableVal, Context), 16); case IIT_MMX: return Type::getX86_MMXTy(Context); - case IIT_PTR: return PointerType::get(DecodeFixedType(TableVal, Context),0); - case IIT_ARG: assert(0 && "Unimp!"); + case IIT_V2: + return VectorType::get(DecodeFixedType(TableVal, Tys, Context), 2); + case IIT_V4: + return VectorType::get(DecodeFixedType(TableVal, Tys, Context), 4); + case IIT_V8: + return VectorType::get(DecodeFixedType(TableVal, Tys, Context), 8); + case IIT_V16: + return VectorType::get(DecodeFixedType(TableVal, Tys, Context), 16); + case IIT_PTR: + return PointerType::getUnqual(DecodeFixedType(TableVal, Tys, Context)); + case IIT_ARG: { + unsigned ArgNo = TableVal & 0xF; + TableVal >>= 4; + assert(ArgNo < Tys.size() && "Not enough types specified!"); + return Tys[ArgNo]; + } } llvm_unreachable("unhandled"); } @@ -394,15 +406,14 @@ FunctionType *Intrinsic::getType(LLVMContext &Context, // Check to see if the intrinsic's type was expressible by the table. unsigned TableVal = IIT_Table[id-1]; if (TableVal != ~0U) { - ResultTy = DecodeFixedType(TableVal, Context); + ResultTy = DecodeFixedType(TableVal, Tys, Context); while (TableVal) - ArgTys.push_back(DecodeFixedType(TableVal, Context)); + ArgTys.push_back(DecodeFixedType(TableVal, Tys, Context)); return FunctionType::get(ResultTy, ArgTys, false); } - #define GET_INTRINSIC_GENERATOR #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_GENERATOR diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index bd4798235c8..d138a75c178 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -404,6 +404,7 @@ static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, // NOTE: This must be kept in synch with the version emitted to the .gen file! enum IIT_Info { + // Common values should be encoded with 0-15. IIT_Done = 0, IIT_I1 = 1, IIT_I8 = 2, @@ -418,9 +419,21 @@ enum IIT_Info { IIT_V16 = 11, IIT_MMX = 12, IIT_PTR = 13, - IIT_ARG = 14 + IIT_ARG = 14, + // 15 + + // Values from 16+ are only encodable with the inefficient encoding. + IIT_F16 = 16, + IIT_F80 = 17, + IIT_F128 = 18, + IIT_PPC128 = 19, + IIT_METADATA = 20, + IIT_EMPTYSTRUCT = 21, + IIT_V32 = 22 + }; + static void EncodeFixedValueType(MVT::SimpleValueType VT, SmallVectorImpl &Sig) { if (EVT(VT).isInteger()) { @@ -435,65 +448,52 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT, } } -/* } else if (VT == MVT::Other) { - // MVT::OtherVT is used to mean the empty struct type here. - OS << "StructType::get(Context)"; - } else if (VT == MVT::f16) { - OS << "Type::getHalfTy(Context)";*/ - if (VT == MVT::f32) - return Sig.push_back(IIT_F32); - if (VT == MVT::f64) - return Sig.push_back(IIT_F64); - //if (VT == MVT::f80) { - // OS << "Type::getX86_FP80Ty(Context)"; - //if (VT == MVT::f128) { - // OS << "Type::getFP128Ty(Context)"; - // if (VT == MVT::ppcf128) { - // OS << "Type::getPPC_FP128Ty(Context)"; - //if (VT == MVT::Metadata) { - // OS << "Type::getMetadataTy(Context)"; - if (VT == MVT::x86mmx) - return Sig.push_back(IIT_MMX); - - assert(VT != MVT::isVoid); - Sig.push_back(~0U); + switch (VT) { + default: assert(0 && "Unknown Type!"); + case MVT::f16: return Sig.push_back(IIT_F16); + case MVT::f32: return Sig.push_back(IIT_F32); + case MVT::f64: return Sig.push_back(IIT_F64); + case MVT::f80: return Sig.push_back(IIT_F80); + case MVT::f128: return Sig.push_back(IIT_F128); + case MVT::ppcf128: return Sig.push_back(IIT_PPC128); + case MVT::Metadata: return Sig.push_back(IIT_METADATA); + case MVT::x86mmx: return Sig.push_back(IIT_MMX); + // MVT::OtherVT is used to mean the empty struct type here. + case MVT::Other: return Sig.push_back(IIT_EMPTYSTRUCT); + } } #ifdef _MSC_VER #pragma optimize("",off) // MSVC 2010 optimizer can't deal with this function. #endif -static void EncodeFixedType(Record *R, SmallVectorImpl &Sig) { +static void EncodeFixedType(Record *R, unsigned &NextArgNo, + SmallVectorImpl &Sig) { if (R->isSubClassOf("LLVMMatchType")) { - return Sig.push_back(~0U); -/* - unsigned Number = ArgType->getValueAsInt("Number"); - assert(Number < ArgNo && "Invalid matching number!"); - if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) - OS << "VectorType::getExtendedElementVectorType" - << "(cast(Tys[" << Number << "]))"; - else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) - OS << "VectorType::getTruncatedElementVectorType" - << "(cast(Tys[" << Number << "]))"; - else - OS << "Tys[" << Number << "]"; - */ + unsigned Number = R->getValueAsInt("Number"); + assert(Number < NextArgNo && "Invalid matching number!"); + if (R->isSubClassOf("LLVMExtendedElementVectorType")) + return Sig.push_back(~0U); + + //OS << "VectorType::getExtendedElementVectorType" + // << "(cast(Tys[" << Number << "]))"; + if (R->isSubClassOf("LLVMTruncatedElementVectorType")) + return Sig.push_back(~0U); + //OS << "VectorType::getTruncatedElementVectorType" + // << "(cast(Tys[" << Number << "]))"; + Sig.push_back(IIT_ARG); + return Sig.push_back(Number); } MVT::SimpleValueType VT = getValueType(R->getValueAsDef("VT")); - - if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny || + + // If this is an "any" valuetype, then the type is the type of the next + // type in the list specified to getIntrinsic(). + if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny || VT == MVT::iPTRAny) { - return Sig.push_back(~0U); - /* - // NOTE: The ArgNo variable here is not the absolute argument number, it is - // the index of the "arbitrary" type in the Tys array passed to the - // Intrinsic::getDeclaration function. Consequently, we only want to - // increment it when we actually hit an overloaded type. Getting this wrong - // leads to very subtle bugs! - OS << "Tys[" << ArgNo++ << "]"; - */ + Sig.push_back(IIT_ARG); + return Sig.push_back(NextArgNo++); } if (EVT(VT).isVector()) { @@ -504,6 +504,7 @@ static void EncodeFixedType(Record *R, SmallVectorImpl &Sig) { case 4: Sig.push_back(IIT_V4); break; case 8: Sig.push_back(IIT_V8); break; case 16: Sig.push_back(IIT_V16); break; + case 32: Sig.push_back(IIT_V32); break; } return EncodeFixedValueType(VVT.getVectorElementType(). @@ -512,10 +513,9 @@ static void EncodeFixedType(Record *R, SmallVectorImpl &Sig) { if (VT == MVT::iPTR) { Sig.push_back(IIT_PTR); - return EncodeFixedType(R->getValueAsDef("ElTy"), Sig); + return EncodeFixedType(R->getValueAsDef("ElTy"), NextArgNo, Sig); } - assert(VT != MVT::isVoid); EncodeFixedValueType(VT, Sig); } @@ -528,6 +528,8 @@ static void EncodeFixedType(Record *R, SmallVectorImpl &Sig) { static unsigned ComputeFixedEncoding(const CodeGenIntrinsic &Int) { if (Int.IS.RetVTs.size() >= 2) return ~0U; + unsigned NextArgNo = 0; + SmallVector TypeSig; if (Int.IS.RetVTs.empty()) TypeSig.push_back(IIT_Done); @@ -535,10 +537,10 @@ static unsigned ComputeFixedEncoding(const CodeGenIntrinsic &Int) { Int.IS.RetVTs[0] == MVT::isVoid) TypeSig.push_back(IIT_Done); else - EncodeFixedType(Int.IS.RetTypeDefs[0], TypeSig); + EncodeFixedType(Int.IS.RetTypeDefs[0], NextArgNo, TypeSig); for (unsigned i = 0, e = Int.IS.ParamTypeDefs.size(); i != e; ++i) - EncodeFixedType(Int.IS.ParamTypeDefs[i], TypeSig); + EncodeFixedType(Int.IS.ParamTypeDefs[i], NextArgNo, TypeSig); // Can only encode 8 nibbles into a 32-bit word. if (TypeSig.size() > 8) return ~0U; @@ -546,7 +548,7 @@ static unsigned ComputeFixedEncoding(const CodeGenIntrinsic &Int) { unsigned Result = 0; for (unsigned i = 0, e = TypeSig.size(); i != e; ++i) { // If we had an unencodable argument, bail out. - if (TypeSig[i] == ~0U) + if (TypeSig[i] > 15) return ~0U; Result = (Result << 4) | TypeSig[e-i-1]; } @@ -574,8 +576,15 @@ void IntrinsicEmitter::EmitGenerator(const std::vector &Ints, OS << " IIT_V16 = 11,\n"; OS << " IIT_MMX = 12,\n"; OS << " IIT_PTR = 13,\n"; - OS << " IIT_ARG = 14\n"; + OS << " IIT_ARG = 14,\n"; // 15 is unassigned so far. + OS << " IIT_F16 = 16,\n"; + OS << " IIT_F80 = 17,\n"; + OS << " IIT_F128 = 18,\n"; + OS << " IIT_PPC128 = 19,\n"; + OS << " IIT_METADATA = 20,\n"; + OS << " IIT_EMPTYSTRUCT = 21,\n"; + OS << " IIT_V32 = 22\n"; OS << "};\n\n";