[llvm] [LLVM][Intrinsics] Refactor IITDescriptors. (PR #190011)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 10:53:14 PDT 2026
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/190011
None
>From b5bd2cb8c4657956f9ac42edccbda1b054a0e30e Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 1 Apr 2026 09:57:47 -0700
Subject: [PATCH] [LLVM][Intrinsics] Refactor IITDescriptors.
---
llvm/include/llvm/IR/Intrinsics.h | 86 +++---
llvm/include/llvm/IR/Intrinsics.td | 44 +--
llvm/lib/IR/Intrinsics.cpp | 253 +++++++++---------
llvm/lib/Transforms/Utils/CloneFunction.cpp | 6 +-
.../utils/TableGen/Basic/IntrinsicEmitter.cpp | 18 +-
5 files changed, 208 insertions(+), 199 deletions(-)
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 73311c96b1326..8485be4ff1175 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -67,17 +67,18 @@ namespace Intrinsic {
/// overloads are required, it is safe to use this version, but better to use
/// the StringRef version. If one of the types is based on an unnamed type, a
/// function type will be computed. Providing FT will avoid this computation.
- LLVM_ABI std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M,
+ LLVM_ABI std::string getName(ID Id, ArrayRef<Type *> OverloadTys, Module *M,
FunctionType *FT = nullptr);
/// Return the LLVM name for an intrinsic. This is a special version only to
/// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
/// based on named types.
- LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);
+ LLVM_ABI std::string getNameNoUnnamedTypes(ID Id,
+ ArrayRef<Type *> OverloadTys);
/// Return the function type for an intrinsic.
LLVM_ABI FunctionType *getType(LLVMContext &Context, ID id,
- ArrayRef<Type *> Tys = {});
+ ArrayRef<Type *> OverloadTys = {});
/// Returns true if the intrinsic can be overloaded.
LLVM_ABI bool isOverloaded(ID id);
@@ -153,6 +154,7 @@ namespace Intrinsic {
/// intrinsic. This is returned by getIntrinsicInfoTableEntries.
struct IITDescriptor {
enum IITDescriptorKind {
+ // Concrete types. Additional qualifiers listed in comments.
Void,
VarArg,
MMX,
@@ -163,70 +165,72 @@ namespace Intrinsic {
Float,
Double,
Quad,
- Integer,
- Vector,
- Pointer,
- Struct,
- Argument,
- ExtendArgument,
- TruncArgument,
- OneNthEltsVecArgument,
- SameVecWidthArgument,
- VecOfAnyPtrsToElt,
- VecElementArgument,
- Subdivide2Argument,
- Subdivide4Argument,
- VecOfBitcastsToInt,
+ Integer, // Width of the integer in IntegerWidth.
+ Vector, // Width of the vector in VectorWidth.
+ Pointer, // Address space of the pointer in PointerAddressSpace.
+ Struct, // Number of elements in StructNumElements.
AMX,
PPCQuad,
AArch64Svcount,
+
+ // Overloaded type.
+ Overloaded, // AnyKind and overload index in OverloadInfo.
+
+ // Fully dependent types. Overload index in OverloadInfo.
+ Extend,
+ Trunc,
+ OneNthEltsVec,
+ SameVecWidth,
+ VecElement,
+ Subdivide2,
+ Subdivide4,
+ VecOfBitcastsToInt,
+
+ // Partially dependent types. Overload index (self and of the overload
+ // type it depends on) in OverloadInfo.
+ VecOfAnyPtrsToElt,
+
} Kind;
union {
unsigned IntegerWidth;
unsigned PointerAddressSpace;
unsigned StructNumElements;
- unsigned ArgumentInfo;
+ unsigned OverloadInfo;
ElementCount VectorWidth;
};
// AK_% : Defined in Intrinsics.td
- enum ArgKind {
-#define GET_INTRINSIC_ARGKIND
+ enum AnyKind {
+#define GET_INTRINSIC_ANYKIND
#include "llvm/IR/IntrinsicEnums.inc"
};
- unsigned getArgumentNumber() const {
- assert(Kind == Argument || Kind == ExtendArgument ||
- Kind == TruncArgument || Kind == SameVecWidthArgument ||
- Kind == VecElementArgument || Kind == Subdivide2Argument ||
- Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
+ unsigned getOverloadIndex() const {
+ assert(Kind == Overloaded || Kind == Extend || Kind == Trunc ||
+ Kind == SameVecWidth || Kind == VecElement || Kind == Subdivide2 ||
+ Kind == Subdivide4 || Kind == VecOfBitcastsToInt ||
+ Kind == VecOfAnyPtrsToElt || Kind == OneNthEltsVec);
// Overload index is packed into lower 5 bits.
- return ArgumentInfo & 0x1f;
- }
- ArgKind getArgumentKind() const {
- // Argument kind is packed into upper 3 bits.
- assert(Kind == Argument);
- return (ArgKind)((ArgumentInfo >> 5) & 0x7);
+ return OverloadInfo & 0x1f;
}
- // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
- // and a reference argument (for matching vector width and element types)
- unsigned getOverloadArgNumber() const {
- assert(Kind == VecOfAnyPtrsToElt);
- return ArgumentInfo >> 16;
+ AnyKind getOverloadKind() const {
+ // Overload kind is packed into upper 3 bits.
+ assert(Kind == Overloaded);
+ return (AnyKind)((OverloadInfo >> 5) & 0x7);
}
// OneNthEltsVecArguments uses both a divisor N and a reference argument for
// the full-width vector to match
unsigned getVectorDivisor() const {
- assert(Kind == OneNthEltsVecArgument);
- return ArgumentInfo >> 16;
+ assert(Kind == OneNthEltsVec);
+ return OverloadInfo >> 16;
}
- unsigned getRefArgNumber() const {
- assert(Kind == VecOfAnyPtrsToElt || Kind == OneNthEltsVecArgument);
- return ArgumentInfo & 0xFFFF;
+ unsigned getRefOverloadIndex() const {
+ assert(Kind == VecOfAnyPtrsToElt);
+ return OverloadInfo & 0xFFFF;
}
static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index abab8c3b53574..8103fe2a5f82b 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -232,8 +232,8 @@ def IntrNoCreateUndefOrPoison : IntrinsicProperty;
// IIT constants and utils
//===----------------------------------------------------------------------===//
-// llvm::Intrinsic::IITDescriptor::ArgKind::AK_%
-def ArgKind {
+// llvm::Intrinsic::IITDescriptor::AnyKind::AK_%
+def AnyKind {
int Any = 0;
int AnyInteger = 1;
int AnyFloat = 2;
@@ -246,13 +246,13 @@ def ArgKind {
// Placeholder to encode the overload index of the current type. We encode bit
// 8 = 1 to indicate that this entry needs to be patched up with the overload
// index (to prevent conflict with any valid not-to-be-patched IIT enccoding
-// byte, whose value will be <= 255). The ArgKind itself is in the lower bits.
+// byte, whose value will be <= 255). The AnyKind itself is in the lower bits.
// Note that this is just a transient representation till its gets processed
// by `DoPatchOverloadIndex` below, so this is *not* the encoding of the
// final type signature.
-class OverloadIndexPlaceholder <int ArgKindVal> {
+class OverloadIndexPlaceholder <int AnyKindVal> {
int ID = 0x100;
- int ret = !or(ID, ArgKindVal);
+ int ret = !or(ID, AnyKindVal);
}
// This class defines how the overload index and the arg kind are actually
@@ -261,10 +261,10 @@ class OverloadIndexPlaceholder <int ArgKindVal> {
// us to use the same packing for llvm_any* types, which use a argument kind
// and for partially dependent types like `LLVMVectorOfAnyPointersToElt` which
// do not use the argument kind and expect the overload index in the lower bits.
-class PackOverloadIndex<int OverloadIndex, int ArgKindVal> {
+class PackOverloadIndex<int OverloadIndex, int AnyKindVal> {
assert !lt(OverloadIndex, 32), "Cannot support more than 32 overload types";
- assert !lt(ArgKindVal, 8), "Cannot support more than 8 argument kinds";
- int ret = !or(!shl(ArgKindVal, 5), OverloadIndex);
+ assert !lt(AnyKindVal, 8), "Cannot support more than 8 argument kinds";
+ int ret = !or(!shl(AnyKindVal, 5), OverloadIndex);
}
// This class handles the actual patching of the overload index into a component
@@ -272,10 +272,10 @@ class PackOverloadIndex<int OverloadIndex, int ArgKindVal> {
// value generated by OverloadIndexPlaceholder and patching is needed, else the
// value is left unchanged.
class PatchOverloadIndex<int Sig, int OverloadIndex> {
- int ArgKindVal = !and(Sig, 0x7);
+ int AnyKindVal = !and(Sig, 0x7);
int ret = !cond(
// If the value is > 255, it indicates that patching is needed.
- !gt(Sig, 255) : PackOverloadIndex<OverloadIndex, ArgKindVal>.ret,
+ !gt(Sig, 255) : PackOverloadIndex<OverloadIndex, AnyKindVal>.ret,
true: Sig);
}
@@ -317,8 +317,8 @@ def IIT_V4 : IIT_Vec<4, 10>;
def IIT_V8 : IIT_Vec<8, 11>;
def IIT_V16 : IIT_Vec<16, 12>;
def IIT_V32 : IIT_Vec<32, 13>;
-def IIT_PTR : IIT_Base< 14>;
-def IIT_ARG : IIT_Base< 15>;
+def IIT_PTR : IIT_Base< 14>; // pointer with address space 0.
+def IIT_ANY : IIT_Base< 15>;
def IIT_V64 : IIT_Vec<64, 16>;
def IIT_MMX : IIT_VT<x86mmx, 17>;
@@ -328,7 +328,7 @@ def IIT_EMPTYSTRUCT : IIT_VT<OtherVT, 20>;
def IIT_STRUCT : IIT_Base<21>;
def IIT_EXTEND_ARG : IIT_Base<22>;
def IIT_TRUNC_ARG : IIT_Base<23>;
-def IIT_ANYPTR : IIT_Base<24>;
+def IIT_PTR_AS : IIT_Base<24>; // Pointer with address space.
def IIT_V1 : IIT_Vec<1, 25>;
def IIT_VARARG : IIT_VT<isVoid, 26>;
def IIT_ONE_NTH_ELTS_VEC_ARG : IIT_Base<27>;
@@ -398,14 +398,14 @@ class LLVMType<ValueType vt> {
class LLVMAnyType<ValueType vt> : LLVMType<vt> {
int ArgCode = !cond(
- !eq(vt, Any) : ArgKind.Any,
- !eq(vt, iAny) : ArgKind.AnyInteger,
- !eq(vt, fAny) : ArgKind.AnyFloat,
- !eq(vt, vAny) : ArgKind.AnyVector,
- !eq(vt, pAny) : ArgKind.AnyPointer,
+ !eq(vt, Any) : AnyKind.Any,
+ !eq(vt, iAny) : AnyKind.AnyInteger,
+ !eq(vt, fAny) : AnyKind.AnyFloat,
+ !eq(vt, vAny) : AnyKind.AnyVector,
+ !eq(vt, pAny) : AnyKind.AnyPointer,
);
let Sig = [
- IIT_ARG.Number,
+ IIT_ANY.Number,
OverloadIndexPlaceholder <ArgCode>.ret,
];
@@ -419,7 +419,7 @@ class LLVMQualPointerType<int addrspace>
let Sig =
!if(addrspace, [
- IIT_ANYPTR.Number,
+ IIT_PTR_AS.Number,
addrspace,
], [
IIT_PTR.Number,
@@ -449,7 +449,7 @@ class LLVMFullyDependentType<int oidx, IIT_Base IIT_Info>
// followed by the overload index of the overload type it depends on.
let Sig = [
IIT_Info.Number,
- PackOverloadIndex<OverloadIndex, ArgKind.MatchType>.ret
+ PackOverloadIndex<OverloadIndex, AnyKind.MatchType>.ret
];
}
@@ -490,7 +490,7 @@ class LLVMPartiallyDependentType<int oidx, IIT_Base IIT_Info>
//
// LLVMMatchType<0> therefore will match the return type, and
// LLVMMatchType<2> will match the 3rd argument.
-class LLVMMatchType<int oidx> : LLVMFullyDependentType<oidx, IIT_ARG>;
+class LLVMMatchType<int oidx> : LLVMFullyDependentType<oidx, IIT_ANY>;
// Match the type of another intrinsic parameter that is expected to be based on
// an integral type (i.e. either iN or <N x iM>), but change the scalar size to
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index dae64cb757a33..0fe829c64ae7e 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -154,41 +154,43 @@ static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) {
return Result;
}
-static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys,
- Module *M, FunctionType *FT,
+static std::string getIntrinsicNameImpl(Intrinsic::ID Id,
+ ArrayRef<Type *> OverloadTys, Module *M,
+ FunctionType *FT,
bool EarlyModuleCheck) {
assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");
- assert((Tys.empty() || Intrinsic::isOverloaded(Id)) &&
+ assert((OverloadTys.empty() || Intrinsic::isOverloaded(Id)) &&
"This version of getName is for overloaded intrinsics only");
(void)EarlyModuleCheck;
assert((!EarlyModuleCheck || M ||
- !any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) &&
+ !any_of(OverloadTys, llvm::IsaPred<PointerType>)) &&
"Intrinsic overloading on pointer types need to provide a Module");
bool HasUnnamedType = false;
std::string Result(Intrinsic::getBaseName(Id));
- for (Type *Ty : Tys)
+ for (Type *Ty : OverloadTys)
Result += "." + getMangledTypeStr(Ty, HasUnnamedType);
if (HasUnnamedType) {
assert(M && "unnamed types need a module");
if (!FT)
- FT = Intrinsic::getType(M->getContext(), Id, Tys);
+ FT = Intrinsic::getType(M->getContext(), Id, OverloadTys);
else
- assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) &&
+ assert(FT == Intrinsic::getType(M->getContext(), Id, OverloadTys) &&
"Provided FunctionType must match arguments");
return M->getUniqueIntrinsicName(Result, Id, FT);
}
return Result;
}
-std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M,
+std::string Intrinsic::getName(ID Id, ArrayRef<Type *> OverloadTys, Module *M,
FunctionType *FT) {
assert(M && "We need to have a Module");
- return getIntrinsicNameImpl(Id, Tys, M, FT, true);
+ return getIntrinsicNameImpl(Id, OverloadTys, M, FT, true);
}
-std::string Intrinsic::getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys) {
- return getIntrinsicNameImpl(Id, Tys, nullptr, nullptr, false);
+std::string Intrinsic::getNameNoUnnamedTypes(ID Id,
+ ArrayRef<Type *> OverloadTys) {
+ return getIntrinsicNameImpl(Id, OverloadTys, nullptr, nullptr, false);
}
/// IIT_Info - These are enumerators that describe the entries returned by the
@@ -206,7 +208,7 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
SmallVectorImpl<Intrinsic::IITDescriptor> &OutputTable) {
using namespace Intrinsic;
- bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC);
+ bool IsScalableVector = LastInfo == IIT_SCALABLE_VEC;
IIT_Info Info = IIT_Info(Infos[NextElt++]);
@@ -347,45 +349,50 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_PTR:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
return;
- case IIT_ANYPTR: // [ANYPTR addrspace]
+ case IIT_PTR_AS: // pointer with address space.
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));
return;
- case IIT_ARG: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
- OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
+ case IIT_ANY: {
+ unsigned OverloadInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(
+ IITDescriptor::get(IITDescriptor::Overloaded, OverloadInfo));
return;
}
case IIT_EXTEND_ARG: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::ExtendArgument, ArgInfo));
+ IITDescriptor::get(IITDescriptor::Extend, OverloadIndex));
return;
}
case IIT_TRUNC_ARG: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::TruncArgument, ArgInfo));
+ IITDescriptor::get(IITDescriptor::Trunc, OverloadIndex));
return;
}
case IIT_ONE_NTH_ELTS_VEC_ARG: {
- unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned short OverloadIndex =
+ (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
unsigned short N = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
- OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::OneNthEltsVecArgument, N, ArgNo));
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::OneNthEltsVec,
+ /*Hi=*/N, /*Lo=*/OverloadIndex));
return;
}
case IIT_SAME_VEC_WIDTH_ARG: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::SameVecWidthArgument, ArgInfo));
+ IITDescriptor::get(IITDescriptor::SameVecWidth, OverloadIndex));
return;
}
case IIT_VEC_OF_ANYPTRS_TO_ELT: {
- unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
- unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
- OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo));
+ unsigned short OverloadIndex =
+ (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned short RefOverloadIndex =
+ (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt,
+ /*Hi=*/RefOverloadIndex,
+ /*Lo=*/OverloadIndex));
return;
}
case IIT_EMPTYSTRUCT:
@@ -402,21 +409,21 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
return;
}
case IIT_SUBDIVIDE2_ARG: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::Subdivide2Argument, ArgInfo));
+ IITDescriptor::get(IITDescriptor::Subdivide2, OverloadIndex));
return;
}
case IIT_SUBDIVIDE4_ARG: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::Subdivide4Argument, ArgInfo));
+ IITDescriptor::get(IITDescriptor::Subdivide4, OverloadIndex));
return;
}
case IIT_VEC_ELEMENT: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::VecElementArgument, ArgInfo));
+ IITDescriptor::get(IITDescriptor::VecElement, OverloadIndex));
return;
}
case IIT_SCALABLE_VEC: {
@@ -424,9 +431,9 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
return;
}
case IIT_VEC_OF_BITCASTS_TO_INT: {
- unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(
- IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, ArgInfo));
+ IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, OverloadIndex));
return;
}
}
@@ -482,7 +489,8 @@ void Intrinsic::getIntrinsicInfoTableEntries(
}
static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
- ArrayRef<Type *> Tys, LLVMContext &Context) {
+ ArrayRef<Type *> OverloadTys,
+ LLVMContext &Context) {
using namespace Intrinsic;
IITDescriptor D = Infos.front();
@@ -519,26 +527,30 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::Integer:
return IntegerType::get(Context, D.IntegerWidth);
case IITDescriptor::Vector:
- return VectorType::get(DecodeFixedType(Infos, Tys, Context), D.VectorWidth);
+ return VectorType::get(DecodeFixedType(Infos, OverloadTys, Context),
+ D.VectorWidth);
case IITDescriptor::Pointer:
return PointerType::get(Context, D.PointerAddressSpace);
case IITDescriptor::Struct: {
SmallVector<Type *, 8> Elts;
for (unsigned i = 0, e = D.StructNumElements; i != e; ++i)
- Elts.push_back(DecodeFixedType(Infos, Tys, Context));
+ Elts.push_back(DecodeFixedType(Infos, OverloadTys, Context));
return StructType::get(Context, Elts);
}
- case IITDescriptor::Argument:
- return Tys[D.getArgumentNumber()];
- case IITDescriptor::ExtendArgument: {
- Type *Ty = Tys[D.getArgumentNumber()];
+ // For any overload kind or partially dependent type, substitute it with the
+ // corresponding concrete type from OverloadTys.
+ case IITDescriptor::Overloaded:
+ case IITDescriptor::VecOfAnyPtrsToElt:
+ return OverloadTys[D.getOverloadIndex()];
+ case IITDescriptor::Extend: {
+ Type *Ty = OverloadTys[D.getOverloadIndex()];
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
return VectorType::getExtendedElementVectorType(VTy);
return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth());
}
- case IITDescriptor::TruncArgument: {
- Type *Ty = Tys[D.getArgumentNumber()];
+ case IITDescriptor::Trunc: {
+ Type *Ty = OverloadTys[D.getOverloadIndex()];
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
return VectorType::getTruncatedElementVectorType(VTy);
@@ -546,63 +558,61 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
assert(ITy->getBitWidth() % 2 == 0);
return IntegerType::get(Context, ITy->getBitWidth() / 2);
}
- case IITDescriptor::Subdivide2Argument:
- case IITDescriptor::Subdivide4Argument: {
- Type *Ty = Tys[D.getArgumentNumber()];
+ case IITDescriptor::Subdivide2:
+ case IITDescriptor::Subdivide4: {
+ Type *Ty = OverloadTys[D.getOverloadIndex()];
VectorType *VTy = dyn_cast<VectorType>(Ty);
- assert(VTy && "Expected an argument of Vector Type");
- int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+ assert(VTy && "Expected overload type to be a Vector Type");
+ int SubDivs = D.Kind == IITDescriptor::Subdivide2 ? 1 : 2;
return VectorType::getSubdividedVectorType(VTy, SubDivs);
}
- case IITDescriptor::OneNthEltsVecArgument:
+ case IITDescriptor::OneNthEltsVec:
return VectorType::getOneNthElementsVectorType(
- cast<VectorType>(Tys[D.getRefArgNumber()]), D.getVectorDivisor());
- case IITDescriptor::SameVecWidthArgument: {
- Type *EltTy = DecodeFixedType(Infos, Tys, Context);
- Type *Ty = Tys[D.getArgumentNumber()];
+ cast<VectorType>(OverloadTys[D.getOverloadIndex()]),
+ D.getVectorDivisor());
+ case IITDescriptor::SameVecWidth: {
+ Type *EltTy = DecodeFixedType(Infos, OverloadTys, Context);
+ Type *Ty = OverloadTys[D.getOverloadIndex()];
if (auto *VTy = dyn_cast<VectorType>(Ty))
return VectorType::get(EltTy, VTy->getElementCount());
return EltTy;
}
- case IITDescriptor::VecElementArgument: {
- Type *Ty = Tys[D.getArgumentNumber()];
+ case IITDescriptor::VecElement: {
+ Type *Ty = OverloadTys[D.getOverloadIndex()];
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
return VTy->getElementType();
- llvm_unreachable("Expected an argument of Vector Type");
+ llvm_unreachable("Expected overload type to be a Vector Type");
}
case IITDescriptor::VecOfBitcastsToInt: {
- Type *Ty = Tys[D.getArgumentNumber()];
+ Type *Ty = OverloadTys[D.getOverloadIndex()];
VectorType *VTy = dyn_cast<VectorType>(Ty);
- assert(VTy && "Expected an argument of Vector Type");
+ assert(VTy && "Expected overload type to be a Vector Type");
return VectorType::getInteger(VTy);
}
- case IITDescriptor::VecOfAnyPtrsToElt:
- // Return the overloaded type (which determines the pointers address space)
- return Tys[D.getOverloadArgNumber()];
}
llvm_unreachable("unhandled");
}
FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
- ArrayRef<Type *> Tys) {
+ ArrayRef<Type *> OverloadTys) {
SmallVector<IITDescriptor, 8> Table;
getIntrinsicInfoTableEntries(id, Table);
ArrayRef<IITDescriptor> TableRef = Table;
- Type *ResultTy = DecodeFixedType(TableRef, Tys, Context);
+ Type *ResultTy = DecodeFixedType(TableRef, OverloadTys, Context);
SmallVector<Type *, 8> ArgTys;
while (!TableRef.empty())
- ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
+ ArgTys.push_back(DecodeFixedType(TableRef, OverloadTys, Context));
- // DecodeFixedType returns Void for IITDescriptor::Void and
- // IITDescriptor::VarArg If we see void type as the type of the last argument,
- // it is vararg intrinsic
+ // VarArg intrinsics encode a void type as the last argument type. Detect that
+ // and then drop the void argument.
+ bool IsVarArg = false;
if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) {
ArgTys.pop_back();
- return FunctionType::get(ResultTy, ArgTys, true);
+ IsVarArg = true;
}
- return FunctionType::get(ResultTy, ArgTys, false);
+ return FunctionType::get(ResultTy, ArgTys, IsVarArg);
}
bool Intrinsic::isOverloaded(ID id) {
@@ -732,15 +742,14 @@ Intrinsic::ID Intrinsic::lookupIntrinsicID(StringRef Name) {
#define GET_INTRINSIC_ATTRIBUTES
#include "llvm/IR/IntrinsicImpl.inc"
-static Function *getOrInsertIntrinsicDeclarationImpl(Module *M,
- Intrinsic::ID id,
- ArrayRef<Type *> Tys,
- FunctionType *FT) {
- Function *F = cast<Function>(
- M->getOrInsertFunction(Tys.empty() ? Intrinsic::getName(id)
- : Intrinsic::getName(id, Tys, M, FT),
- FT)
- .getCallee());
+static Function *
+getOrInsertIntrinsicDeclarationImpl(Module *M, Intrinsic::ID id,
+ ArrayRef<Type *> OverloadTys,
+ FunctionType *FT) {
+ std::string Name = OverloadTys.empty()
+ ? Intrinsic::getName(id).str()
+ : Intrinsic::getName(id, OverloadTys, M, FT);
+ Function *F = cast<Function>(M->getOrInsertFunction(Name, FT).getCallee());
if (F->getFunctionType() == FT)
return F;
@@ -750,19 +759,15 @@ static Function *getOrInsertIntrinsicDeclarationImpl(Module *M,
// invalid declaration and insert a new one with the correct signature. The
// invalid declaration will get upgraded later.
F->setName(F->getName() + ".invalid");
- return cast<Function>(
- M->getOrInsertFunction(Tys.empty() ? Intrinsic::getName(id)
- : Intrinsic::getName(id, Tys, M, FT),
- FT)
- .getCallee());
+ return cast<Function>(M->getOrInsertFunction(Name, FT).getCallee());
}
Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
- ArrayRef<Type *> Tys) {
+ ArrayRef<Type *> OverloadTys) {
// There can never be multiple globals with the same name of different types,
// because intrinsics must be a specific type.
- FunctionType *FT = getType(M->getContext(), id, Tys);
- return getOrInsertIntrinsicDeclarationImpl(M, id, Tys, FT);
+ FunctionType *FT = getType(M->getContext(), id, OverloadTys);
+ return getOrInsertIntrinsicDeclarationImpl(M, id, OverloadTys, FT);
}
Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id, Type *RetTy,
@@ -799,9 +804,9 @@ Function *Intrinsic::getDeclarationIfExists(const Module *M, ID id) {
}
Function *Intrinsic::getDeclarationIfExists(Module *M, ID id,
- ArrayRef<Type *> Tys,
+ ArrayRef<Type *> OverloadTys,
FunctionType *FT) {
- return M->getFunction(getName(id, Tys, M, FT));
+ return M->getFunction(getName(id, OverloadTys, M, FT));
}
// This defines the "Intrinsic::getIntrinsicForClangBuiltin()" method.
@@ -917,21 +922,21 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return false;
}
- case IITDescriptor::Argument:
+ case IITDescriptor::Overloaded:
// If this is the second occurrence of an argument,
// verify that the later instance matches the previous instance.
- if (D.getArgumentNumber() < ArgTys.size())
- return Ty != ArgTys[D.getArgumentNumber()];
+ if (D.getOverloadIndex() < ArgTys.size())
+ return Ty != ArgTys[D.getOverloadIndex()];
- if (D.getArgumentNumber() > ArgTys.size() ||
- D.getArgumentKind() == IITDescriptor::AK_MatchType)
+ if (D.getOverloadIndex() > ArgTys.size() ||
+ D.getOverloadKind() == IITDescriptor::AK_MatchType)
return IsDeferredCheck || DeferCheck(Ty);
- assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck &&
+ assert(D.getOverloadIndex() == ArgTys.size() && !IsDeferredCheck &&
"Table consistency error");
ArgTys.push_back(Ty);
- switch (D.getArgumentKind()) {
+ switch (D.getOverloadKind()) {
case IITDescriptor::AK_Any:
return false; // Success
case IITDescriptor::AK_AnyInteger:
@@ -947,12 +952,12 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
}
llvm_unreachable("all argument kinds not covered");
- case IITDescriptor::ExtendArgument: {
+ case IITDescriptor::Extend: {
// If this is a forward reference, defer the check for later.
- if (D.getArgumentNumber() >= ArgTys.size())
+ if (D.getOverloadIndex() >= ArgTys.size())
return IsDeferredCheck || DeferCheck(Ty);
- Type *NewTy = ArgTys[D.getArgumentNumber()];
+ Type *NewTy = ArgTys[D.getOverloadIndex()];
if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
NewTy = VectorType::getExtendedElementVectorType(VTy);
else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
@@ -962,12 +967,12 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return Ty != NewTy;
}
- case IITDescriptor::TruncArgument: {
+ case IITDescriptor::Trunc: {
// If this is a forward reference, defer the check for later.
- if (D.getArgumentNumber() >= ArgTys.size())
+ if (D.getOverloadIndex() >= ArgTys.size())
return IsDeferredCheck || DeferCheck(Ty);
- Type *NewTy = ArgTys[D.getArgumentNumber()];
+ Type *NewTy = ArgTys[D.getOverloadIndex()];
if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
NewTy = VectorType::getTruncatedElementVectorType(VTy);
else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
@@ -977,11 +982,11 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return Ty != NewTy;
}
- case IITDescriptor::OneNthEltsVecArgument: {
+ case IITDescriptor::OneNthEltsVec: {
// If this is a forward reference, defer the check for later.
- if (D.getRefArgNumber() >= ArgTys.size())
+ if (D.getOverloadIndex() >= ArgTys.size())
return IsDeferredCheck || DeferCheck(Ty);
- auto *VTy = dyn_cast<VectorType>(ArgTys[D.getRefArgNumber()]);
+ auto *VTy = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
if (!VTy)
return true;
if (!VTy->getElementCount().isKnownMultipleOf(D.getVectorDivisor()))
@@ -989,13 +994,13 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return VectorType::getOneNthElementsVectorType(VTy, D.getVectorDivisor()) !=
Ty;
}
- case IITDescriptor::SameVecWidthArgument: {
- if (D.getArgumentNumber() >= ArgTys.size()) {
+ case IITDescriptor::SameVecWidth: {
+ if (D.getOverloadIndex() >= ArgTys.size()) {
// Defer check and subsequent check for the vector element type.
Infos = Infos.slice(1);
return IsDeferredCheck || DeferCheck(Ty);
}
- auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
+ auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
auto *ThisArgType = dyn_cast<VectorType>(Ty);
// Both must be vectors of the same number of elements or neither.
if ((ReferenceType != nullptr) != (ThisArgType != nullptr))
@@ -1010,8 +1015,8 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
IsDeferredCheck);
}
case IITDescriptor::VecOfAnyPtrsToElt: {
- unsigned RefArgNumber = D.getRefArgNumber();
- if (RefArgNumber >= ArgTys.size()) {
+ unsigned RefOverloadIndex = D.getRefOverloadIndex();
+ if (RefOverloadIndex >= ArgTys.size()) {
if (IsDeferredCheck)
return true;
// If forward referencing, already add the pointer-vector type and
@@ -1021,7 +1026,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
}
if (!IsDeferredCheck) {
- assert(D.getOverloadArgNumber() == ArgTys.size() &&
+ assert(D.getOverloadIndex() == ArgTys.size() &&
"Table consistency error");
ArgTys.push_back(Ty);
}
@@ -1029,37 +1034,37 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
// Verify the overloaded type "matches" the Ref type.
// i.e. Ty is a vector with the same width as Ref.
// Composed of pointers to the same element type as Ref.
- auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
+ auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefOverloadIndex]);
auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
if (!ThisArgVecTy || !ReferenceType ||
(ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
return true;
return !ThisArgVecTy->getElementType()->isPointerTy();
}
- case IITDescriptor::VecElementArgument: {
- if (D.getArgumentNumber() >= ArgTys.size())
+ case IITDescriptor::VecElement: {
+ if (D.getOverloadIndex() >= ArgTys.size())
return IsDeferredCheck ? true : DeferCheck(Ty);
- auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
+ auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
return !ReferenceType || Ty != ReferenceType->getElementType();
}
- case IITDescriptor::Subdivide2Argument:
- case IITDescriptor::Subdivide4Argument: {
+ case IITDescriptor::Subdivide2:
+ case IITDescriptor::Subdivide4: {
// If this is a forward reference, defer the check for later.
- if (D.getArgumentNumber() >= ArgTys.size())
+ if (D.getOverloadIndex() >= ArgTys.size())
return IsDeferredCheck || DeferCheck(Ty);
- Type *NewTy = ArgTys[D.getArgumentNumber()];
+ Type *NewTy = ArgTys[D.getOverloadIndex()];
if (auto *VTy = dyn_cast<VectorType>(NewTy)) {
- int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+ int SubDivs = D.Kind == IITDescriptor::Subdivide2 ? 1 : 2;
NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);
return Ty != NewTy;
}
return true;
}
case IITDescriptor::VecOfBitcastsToInt: {
- if (D.getArgumentNumber() >= ArgTys.size())
+ if (D.getOverloadIndex() >= ArgTys.size())
return IsDeferredCheck || DeferCheck(Ty);
- auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
+ auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getOverloadIndex()]);
auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
if (!ThisArgVecTy || !ReferenceType)
return true;
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 031ce978d21ce..ac78e8251df9a 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -475,8 +475,8 @@ PruningFunctionCloner::cloneInstruction(BasicBlock::const_iterator II) {
for (unsigned I = 0, E = Descriptor.size(); I != E; ++I) {
Intrinsic::IITDescriptor Operand = Descriptor[I];
switch (Operand.Kind) {
- case Intrinsic::IITDescriptor::Argument:
- if (Operand.getArgumentKind() !=
+ case Intrinsic::IITDescriptor::Overloaded:
+ if (Operand.getOverloadKind() !=
Intrinsic::IITDescriptor::AK_MatchType) {
if (I == 0)
TParams.push_back(OldInst.getType());
@@ -484,7 +484,7 @@ PruningFunctionCloner::cloneInstruction(BasicBlock::const_iterator II) {
TParams.push_back(OldInst.getOperand(I - 1)->getType());
}
break;
- case Intrinsic::IITDescriptor::SameVecWidthArgument:
+ case Intrinsic::IITDescriptor::SameVecWidth:
++I;
break;
default:
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index 5a2b2f89d5582..bda911b50d813 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -54,7 +54,7 @@ class IntrinsicEmitter {
void run(raw_ostream &OS, bool Enums);
void EmitEnumInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
- void EmitArgKind(raw_ostream &OS);
+ void EmitAnyKind(raw_ostream &OS);
void EmitIITInfo(raw_ostream &OS);
void EmitTargetInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS);
void EmitIntrinsicToNameTable(const CodeGenIntrinsicTable &Ints,
@@ -97,8 +97,8 @@ void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) {
// Emit the enum information.
EmitEnumInfo(Ints, OS);
- // Emit ArgKind for Intrinsics.h.
- EmitArgKind(OS);
+ // Emit AnyKind for Intrinsics.h.
+ EmitAnyKind(OS);
} else {
// Emit IIT_Info constants.
EmitIITInfo(OS);
@@ -199,16 +199,16 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints,
OS << "}; // enum\n";
}
-void IntrinsicEmitter::EmitArgKind(raw_ostream &OS) {
+void IntrinsicEmitter::EmitAnyKind(raw_ostream &OS) {
if (!IntrinsicPrefix.empty())
return;
- IfDefEmitter IfDef(OS, "GET_INTRINSIC_ARGKIND");
- OS << "// llvm::Intrinsic::IITDescriptor::ArgKind.\n";
- if (const auto RecArgKind = Records.getDef("ArgKind")) {
- for (const auto &RV : RecArgKind->getValues())
+ IfDefEmitter IfDef(OS, "GET_INTRINSIC_ANYKIND");
+ OS << "// llvm::Intrinsic::IITDescriptor::AnyKind.\n";
+ if (const auto RecAnyKind = Records.getDef("AnyKind")) {
+ for (const auto &RV : RecAnyKind->getValues())
OS << " AK_" << RV.getName() << " = " << *RV.getValue() << ",\n";
} else {
- OS << "#error \"ArgKind is not defined\"\n";
+ OS << "#error \"AnyKind is not defined\"\n";
}
}
More information about the llvm-commits
mailing list