3333#include " llvm/IR/IntrinsicsXCore.h"
3434#include " llvm/IR/Module.h"
3535#include " llvm/IR/Type.h"
36+ #include " llvm/Support/IntrinsicID.h"
3637
3738using namespace llvm ;
39+ using namespace Intrinsic ;
40+
41+ // / Table of per-target intrinsic name tables.
42+ #define GET_INTRINSIC_TARGET_DATA
43+ #include " llvm/IR/IntrinsicImpl.inc"
44+ #undef GET_INTRINSIC_TARGET_DATA
45+ size_t constexpr NumTargets = sizeof (TargetInfos) / sizeof (TargetInfos[0 ]);
46+
47+ // Returns true if the given intrinsic ID is valid, that is, its value is one
48+ // of the enum values defined for this intrinsic (including not_intrinsic).
49+ bool Intrinsic::IsIntrinsicIDValid (ID ID) {
50+ if (ID == Intrinsic::not_intrinsic)
51+ return true ;
52+ auto Decoded = DecodeIntrinsicIDNoFail (ID);
53+ if (!Decoded)
54+ return false ;
55+ unsigned TargetIdx = Decoded->first ;
56+ unsigned IntrinsicIdx = Decoded->second ;
57+ return TargetIdx < NumTargets && IntrinsicIdx < TargetInfos[TargetIdx].Count ;
58+ }
59+
60+ // Returns linear index of ID if its valid, else returns 0.
61+ unsigned getLinearIndex (Intrinsic::ID ID) {
62+ auto Decoded = DecodeIntrinsicIDNoFail (ID);
63+ if (!Decoded)
64+ return 0 ;
65+ unsigned TargetIdx = Decoded->first ;
66+ unsigned IntrinsicIdx = Decoded->second ;
67+ return TargetInfos[TargetIdx].FirstLinearIndex + IntrinsicIdx;
68+ }
69+
70+ ID Intrinsic::GetNextValidIntrinsicID (Intrinsic::ID ID) {
71+ if (ID == Intrinsic::not_intrinsic)
72+ return EncodeIntrinsicID (0 , 0 );
73+ if (ID == Intrinsic::last_valid_intrinsic_id)
74+ return Intrinsic::end_id;
75+ if (ID == Intrinsic::end_id)
76+ llvm_unreachable (" Cannot find the next valid intrisnic" );
77+ auto [TargetIndex, IntrinsicIndex] = DecodeIntrinsicID (ID);
78+ if (IntrinsicIndex + 1 < TargetInfos[TargetIndex].Count )
79+ return EncodeIntrinsicID (TargetIndex, IntrinsicIndex + 1 );
80+ if (TargetIndex + 1 < NumTargets)
81+ return EncodeIntrinsicID (TargetIndex + 1 , 0 );
82+ llvm_unreachable (" Cannot find the next valid intrisnic" );
83+ }
3884
3985// / Table of string intrinsic names indexed by enum value.
4086static constexpr const char *const IntrinsicNameTable[] = {
@@ -45,12 +91,12 @@ static constexpr const char *const IntrinsicNameTable[] = {
4591};
4692
4793StringRef Intrinsic::getBaseName (ID id) {
48- assert (id < num_intrinsics && " Invalid intrinsic ID!" );
49- return IntrinsicNameTable[id ];
94+ assert (IsIntrinsicIDValid (id) && " Invalid intrinsic ID!" );
95+ return ArrayRef ( IntrinsicNameTable)[ getLinearIndex (id) ];
5096}
5197
5298StringRef Intrinsic::getName (ID id) {
53- assert (id < num_intrinsics && " Invalid intrinsic ID!" );
99+ assert (IsIntrinsicIDValid (id) && " Invalid intrinsic ID!" );
54100 assert (!Intrinsic::isOverloaded (id) &&
55101 " This version of getName does not support overloading" );
56102 return getBaseName (id);
@@ -157,8 +203,7 @@ static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) {
157203static std::string getIntrinsicNameImpl (Intrinsic::ID Id, ArrayRef<Type *> Tys,
158204 Module *M, FunctionType *FT,
159205 bool EarlyModuleCheck) {
160-
161- assert (Id < Intrinsic::num_intrinsics && " Invalid intrinsic ID!" );
206+ assert (IsIntrinsicIDValid (Id) && " Invalid intrinsic ID!" );
162207 assert ((Tys.empty () || Intrinsic::isOverloaded (Id)) &&
163208 " This version of getName is for overloaded intrinsics only" );
164209 (void )EarlyModuleCheck;
@@ -450,11 +495,15 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
450495#undef GET_INTRINSIC_GENERATOR_GLOBAL
451496
452497void Intrinsic::getIntrinsicInfoTableEntries (
453- ID id , SmallVectorImpl<IITDescriptor> &T) {
498+ ID IntrinsicID , SmallVectorImpl<IITDescriptor> &T) {
454499 static_assert (sizeof (IIT_Table[0 ]) == 2 ,
455500 " Expect 16-bit entries in IIT_Table" );
501+ assert (IsIntrinsicIDValid (IntrinsicID));
502+ unsigned Idx = getLinearIndex (IntrinsicID);
503+ if (Idx == 0 )
504+ return ;
456505 // Check to see if the intrinsic's type was expressible by the table.
457- uint16_t TableVal = IIT_Table[id - 1 ];
506+ uint16_t TableVal = IIT_Table[Idx - 1 ];
458507
459508 // Decode the TableVal into an array of IITValues.
460509 SmallVector<unsigned char > IITValues;
@@ -609,19 +658,20 @@ FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
609658 return FunctionType::get (ResultTy, ArgTys, false );
610659}
611660
612- bool Intrinsic::isOverloaded (ID id) {
661+ // Check if an intrinsic is overloaded or not using its linear index.
662+ static bool isOverloadedUsingLinearIndex (unsigned Idx) {
613663#define GET_INTRINSIC_OVERLOAD_TABLE
614664#include " llvm/IR/IntrinsicImpl.inc"
615665#undef GET_INTRINSIC_OVERLOAD_TABLE
616666}
617667
618- // / Table of per-target intrinsic name tables.
619- # define GET_INTRINSIC_TARGET_DATA
620- # include " llvm/IR/IntrinsicImpl.inc "
621- # undef GET_INTRINSIC_TARGET_DATA
668+ bool Intrinsic::isOverloaded (ID id) {
669+ assert ( IsIntrinsicIDValid (id));
670+ return isOverloadedUsingLinearIndex ( getLinearIndex (id));
671+ }
622672
623673bool Intrinsic::isTargetIntrinsic (Intrinsic::ID IID) {
624- return IID > TargetInfos[ 0 ]. Count ;
674+ return IID != Intrinsic::not_intrinsic && DecodeIntrinsicID (IID). first != 0 ;
625675}
626676
627677int llvm::Intrinsic::lookupLLVMIntrinsicByName (ArrayRef<const char *> NameTable,
@@ -683,7 +733,29 @@ findTargetSubtable(StringRef Name) {
683733 // We've either found the target or just fall back to the generic set, which
684734 // is always first.
685735 const auto &TI = It != Targets.end () && It->Name == Target ? *It : Targets[0 ];
686- return {ArrayRef (&IntrinsicNameTable[1 ] + TI.Offset , TI.Count ), TI.Name };
736+ unsigned LinearIndex = TI.FirstLinearIndex ;
737+ return {ArrayRef (IntrinsicNameTable + LinearIndex, TI.Count ), TI.Name };
738+ }
739+
740+ static Intrinsic::ID getIntrinsicIDFromIndex (unsigned Idx) {
741+ if (Idx == 0 )
742+ return Intrinsic::not_intrinsic;
743+
744+ auto It =
745+ partition_point (TargetInfos, [Idx](const IntrinsicTargetInfo &Info) {
746+ return Info.FirstLinearIndex + Info.Count < Idx;
747+ });
748+ // Idx, if present, will be in the entry at It or It + 1.
749+ if (It == std::end (TargetInfos))
750+ return Intrinsic::not_intrinsic;
751+ unsigned TargetIndex = std::distance (std::begin (TargetInfos), It);
752+ if (It->FirstLinearIndex <= Idx && Idx < It->FirstLinearIndex + It->Count )
753+ return EncodeIntrinsicID (TargetIndex, Idx - It->FirstLinearIndex );
754+ ++It;
755+ ++TargetIndex;
756+ if (It->FirstLinearIndex <= Idx && Idx < It->FirstLinearIndex + It->Count )
757+ return EncodeIntrinsicID (TargetIndex, Idx - It->FirstLinearIndex );
758+ return Intrinsic::not_intrinsic;
687759}
688760
689761// / This does the actual lookup of an intrinsic ID which matches the given
@@ -693,19 +765,19 @@ Intrinsic::ID Intrinsic::lookupIntrinsicID(StringRef Name) {
693765 int Idx = Intrinsic::lookupLLVMIntrinsicByName (NameTable, Name, Target);
694766 if (Idx == -1 )
695767 return Intrinsic::not_intrinsic;
696-
697- // Intrinsic IDs correspond to the location in IntrinsicNameTable, but we have
698- // an index into a sub-table.
768+ const auto MatchSize = strlen (NameTable[Idx]);
769+ // Adjust the index from sub-table index to index into the global table.
699770 int Adjust = NameTable.data () - IntrinsicNameTable;
700- Intrinsic::ID ID = static_cast <Intrinsic::ID>( Idx + Adjust) ;
771+ Idx += Adjust;
701772
702773 // If the intrinsic is not overloaded, require an exact match. If it is
703774 // overloaded, require either exact or prefix match.
704- const auto MatchSize = strlen (NameTable[Idx]);
705775 assert (Name.size () >= MatchSize && " Expected either exact or prefix match" );
706776 bool IsExactMatch = Name.size () == MatchSize;
707- return IsExactMatch || Intrinsic::isOverloaded (ID) ? ID
708- : Intrinsic::not_intrinsic;
777+ Intrinsic::ID r = IsExactMatch || isOverloadedUsingLinearIndex (Idx)
778+ ? getIntrinsicIDFromIndex (Idx)
779+ : Intrinsic::not_intrinsic;
780+ return r;
709781}
710782
711783// / This defines the "Intrinsic::getAttributes(ID id)" method.
@@ -1043,8 +1115,9 @@ bool Intrinsic::matchIntrinsicVarArg(
10431115
10441116bool Intrinsic::getIntrinsicSignature (Intrinsic::ID ID, FunctionType *FT,
10451117 SmallVectorImpl<Type *> &ArgTys) {
1046- if (!ID )
1118+ if (ID == Intrinsic::not_intrinsic )
10471119 return false ;
1120+ assert (IsIntrinsicIDValid (ID));
10481121
10491122 SmallVector<Intrinsic::IITDescriptor, 8 > Table;
10501123 getIntrinsicInfoTableEntries (ID, Table);
0 commit comments