From 61fc4cf7aa0b87ceab62082cee8ef5ce3f574ffc Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 11 Aug 2009 01:14:02 +0000 Subject: [PATCH] Add a new overloaded EVT::vAny type for use in TableGen to allow intrinsic arguments that are vectors of any size and element type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78631 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/ValueTypes.h | 21 ++++++++++++++++----- include/llvm/CodeGen/ValueTypes.td | 7 +++++-- include/llvm/Intrinsics.h | 2 +- include/llvm/Intrinsics.td | 1 + lib/VMCore/Verifier.cpp | 6 ++++++ utils/TableGen/CodeGenDAGPatterns.cpp | 21 +++++++++++++++++++-- utils/TableGen/CodeGenTarget.cpp | 5 +++-- utils/TableGen/IntrinsicEmitter.cpp | 6 +++--- 8 files changed, 54 insertions(+), 15 deletions(-) diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index a77ed508057..b32bda9c792 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -83,26 +83,31 @@ namespace llvm { MAX_ALLOWED_VALUETYPE = 64, // Metadata - This is MDNode or MDString. - Metadata = 251, + Metadata = 250, // iPTRAny - An int value the size of the pointer of the current // target to any address space. This must only be used internal to // tblgen. Other than for overloading, we treat iPTRAny the same as iPTR. - iPTRAny = 252, + iPTRAny = 251, + + // vAny - A vector with any length and element size. This is used + // for intrinsics that have overloadings based on vector types. + // This is only for tblgen's consumption! + vAny = 252, // fAny - Any floating-point or vector floating-point value. This is used // for intrinsics that have overloadings based on floating-point types. // This is only for tblgen's consumption! - fAny = 253, + fAny = 253, // iAny - An integer or vector integer value of any bit width. This is // used for intrinsics that have overloadings based on integer bit widths. // This is only for tblgen's consumption! - iAny = 254, + iAny = 254, // iPTR - An int value the size of the pointer of the current // target. This should only be used internal to tblgen! - iPTR = 255, + iPTR = 255, // LastSimpleValueType - The greatest valid SimpleValueType value. LastSimpleValueType = 255 @@ -284,6 +289,11 @@ namespace llvm { V==v4i64) : isExtended256BitVector(); } + /// isOverloaded - Return true if this is an overloaded type for TableGen. + bool isOverloaded() const { + return (V==iAny || V==fAny || V==vAny || V==iPTRAny); + } + /// isByteSized - Return true if the bit size is a multiple of 8. bool isByteSized() const { return (getSizeInBits() & 7) == 0; @@ -396,6 +406,7 @@ namespace llvm { case iPTRAny: case iAny: case fAny: + case vAny: assert(0 && "Value type is overloaded."); default: return getExtendedSizeInBits(); diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index 596da059c95..986555b976e 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -56,11 +56,14 @@ def v8f32 : ValueType<256, 31>; // 8 x f32 vector value def v2f64 : ValueType<128, 32>; // 2 x f64 vector value def v4f64 : ValueType<256, 33>; // 4 x f64 vector value -def MetadataVT: ValueType<0, 251>; // Metadata +def MetadataVT: ValueType<0, 250>; // Metadata // Pseudo valuetype mapped to the current pointer size to any address space. // Should only be used in TableGen. -def iPTRAny : ValueType<0, 252>; +def iPTRAny : ValueType<0, 251>; + +// Pseudo valuetype to represent "vector of any size" +def vAny : ValueType<0 , 252>; // Pseudo valuetype to represent "float of any format" def fAny : ValueType<0 , 253>; diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h index 0b99204bb13..5750a27d732 100644 --- a/include/llvm/Intrinsics.h +++ b/include/llvm/Intrinsics.h @@ -63,7 +63,7 @@ namespace Intrinsic { /// declaration for an intrinsic, and return it. /// /// The Tys and numTys parameters are for intrinsics with overloaded types - /// (i.e., those using iAny or fAny). For a declaration for an overloaded + /// (e.g., those using iAny or fAny). For a declaration for an overloaded /// intrinsic, Tys should point to an array of numTys pointers to Type, /// and must provide exactly one type for each overloaded type in the /// intrinsic. diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 25f6604afab..83d28fb8fea 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -94,6 +94,7 @@ class LLVMTruncatedElementVectorType : LLVMMatchType; def llvm_void_ty : LLVMType; def llvm_anyint_ty : LLVMType; def llvm_anyfloat_ty : LLVMType; +def llvm_anyvector_ty : LLVMType; def llvm_i1_ty : LLVMType; def llvm_i8_ty : LLVMType; def llvm_i16_ty : LLVMType; diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index a60169094fb..ca099525cd7 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1597,6 +1597,12 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, Suffix += "v" + utostr(NumElts); Suffix += EVT::getEVT(EltTy).getEVTString(); + } else if (VT == EVT::vAny) { + if (!VTy) { + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a vector type.", F); + return false; + } + Suffix += ".v" + utostr(NumElts) + EVT::getEVT(EltTy).getEVTString(); } else if (VT == EVT::iPTR) { if (!isa(Ty)) { CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a " diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 05ede6cec6d..af72b93fd30 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -87,9 +87,16 @@ bool isExtIntegerInVTs(const std::vector &EVTs) { /// isExtFloatingPointInVTs - Return true if the specified extended value type /// vector contains isFP or a FP value type. bool isExtFloatingPointInVTs(const std::vector &EVTs) { - assert(!EVTs.empty() && "Cannot check for integer in empty ExtVT list!"); + assert(!EVTs.empty() && "Cannot check for FP in empty ExtVT list!"); return EVTs[0] == isFP || !(FilterEVTs(EVTs, isFloatingPoint).empty()); } + +/// isExtVectorInVTs - Return true if the specified extended value type +/// vector contains a vector value type. +bool isExtVectorInVTs(const std::vector &EVTs) { + assert(!EVTs.empty() && "Cannot check for vector in empty ExtVT list!"); + return !(FilterEVTs(EVTs, isVector).empty()); +} } // end namespace EEVT. } // end namespace llvm. @@ -495,6 +502,14 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, setTypes(FVTs); return true; } + if (ExtVTs[0] == EVT::vAny && EEVT::isExtVectorInVTs(getExtTypes())) { + assert(hasTypeSet() && "should be handled above!"); + std::vector FVTs = FilterEVTs(getExtTypes(), isVector); + if (getExtTypes() == FVTs) + return false; + setTypes(FVTs); + return true; + } // If we know this is an int or fp type, and we are told it is a specific one, // take the advice. @@ -504,7 +519,9 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, if (((getExtTypeNum(0) == EEVT::isInt || getExtTypeNum(0) == EVT::iAny) && EEVT::isExtIntegerInVTs(ExtVTs)) || ((getExtTypeNum(0) == EEVT::isFP || getExtTypeNum(0) == EVT::fAny) && - EEVT::isExtFloatingPointInVTs(ExtVTs))) { + EEVT::isExtFloatingPointInVTs(ExtVTs)) || + (getExtTypeNum(0) == EVT::vAny && + EEVT::isExtVectorInVTs(ExtVTs))) { setTypes(ExtVTs); return true; } diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 15aa2de1d58..28ee33c1a35 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -56,6 +56,7 @@ std::string llvm::getEnumName(EVT::SimpleValueType T) { case EVT::i128: return "EVT::i128"; case EVT::iAny: return "EVT::iAny"; case EVT::fAny: return "EVT::fAny"; + case EVT::vAny: return "EVT::vAny"; case EVT::f32: return "EVT::f32"; case EVT::f64: return "EVT::f64"; case EVT::f80: return "EVT::f80"; @@ -496,7 +497,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { } else { VT = getValueType(TyEl->getValueAsDef("VT")); } - if (VT == EVT::iAny || VT == EVT::fAny || VT == EVT::iPTRAny) { + if (EVT(VT).isOverloaded()) { OverloadedVTs.push_back(VT); isOverloaded |= true; } @@ -526,7 +527,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { VT == EVT::iAny) && "Expected iAny type"); } else VT = getValueType(TyEl->getValueAsDef("VT")); - if (VT == EVT::iAny || VT == EVT::fAny || VT == EVT::iPTRAny) { + if (EVT(VT).isOverloaded()) { OverloadedVTs.push_back(VT); isOverloaded |= true; } diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 94d381d466a..79874b1629b 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -203,7 +203,7 @@ static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, << "(dyn_cast(Tys[" << Number << "]))"; else OS << "Tys[" << Number << "]"; - } else if (VT == EVT::iAny || VT == EVT::fAny) { + } else if (VT == EVT::iAny || VT == EVT::fAny || VT == EVT::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 @@ -329,7 +329,7 @@ void IntrinsicEmitter::EmitVerifier(const std::vector &Ints, EVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); OS << getEnumName(VT); - if (VT == EVT::iAny || VT == EVT::fAny || VT == EVT::iPTRAny) + if (EVT(VT).isOverloaded()) OverloadedTypeIndices.push_back(j); if (VT == EVT::isVoid && j != 0 && j != je - 1) @@ -357,7 +357,7 @@ void IntrinsicEmitter::EmitVerifier(const std::vector &Ints, EVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); OS << getEnumName(VT); - if (VT == EVT::iAny || VT == EVT::fAny || VT == EVT::iPTRAny) + if (EVT(VT).isOverloaded()) OverloadedTypeIndices.push_back(j + RetTys.size()); if (VT == EVT::isVoid && j != 0 && j != je - 1)