[llvm-commits] [llvm] r156905 - in /llvm/trunk: lib/VMCore/Function.cpp utils/TableGen/IntrinsicEmitter.cpp
Francois Pichet
pichet2000 at gmail.com
Wed May 16 20:03:24 PDT 2012
On Wed, May 16, 2012 at 2:34 AM, Chris Lattner <sabre at nondot.org> wrote:
> Author: lattner
> Date: Wed May 16 01:34:44 2012
> New Revision: 156905
>
> URL: http://llvm.org/viewvc/llvm-project?rev=156905&view=rev
> Log:
> Significantly reduce the compiled size of Functions.cpp by turning a big blob of tblgen
> generated code (for Intrinsic::getType) into a table. This handles common cases right now,
> but I plan to extend it to handle all cases and merge in type verification logic as well
> in follow-on patches.
>
> Modified:
> llvm/trunk/lib/VMCore/Function.cpp
> llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
>
> Modified: llvm/trunk/lib/VMCore/Function.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=156905&r1=156904&r2=156905&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Function.cpp (original)
> +++ llvm/trunk/lib/VMCore/Function.cpp Wed May 16 01:34:44 2012
> @@ -29,7 +29,6 @@
> #include "llvm/ADT/StringExtras.h"
> using namespace llvm;
>
> -
> // Explicit instantiations of SymbolTableListTraits since some of the methods
> // are not in the public header file...
> template class llvm::SymbolTableListTraits<Argument, Function>;
> @@ -358,17 +357,57 @@
> return Result;
> }
>
> +#define GET_INTRINSTIC_GENERATOR_GLOBAL
> +#include "llvm/Intrinsics.gen"
> +#undef GET_INTRINSTIC_GENERATOR_GLOBAL
> +
> +static Type *DecodeFixedType(unsigned &TableVal, LLVMContext &Context) {
> + unsigned Nibble = TableVal & 0xF;
> + TableVal >>= 4;
> +
> + switch ((IIT_Info)Nibble) {
> + case IIT_Done: return Type::getVoidTy(Context);
> + case IIT_I1: return Type::getInt1Ty(Context);
> + case IIT_I8: return Type::getInt8Ty(Context);
> + case IIT_I16: return Type::getInt16Ty(Context);
> + case IIT_I32: return Type::getInt32Ty(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!");
> + }
> + llvm_unreachable("unhandled");
> +}
> +
> +
> FunctionType *Intrinsic::getType(LLVMContext &Context,
> - ID id, ArrayRef<Type*> Tys) {
> - Type *ResultTy = NULL;
> + ID id, ArrayRef<Type*> Tys) {
> + Type *ResultTy = 0;
> SmallVector<Type*, 8> ArgTys;
> - bool IsVarArg = false;
> +
> + // 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);
> +
> + while (TableVal)
> + ArgTys.push_back(DecodeFixedType(TableVal, Context));
> +
> + return FunctionType::get(ResultTy, ArgTys, false);
> + }
> +
>
> #define GET_INTRINSIC_GENERATOR
> #include "llvm/Intrinsics.gen"
> #undef GET_INTRINSIC_GENERATOR
>
> - return FunctionType::get(ResultTy, ArgTys, IsVarArg);
> + return FunctionType::get(ResultTy, ArgTys, false);
> }
>
> bool Intrinsic::isOverloaded(ID id) {
> @@ -440,4 +479,3 @@
> return false;
> }
>
> -// vim: sw=2 ai
>
> Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=156905&r1=156904&r2=156905&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Wed May 16 01:34:44 2012
> @@ -174,109 +174,6 @@
> OS << "#endif\n\n";
> }
>
> -static void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
> - if (EVT(VT).isInteger()) {
> - unsigned BitWidth = EVT(VT).getSizeInBits();
> - OS << "IntegerType::get(Context, " << BitWidth << ")";
> - } 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)";
> - } else if (VT == MVT::f32) {
> - OS << "Type::getFloatTy(Context)";
> - } else if (VT == MVT::f64) {
> - OS << "Type::getDoubleTy(Context)";
> - } else if (VT == MVT::f80) {
> - OS << "Type::getX86_FP80Ty(Context)";
> - } else if (VT == MVT::f128) {
> - OS << "Type::getFP128Ty(Context)";
> - } else if (VT == MVT::ppcf128) {
> - OS << "Type::getPPC_FP128Ty(Context)";
> - } else if (VT == MVT::isVoid) {
> - OS << "Type::getVoidTy(Context)";
> - } else if (VT == MVT::Metadata) {
> - OS << "Type::getMetadataTy(Context)";
> - } else if (VT == MVT::x86mmx) {
> - OS << "Type::getX86_MMXTy(Context)";
> - } else {
> - assert(false && "Unsupported ValueType!");
> - }
> -}
> -
> -static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
> - unsigned &ArgNo);
> -
> -static void EmitTypeGenerate(raw_ostream &OS,
> - const std::vector<Record*> &ArgTypes,
> - unsigned &ArgNo) {
> - if (ArgTypes.empty())
> - return EmitTypeForValueType(OS, MVT::isVoid);
> -
> - if (ArgTypes.size() == 1)
> - return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo);
> -
> - OS << "StructType::get(";
> -
> - for (std::vector<Record*>::const_iterator
> - I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) {
> - EmitTypeGenerate(OS, *I, ArgNo);
> - OS << ", ";
> - }
> -
> - OS << " NULL)";
> -}
> -
> -static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
> - unsigned &ArgNo) {
> - MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
> -
> - if (ArgType->isSubClassOf("LLVMMatchType")) {
> - unsigned Number = ArgType->getValueAsInt("Number");
> - assert(Number < ArgNo && "Invalid matching number!");
> - if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
> - OS << "VectorType::getExtendedElementVectorType"
> - << "(cast<VectorType>(Tys[" << Number << "]))";
> - else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
> - OS << "VectorType::getTruncatedElementVectorType"
> - << "(cast<VectorType>(Tys[" << Number << "]))";
> - else
> - OS << "Tys[" << Number << "]";
> - } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) {
> - // 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++ << "]";
> - } else if (EVT(VT).isVector()) {
> - EVT VVT = VT;
> - OS << "VectorType::get(";
> - EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy);
> - OS << ", " << VVT.getVectorNumElements() << ")";
> - } else if (VT == MVT::iPTR) {
> - OS << "PointerType::getUnqual(";
> - EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
> - OS << ")";
> - } else if (VT == MVT::iPTRAny) {
> - // Make sure the user has passed us an argument type to overload. If not,
> - // treat it as an ordinary (not overloaded) intrinsic.
> - OS << "(" << ArgNo << " < Tys.size()) ? Tys[" << ArgNo
> - << "] : PointerType::getUnqual(";
> - EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
> - OS << ")";
> - ++ArgNo;
> - } else if (VT == MVT::isVoid) {
> - if (ArgNo == 0)
> - OS << "Type::getVoidTy(Context)";
> - else
> - // MVT::isVoid is used to mean varargs here.
> - OS << "...";
> - } else {
> - EmitTypeForValueType(OS, VT);
> - }
> -}
> -
> /// RecordListComparator - Provide a deterministic comparator for lists of
> /// records.
> namespace {
> @@ -411,22 +308,322 @@
> OS << "#endif\n\n";
> }
>
> +static void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
> + if (EVT(VT).isInteger()) {
> + unsigned BitWidth = EVT(VT).getSizeInBits();
> + OS << "IntegerType::get(Context, " << BitWidth << ")";
> + } 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)";
> + } else if (VT == MVT::f32) {
> + OS << "Type::getFloatTy(Context)";
> + } else if (VT == MVT::f64) {
> + OS << "Type::getDoubleTy(Context)";
> + } else if (VT == MVT::f80) {
> + OS << "Type::getX86_FP80Ty(Context)";
> + } else if (VT == MVT::f128) {
> + OS << "Type::getFP128Ty(Context)";
> + } else if (VT == MVT::ppcf128) {
> + OS << "Type::getPPC_FP128Ty(Context)";
> + } else if (VT == MVT::isVoid) {
> + OS << "Type::getVoidTy(Context)";
> + } else if (VT == MVT::Metadata) {
> + OS << "Type::getMetadataTy(Context)";
> + } else if (VT == MVT::x86mmx) {
> + OS << "Type::getX86_MMXTy(Context)";
> + } else {
> + assert(false && "Unsupported ValueType!");
> + }
> +}
> +
> +static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
> + unsigned &ArgNo);
> +
> +static void EmitTypeGenerate(raw_ostream &OS,
> + const std::vector<Record*> &ArgTypes,
> + unsigned &ArgNo) {
> + if (ArgTypes.empty())
> + return EmitTypeForValueType(OS, MVT::isVoid);
> +
> + if (ArgTypes.size() == 1)
> + return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo);
> +
> + OS << "StructType::get(";
> +
> + for (std::vector<Record*>::const_iterator
> + I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) {
> + EmitTypeGenerate(OS, *I, ArgNo);
> + OS << ", ";
> + }
> +
> + OS << " NULL)";
> +}
> +
> +static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
> + unsigned &ArgNo) {
> + MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
> +
> + if (ArgType->isSubClassOf("LLVMMatchType")) {
> + unsigned Number = ArgType->getValueAsInt("Number");
> + assert(Number < ArgNo && "Invalid matching number!");
> + if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
> + OS << "VectorType::getExtendedElementVectorType"
> + << "(cast<VectorType>(Tys[" << Number << "]))";
> + else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
> + OS << "VectorType::getTruncatedElementVectorType"
> + << "(cast<VectorType>(Tys[" << Number << "]))";
> + else
> + OS << "Tys[" << Number << "]";
> + } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) {
> + // 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++ << "]";
> + } else if (EVT(VT).isVector()) {
> + EVT VVT = VT;
> + OS << "VectorType::get(";
> + EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy);
> + OS << ", " << VVT.getVectorNumElements() << ")";
> + } else if (VT == MVT::iPTR) {
> + OS << "PointerType::getUnqual(";
> + EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
> + OS << ")";
> + } else if (VT == MVT::iPTRAny) {
> + // Make sure the user has passed us an argument type to overload. If not,
> + // treat it as an ordinary (not overloaded) intrinsic.
> + OS << "(" << ArgNo << " < Tys.size()) ? Tys[" << ArgNo
> + << "] : PointerType::getUnqual(";
> + EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
> + OS << ")";
> + ++ArgNo;
> + } else if (VT == MVT::isVoid) {
> + assert(ArgNo == 0);
> + OS << "Type::getVoidTy(Context)";
> + } else {
> + EmitTypeForValueType(OS, VT);
> + }
> +}
> +
> +
> +// NOTE: This must be kept in synch with the version emitted to the .gen file!
> +enum IIT_Info {
> + IIT_Done = 0,
> + IIT_I1 = 1,
> + IIT_I8 = 2,
> + IIT_I16 = 3,
> + IIT_I32 = 4,
> + IIT_I64 = 5,
> + IIT_F32 = 6,
> + IIT_F64 = 7,
> + IIT_V2 = 8,
> + IIT_V4 = 9,
> + IIT_V8 = 10,
> + IIT_V16 = 11,
> + IIT_MMX = 12,
> + IIT_PTR = 13,
> + IIT_ARG = 14
> +};
> +
> +static void EncodeFixedValueType(MVT::SimpleValueType VT,
> + SmallVectorImpl<unsigned> &Sig) {
> + if (EVT(VT).isInteger()) {
> + unsigned BitWidth = EVT(VT).getSizeInBits();
> + switch (BitWidth) {
> + default: return Sig.push_back(~0U);
> + case 1: return Sig.push_back(IIT_I1);
> + case 8: return Sig.push_back(IIT_I8);
> + case 16: return Sig.push_back(IIT_I16);
> + case 32: return Sig.push_back(IIT_I32);
> + case 64: return Sig.push_back(IIT_I64);
> + }
> + }
> +
> +/* } 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);
> +}
> +
> +
> +static void EncodeFixedType(Record *R, SmallVectorImpl<unsigned> &Sig) {
> +
> + if (R->isSubClassOf("LLVMMatchType")) {
> + return Sig.push_back(~0U);
You are too powerful for MSVC:
1>c:\dev\llvm\llvm_trunk2\utils\tablegen\intrinsicemitter.cpp(472):
fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file
'f:\dd\vctools\compiler\utc\src\p2\main.c[0x695A85AC:0x00000018]',
line 183)
More information about the llvm-commits
mailing list