1//===-- Intrinsics.cpp - Intrinsic Function Handling ------------*- C++ -*-===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file implements functions required for supporting intrinsic functions. 11//===----------------------------------------------------------------------===// 17#include "llvm/IR/IntrinsicsAArch64.h" 18#include "llvm/IR/IntrinsicsAMDGPU.h" 19#include "llvm/IR/IntrinsicsARM.h" 20#include "llvm/IR/IntrinsicsBPF.h" 21#include "llvm/IR/IntrinsicsHexagon.h" 22#include "llvm/IR/IntrinsicsLoongArch.h" 23#include "llvm/IR/IntrinsicsMips.h" 24#include "llvm/IR/IntrinsicsNVPTX.h" 25#include "llvm/IR/IntrinsicsPowerPC.h" 26#include "llvm/IR/IntrinsicsR600.h" 27#include "llvm/IR/IntrinsicsRISCV.h" 28#include "llvm/IR/IntrinsicsS390.h" 29#include "llvm/IR/IntrinsicsVE.h" 30#include "llvm/IR/IntrinsicsX86.h" 31#include "llvm/IR/IntrinsicsXCore.h" 37/// Table of string intrinsic names indexed by enum value. 38#define GET_INTRINSIC_NAME_TABLE 39#include "llvm/IR/IntrinsicImpl.inc" 40#undef GET_INTRINSIC_NAME_TABLE 43assert(
id < num_intrinsics &&
"Invalid intrinsic ID!");
44return IntrinsicNameTable[IntrinsicNameOffsetTable[
id]];
48assert(
id < num_intrinsics &&
"Invalid intrinsic ID!");
50"This version of getName does not support overloading");
54/// Returns a stable mangling for the type specified for use in the name 55/// mangling scheme used by 'any' types in intrinsic signatures. The mangling 56/// of named types is simply their name. Manglings for unnamed types consist 57/// of a prefix ('p' for pointers, 'a' for arrays, 'f_' for functions) 58/// combined with the mangling of their component types. A vararg function 59/// type will have a suffix of 'vararg'. Since function types can contain 60/// other function types, we close a function type mangling with suffix 'f' 61/// which can't be confused with it's prefix. This ensures we don't have 62/// collisions between two unrelated function types. Otherwise, you might 63/// parse ffXX as f(fXX) or f(fX)X. (X is a placeholder for any other type.) 64/// The HasUnnamedType boolean is set if an unnamed type was encountered, 65/// indicating that extra care must be taken to ensure a unique name. 69 Result +=
"p" + utostr(PTyp->getAddressSpace());
70 }
elseif (
ArrayType *ATyp = dyn_cast<ArrayType>(Ty)) {
71 Result +=
"a" + utostr(ATyp->getNumElements()) +
73 }
elseif (
StructType *STyp = dyn_cast<StructType>(Ty)) {
74if (!STyp->isLiteral()) {
77 Result += STyp->getName();
82for (
auto *Elem : STyp->elements())
85// Ensure nested structs are distinguishable. 87 }
elseif (
FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
89for (
size_t i = 0; i < FT->getNumParams(); i++)
93// Ensure nested function types are distinguishable. 95 }
elseif (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
99 Result +=
"v" + utostr(EC.getKnownMinValue()) +
101 }
elseif (
TargetExtType *TETy = dyn_cast<TargetExtType>(Ty)) {
103 Result += TETy->getName();
104for (
Type *ParamTy : TETy->type_params())
106for (
unsigned IntParam : TETy->int_params())
107 Result +=
"_" + utostr(IntParam);
108// Ensure nested target extension types are distinguishable. 145 Result +=
"i" + utostr(cast<IntegerType>(Ty)->
getBitWidth());
154bool EarlyModuleCheck) {
156assert(Id < Intrinsic::num_intrinsics &&
"Invalid intrinsic ID!");
158"This version of getName is for overloaded intrinsics only");
159 (void)EarlyModuleCheck;
160assert((!EarlyModuleCheck || M ||
161 !
any_of(Tys, [](
Type *
T) {
return isa<PointerType>(
T); })) &&
162"Intrinsic overloading on pointer types need to provide a Module");
163bool HasUnnamedType =
false;
168assert(M &&
"unnamed types need a module");
173"Provided FunctionType must match arguments");
174return M->getUniqueIntrinsicName(Result, Id, FT);
181assert(M &&
"We need to have a Module");
189/// IIT_Info - These are enumerators that describe the entries returned by the 190/// getIntrinsicInfoTableEntries function. 192/// Defined in Intrinsics.td. 194#define GET_INTRINSIC_IITINFO 195#include "llvm/IR/IntrinsicImpl.inc" 196#undef GET_INTRINSIC_IITINFO 203using namespaceIntrinsic;
205bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC);
208unsigned StructElts = 2;
212 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Void, 0));
215 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));
218 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
221 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::AMX, 0));
224 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Token, 0));
227 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));
230 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Half, 0));
233 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::BFloat, 0));
236 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Float, 0));
239 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Double, 0));
242 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Quad, 0));
245 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::PPCQuad, 0));
248 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 1));
251 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 2));
254 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 4));
256case IIT_AARCH64_SVCOUNT:
257 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::AArch64Svcount, 0));
260 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 8));
263 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 16));
266 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 32));
269 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 64));
272 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 128));
275 OutputTable.
push_back(IITDescriptor::getVector(1, IsScalableVector));
279 OutputTable.
push_back(IITDescriptor::getVector(2, IsScalableVector));
283 OutputTable.
push_back(IITDescriptor::getVector(3, IsScalableVector));
287 OutputTable.
push_back(IITDescriptor::getVector(4, IsScalableVector));
291 OutputTable.
push_back(IITDescriptor::getVector(6, IsScalableVector));
295 OutputTable.
push_back(IITDescriptor::getVector(8, IsScalableVector));
299 OutputTable.
push_back(IITDescriptor::getVector(10, IsScalableVector));
303 OutputTable.
push_back(IITDescriptor::getVector(16, IsScalableVector));
307 OutputTable.
push_back(IITDescriptor::getVector(32, IsScalableVector));
311 OutputTable.
push_back(IITDescriptor::getVector(64, IsScalableVector));
315 OutputTable.
push_back(IITDescriptor::getVector(128, IsScalableVector));
319 OutputTable.
push_back(IITDescriptor::getVector(256, IsScalableVector));
323 OutputTable.
push_back(IITDescriptor::getVector(512, IsScalableVector));
327 OutputTable.
push_back(IITDescriptor::getVector(1024, IsScalableVector));
331 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Pointer, 10));
334 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Pointer, 20));
337 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
339case IIT_ANYPTR:
// [ANYPTR addrspace] 341 IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));
344unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
348case IIT_EXTEND_ARG: {
349unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
351 IITDescriptor::get(IITDescriptor::ExtendArgument,
ArgInfo));
355unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
357 IITDescriptor::get(IITDescriptor::TruncArgument,
ArgInfo));
360case IIT_HALF_VEC_ARG: {
361unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
363 IITDescriptor::get(IITDescriptor::HalfVecArgument,
ArgInfo));
366case IIT_SAME_VEC_WIDTH_ARG: {
367unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
369 IITDescriptor::get(IITDescriptor::SameVecWidthArgument,
ArgInfo));
372case IIT_VEC_OF_ANYPTRS_TO_ELT: {
373unsignedshort ArgNo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
374unsignedshort RefNo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
376 IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo));
380 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
405 IITDescriptor::get(IITDescriptor::Struct, StructElts));
407for (
unsigned i = 0; i != StructElts; ++i)
411case IIT_SUBDIVIDE2_ARG: {
412unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
414 IITDescriptor::get(IITDescriptor::Subdivide2Argument,
ArgInfo));
417case IIT_SUBDIVIDE4_ARG: {
418unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
420 IITDescriptor::get(IITDescriptor::Subdivide4Argument,
ArgInfo));
423case IIT_VEC_ELEMENT: {
424unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
426 IITDescriptor::get(IITDescriptor::VecElementArgument,
ArgInfo));
429case IIT_SCALABLE_VEC: {
433case IIT_VEC_OF_BITCASTS_TO_INT: {
434unsignedArgInfo = (NextElt == Infos.
size() ? 0 : Infos[NextElt++]);
436 IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt,
ArgInfo));
443#define GET_INTRINSIC_GENERATOR_GLOBAL 444#include "llvm/IR/IntrinsicImpl.inc" 445#undef GET_INTRINSIC_GENERATOR_GLOBAL 449static_assert(
sizeof(IIT_Table[0]) == 2,
450"Expect 16-bit entries in IIT_Table");
451// Check to see if the intrinsic's type was expressible by the table. 452uint16_t TableVal = IIT_Table[
id - 1];
454// Decode the TableVal into an array of IITValues. 459// This is an offset into the IIT_LongEncodingTable. 460 IITEntries = IIT_LongEncodingTable;
462// Strip sentinel bit. 463 NextElt = TableVal & 0x7fff;
465// If the entry was encoded into a single word in the table itself, decode 466// it from an array of nibbles to an array of bytes. 472 IITEntries = IITValues;
476// Okay, decode the table into the output vector of IITDescriptors. 478while (NextElt != IITEntries.
size() && IITEntries[NextElt] != 0)
484using namespaceIntrinsic;
486 IITDescriptor
D = Infos.
front();
487 Infos = Infos.
slice(1);
490case IITDescriptor::Void:
492case IITDescriptor::VarArg:
494case IITDescriptor::MMX:
496case IITDescriptor::AMX:
498case IITDescriptor::Token:
500case IITDescriptor::Metadata:
502case IITDescriptor::Half:
504case IITDescriptor::BFloat:
506case IITDescriptor::Float:
508case IITDescriptor::Double:
510case IITDescriptor::Quad:
512case IITDescriptor::PPCQuad:
514case IITDescriptor::AArch64Svcount:
517case IITDescriptor::Integer:
519case IITDescriptor::Vector:
522case IITDescriptor::Pointer:
523return PointerType::get(Context,
D.Pointer_AddressSpace);
524case IITDescriptor::Struct: {
526for (
unsigned i = 0, e =
D.Struct_NumElements; i != e; ++i)
530case IITDescriptor::Argument:
531return Tys[
D.getArgumentNumber()];
532case IITDescriptor::ExtendArgument: {
533Type *Ty = Tys[
D.getArgumentNumber()];
534if (
VectorType *VTy = dyn_cast<VectorType>(Ty))
535return VectorType::getExtendedElementVectorType(VTy);
539case IITDescriptor::TruncArgument: {
540Type *Ty = Tys[
D.getArgumentNumber()];
541if (
VectorType *VTy = dyn_cast<VectorType>(Ty))
542return VectorType::getTruncatedElementVectorType(VTy);
548case IITDescriptor::Subdivide2Argument:
549case IITDescriptor::Subdivide4Argument: {
550Type *Ty = Tys[
D.getArgumentNumber()];
552assert(VTy &&
"Expected an argument of Vector Type");
553int SubDivs =
D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
554return VectorType::getSubdividedVectorType(VTy, SubDivs);
556case IITDescriptor::HalfVecArgument:
557return VectorType::getHalfElementsVectorType(
558 cast<VectorType>(Tys[
D.getArgumentNumber()]));
559case IITDescriptor::SameVecWidthArgument: {
561Type *Ty = Tys[
D.getArgumentNumber()];
562if (
auto *VTy = dyn_cast<VectorType>(Ty))
563return VectorType::get(EltTy, VTy->getElementCount());
566case IITDescriptor::VecElementArgument: {
567Type *Ty = Tys[
D.getArgumentNumber()];
568if (
VectorType *VTy = dyn_cast<VectorType>(Ty))
569return VTy->getElementType();
572case IITDescriptor::VecOfBitcastsToInt: {
573Type *Ty = Tys[
D.getArgumentNumber()];
575assert(VTy &&
"Expected an argument of Vector Type");
576return VectorType::getInteger(VTy);
578case IITDescriptor::VecOfAnyPtrsToElt:
579// Return the overloaded type (which determines the pointers address space) 580return Tys[
D.getOverloadArgNumber()];
597// DecodeFixedType returns Void for IITDescriptor::Void and 598// IITDescriptor::VarArg If we see void type as the type of the last argument, 599// it is vararg intrinsic 600if (!ArgTys.
empty() && ArgTys.
back()->isVoidTy()) {
602return FunctionType::get(ResultTy, ArgTys,
true);
604return FunctionType::get(ResultTy, ArgTys,
false);
608#define GET_INTRINSIC_OVERLOAD_TABLE 609#include "llvm/IR/IntrinsicImpl.inc" 610#undef GET_INTRINSIC_OVERLOAD_TABLE 613/// Table of per-target intrinsic name tables. 614#define GET_INTRINSIC_TARGET_DATA 615#include "llvm/IR/IntrinsicImpl.inc" 616#undef GET_INTRINSIC_TARGET_DATA 619return IID > TargetInfos[0].Count;
622/// Looks up Name in NameTable via binary search. NameTable must be sorted 623/// and all entries must start with "llvm.". If NameTable contains an exact 624/// match for Name or a prefix of Name followed by a dot, its index in 625/// NameTable is returned. Otherwise, -1 is returned. 628assert(
Name.starts_with(
"llvm.") &&
"Unexpected intrinsic prefix");
631// Do successive binary searches of the dotted name components. For 632// "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of 633// intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then 634// "llvm.gc.experimental.statepoint", and then we will stop as the range is 635// size 1. During the search, we can skip the prefix that we already know is 636// identical. By using strncmp we consider names with differing suffixes to 637// be part of the equal range. 638size_t CmpEnd = 4;
// Skip the "llvm" component. 640 CmpEnd += 1 +
Target.size();
// skip the .target component. 642constunsigned *
Low = NameOffsetTable.
begin();
643constunsigned *
High = NameOffsetTable.
end();
644constunsigned *LastLow =
Low;
646size_t CmpStart = CmpEnd;
647 CmpEnd =
Name.find(
'.', CmpStart + 1);
649auto Cmp = [CmpStart, CmpEnd](
autoLHS,
autoRHS) {
650// `equal_range` requires the comparison to work with either side being an 651// offset or the value. Detect which kind each side is to set up the 654ifconstexpr (std::is_integral_v<
decltype(
LHS)>) {
655 LHSStr = IntrinsicNameTable[
LHS];
660ifconstexpr (std::is_integral_v<
decltype(
RHS)>) {
661 RHSStr = IntrinsicNameTable[
RHS];
665return strncmp(LHSStr.
data() + CmpStart, RHSStr.
data() + CmpStart,
666 CmpEnd - CmpStart) < 0;
674if (LastLow == NameOffsetTable.
end())
676StringRef NameFound = IntrinsicNameTable[*LastLow];
677if (
Name == NameFound ||
678 (
Name.starts_with(NameFound) &&
Name[NameFound.
size()] ==
'.'))
679return LastLow - NameOffsetTable.
begin();
683/// Find the segment of \c IntrinsicNameOffsetTable for intrinsics with the same 684/// target as \c Name, or the generic table if \c Name is not target specific. 686/// Returns the relevant slice of \c IntrinsicNameOffsetTable and the target 688static std::pair<ArrayRef<unsigned>,
StringRef>
693// Drop "llvm." and take the first dotted component. That will be the target 694// if this is target specific. 697 Targets, [=](
const IntrinsicTargetInfo &TI) {
return TI.Name <
Target; });
698// We've either found the target or just fall back to the generic set, which 700constauto &TI = It != Targets.
end() && It->Name ==
Target ? *It : Targets[0];
701return {
ArrayRef(&IntrinsicNameOffsetTable[1] + TI.Offset, TI.Count),
705/// This does the actual lookup of an intrinsic ID which matches the given 713// Intrinsic IDs correspond to the location in IntrinsicNameTable, but we have 714// an index into a sub-table. 715int Adjust = NameOffsetTable.data() - IntrinsicNameOffsetTable;
718// If the intrinsic is not overloaded, require an exact match. If it is 719// overloaded, require either exact or prefix match. 720constauto MatchSize = IntrinsicNameTable[NameOffsetTable[
Idx]].size();
721assert(
Name.size() >= MatchSize &&
"Expected either exact or prefix match");
722bool IsExactMatch =
Name.size() == MatchSize;
727/// This defines the "Intrinsic::getAttributes(ID id)" method. 728#define GET_INTRINSIC_ATTRIBUTES 729#include "llvm/IR/IntrinsicImpl.inc" 730#undef GET_INTRINSIC_ATTRIBUTES 734// There can never be multiple globals with the same name of different types, 735// because intrinsics must be a specific type. 737return cast<Function>(
738 M->getOrInsertFunction(
744return M->getFunction(
getName(
id));
753// This defines the "Intrinsic::getIntrinsicForClangBuiltin()" method. 754#define GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN 755#include "llvm/IR/IntrinsicImpl.inc" 756#undef GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN 758// This defines the "Intrinsic::getIntrinsicForMSBuiltin()" method. 759#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN 760#include "llvm/IR/IntrinsicImpl.inc" 761#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN 765#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ 766 case Intrinsic::INTRINSIC: 767#include "llvm/IR/ConstrainedOps.def" 777#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ 778 case Intrinsic::INTRINSIC: \ 779 return ROUND_MODE == 1; 780#include "llvm/IR/ConstrainedOps.def" 788 std::pair<Type *, ArrayRef<Intrinsic::IITDescriptor>>;
794bool IsDeferredCheck) {
795using namespaceIntrinsic;
797// If we ran out of descriptors, there are too many arguments. 801// Do this before slicing off the 'front' part 802auto InfosRef = Infos;
803auto DeferCheck = [&DeferredChecks, &InfosRef](
Type *
T) {
808 IITDescriptor
D = Infos.
front();
809 Infos = Infos.
slice(1);
812case IITDescriptor::Void:
814case IITDescriptor::VarArg:
816case IITDescriptor::MMX: {
821case IITDescriptor::AMX:
823case IITDescriptor::Token:
825case IITDescriptor::Metadata:
827case IITDescriptor::Half:
829case IITDescriptor::BFloat:
831case IITDescriptor::Float:
833case IITDescriptor::Double:
835case IITDescriptor::Quad:
837case IITDescriptor::PPCQuad:
839case IITDescriptor::Integer:
841case IITDescriptor::AArch64Svcount:
842return !isa<TargetExtType>(Ty) ||
843 cast<TargetExtType>(Ty)->getName() !=
"aarch64.svcount";
844case IITDescriptor::Vector: {
846return !VT || VT->getElementCount() !=
D.Vector_Width ||
848 DeferredChecks, IsDeferredCheck);
850case IITDescriptor::Pointer: {
852return !PT || PT->getAddressSpace() !=
D.Pointer_AddressSpace;
855case IITDescriptor::Struct: {
857if (!ST || !ST->isLiteral() || ST->isPacked() ||
858 ST->getNumElements() !=
D.Struct_NumElements)
861for (
unsigned i = 0, e =
D.Struct_NumElements; i != e; ++i)
863 DeferredChecks, IsDeferredCheck))
868case IITDescriptor::Argument:
869// If this is the second occurrence of an argument, 870// verify that the later instance matches the previous instance. 871if (
D.getArgumentNumber() < ArgTys.
size())
872return Ty != ArgTys[
D.getArgumentNumber()];
874if (
D.getArgumentNumber() > ArgTys.
size() ||
875D.getArgumentKind() == IITDescriptor::AK_MatchType)
876return IsDeferredCheck || DeferCheck(Ty);
878assert(
D.getArgumentNumber() == ArgTys.
size() && !IsDeferredCheck &&
879"Table consistency error");
882switch (
D.getArgumentKind()) {
883case IITDescriptor::AK_Any:
884returnfalse;
// Success 885case IITDescriptor::AK_AnyInteger:
887case IITDescriptor::AK_AnyFloat:
889case IITDescriptor::AK_AnyVector:
890return !isa<VectorType>(Ty);
891case IITDescriptor::AK_AnyPointer:
892return !isa<PointerType>(Ty);
898case IITDescriptor::ExtendArgument: {
899// If this is a forward reference, defer the check for later. 900if (
D.getArgumentNumber() >= ArgTys.
size())
901return IsDeferredCheck || DeferCheck(Ty);
903Type *NewTy = ArgTys[
D.getArgumentNumber()];
904if (
VectorType *VTy = dyn_cast<VectorType>(NewTy))
905 NewTy = VectorType::getExtendedElementVectorType(VTy);
906elseif (
IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
913case IITDescriptor::TruncArgument: {
914// If this is a forward reference, defer the check for later. 915if (
D.getArgumentNumber() >= ArgTys.
size())
916return IsDeferredCheck || DeferCheck(Ty);
918Type *NewTy = ArgTys[
D.getArgumentNumber()];
919if (
VectorType *VTy = dyn_cast<VectorType>(NewTy))
920 NewTy = VectorType::getTruncatedElementVectorType(VTy);
921elseif (
IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
928case IITDescriptor::HalfVecArgument:
929// If this is a forward reference, defer the check for later. 930if (
D.getArgumentNumber() >= ArgTys.
size())
931return IsDeferredCheck || DeferCheck(Ty);
932return !isa<VectorType>(ArgTys[
D.getArgumentNumber()]) ||
933 VectorType::getHalfElementsVectorType(
934 cast<VectorType>(ArgTys[
D.getArgumentNumber()])) != Ty;
935case IITDescriptor::SameVecWidthArgument: {
936if (
D.getArgumentNumber() >= ArgTys.
size()) {
937// Defer check and subsequent check for the vector element type. 938 Infos = Infos.
slice(1);
939return IsDeferredCheck || DeferCheck(Ty);
941auto *
ReferenceType = dyn_cast<VectorType>(ArgTys[
D.getArgumentNumber()]);
942auto *ThisArgType = dyn_cast<VectorType>(Ty);
943// Both must be vectors of the same number of elements or neither. 948if (
ReferenceType->getElementCount() != ThisArgType->getElementCount())
950 EltTy = ThisArgType->getElementType();
955case IITDescriptor::VecOfAnyPtrsToElt: {
956unsigned RefArgNumber =
D.getRefArgNumber();
957if (RefArgNumber >= ArgTys.
size()) {
960// If forward referencing, already add the pointer-vector type and 961// defer the checks for later. 963return DeferCheck(Ty);
966if (!IsDeferredCheck) {
968"Table consistency error");
972// Verify the overloaded type "matches" the Ref type. 973// i.e. Ty is a vector with the same width as Ref. 974// Composed of pointers to the same element type as Ref. 975auto *
ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
976auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
978 (
ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
980return !ThisArgVecTy->getElementType()->isPointerTy();
982case IITDescriptor::VecElementArgument: {
983if (
D.getArgumentNumber() >= ArgTys.
size())
984return IsDeferredCheck ?
true : DeferCheck(Ty);
985auto *
ReferenceType = dyn_cast<VectorType>(ArgTys[
D.getArgumentNumber()]);
988case IITDescriptor::Subdivide2Argument:
989case IITDescriptor::Subdivide4Argument: {
990// If this is a forward reference, defer the check for later. 991if (
D.getArgumentNumber() >= ArgTys.
size())
992return IsDeferredCheck || DeferCheck(Ty);
994Type *NewTy = ArgTys[
D.getArgumentNumber()];
995if (
auto *VTy = dyn_cast<VectorType>(NewTy)) {
996int SubDivs =
D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
997 NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);
1002case IITDescriptor::VecOfBitcastsToInt: {
1003if (
D.getArgumentNumber() >= ArgTys.
size())
1004return IsDeferredCheck || DeferCheck(Ty);
1005auto *
ReferenceType = dyn_cast<VectorType>(ArgTys[
D.getArgumentNumber()]);
1006auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
1009return ThisArgVecTy != VectorType::getInteger(
ReferenceType);
1024unsigned NumDeferredReturnChecks = DeferredChecks.
size();
1026for (
auto *Ty : FTy->
params())
1030for (
unsignedI = 0, E = DeferredChecks.
size();
I != E; ++
I) {
1043// If there are no descriptors left, then it can't be a vararg. 1047// There should be only one descriptor remaining at this point. 1048if (Infos.
size() != 1)
1051// Check and verify the descriptor. 1053 Infos = Infos.
slice(1);
1054if (
D.Kind == IITDescriptor::VarArg)
1070 Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
1091 std::string WantedName =
1093if (
Name == WantedName)
1097if (
auto *ExistingGV =
F->getParent()->getNamedValue(WantedName)) {
1098if (
auto *ExistingF = dyn_cast<Function>(ExistingGV))
1099if (ExistingF->getFunctionType() ==
F->getFunctionType())
1102// The name already exists, but is not a function or has the wrong 1103// prototype. Make place for the new one by renaming the old version. 1104// Either this old version will be removed later on or the module is 1105// invalid and we'll get an error. 1106 ExistingGV->
setName(WantedName +
".renamed");
1113"Shouldn't change the signature");
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Module.h This file contains the declarations for the Module class.
static bool matchIntrinsicType(Type *Ty, ArrayRef< Intrinsic::IITDescriptor > &Infos, SmallVectorImpl< Type * > &ArgTys, SmallVectorImpl< DeferredIntrinsicMatchPair > &DeferredChecks, bool IsDeferredCheck)
static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef< Type * > Tys, Module *M, FunctionType *FT, bool EarlyModuleCheck)
std::pair< Type *, ArrayRef< Intrinsic::IITDescriptor > > DeferredIntrinsicMatchPair
static std::pair< ArrayRef< unsigned >, StringRef > findTargetSubtable(StringRef Name)
Find the segment of IntrinsicNameOffsetTable for intrinsics with the same target as Name,...
static void DecodeIITType(unsigned &NextElt, ArrayRef< unsigned char > Infos, IIT_Info LastInfo, SmallVectorImpl< Intrinsic::IITDescriptor > &OutputTable)
IIT_Info
IIT_Info - These are enumerators that describe the entries returned by the getIntrinsicInfoTableEntri...
static Type * DecodeFixedType(ArrayRef< Intrinsic::IITDescriptor > &Infos, ArrayRef< Type * > Tys, LLVMContext &Context)
static int lookupLLVMIntrinsicByName(ArrayRef< unsigned > NameOffsetTable, StringRef Name, StringRef Target="")
Looks up Name in NameTable via binary search.
static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType)
Returns a stable mangling for the type specified for use in the name mangling scheme used by 'any' ty...
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some functions that are useful when dealing with strings.
static SymbolRef::Type getType(const Symbol *Sym)
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Class to represent function types.
ArrayRef< Type * > params() const
Type * getReturnType() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
void setCallingConv(CallingConv::ID CC)
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
This is an important class for using LLVM in a threaded context.
A Module instance is used to store all the information related to an LLVM module.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
static constexpr size_t npos
Class to represent struct types.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
static TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})
Return a target extension type having the specified name and optional type and integer parameters.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
static Type * getHalfTy(LLVMContext &C)
static Type * getDoubleTy(LLVMContext &C)
static Type * getBFloatTy(LLVMContext &C)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static Type * getX86_AMXTy(LLVMContext &C)
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
static Type * getMetadataTy(LLVMContext &C)
@ X86_AMXTyID
AMX vectors (8192 bits, X86 specific)
@ HalfTyID
16-bit floating point type
@ VoidTyID
type with no size
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ BFloatTyID
16-bit floating point type (7-bit significand)
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ FP128TyID
128-bit floating point type (112-bit significand)
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isFP128Ty() const
Return true if this is 'fp128'.
static Type * getVoidTy(LLVMContext &C)
static Type * getFP128Ty(LLVMContext &C)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static Type * getTokenTy(LLVMContext &C)
bool isX86_AMXTy() const
Return true if this is X86 AMX.
static Type * getFloatTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isTokenTy() const
Return true if this is 'token'.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static Type * getPPC_FP128Ty(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
bool isMetadataTy() const
Return true if this is 'metadata'.
void setName(const Twine &Name)
Change the name of the value.
Type * getElementType() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ID ArrayRef< Type * > Tys
Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
MatchIntrinsicTypesResult matchIntrinsicSignature(FunctionType *FTy, ArrayRef< IITDescriptor > &Infos, SmallVectorImpl< Type * > &ArgTys)
Match the specified function type with the type constraints specified by the .td file.
void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl< IITDescriptor > &T)
Return the IIT table descriptor for the specified intrinsic into an array of IITDescriptors.
MatchIntrinsicTypesResult
@ MatchIntrinsicTypes_Match
@ MatchIntrinsicTypes_NoMatchRet
@ MatchIntrinsicTypes_NoMatchArg
std::string getNameNoUnnamedTypes(ID Id, ArrayRef< Type * > Tys)
Return the LLVM name for an intrinsic.
std::optional< Function * > remangleIntrinsicFunction(Function *F)
bool hasConstrainedFPRoundingModeOperand(ID QID)
Returns true if the intrinsic ID is for one of the "Constrained Floating-Point Intrinsics" that take ...
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
bool isConstrainedFPIntrinsic(ID QID)
Returns true if the intrinsic ID is for one of the "Constrained Floating-Point Intrinsics".
ID lookupIntrinsicID(StringRef Name)
This does the actual lookup of an intrinsic ID which matches the given function name.
Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)
This version supports overloaded intrinsics.
StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
bool isOverloaded(ID id)
Returns true if the intrinsic can be overloaded.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys={})
Return the function type for an intrinsic.
bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, SmallVectorImpl< Type * > &ArgTys)
Gets the type arguments of an intrinsic call by matching type contraints specified by the ....
bool isTargetIntrinsic(ID IID)
isTargetIntrinsic - Returns true if IID is an intrinsic specific to a certain target.
bool matchIntrinsicVarArg(bool isVarArg, ArrayRef< IITDescriptor > &Infos)
Verify if the intrinsic has variable arguments.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Helper struct shared between Function Specialization and SCCP Solver.
This is a type descriptor which explains the type requirements of an intrinsic.