[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