Skip to content

Commit 6786928

Browse files
authored
[Core] Skip over target name in intrinsic name lookup (#109971)
When searching for an intrinsic name in a target specific slice of the intrinsic name table, skip over the target prefix. For such cases, currently the first loop iteration in `lookupLLVMIntrinsicByName` does nothing (i.e., `Low` and `High` stay unchanged and it does not shrink down the search window), so we can skip this useless first iteration by skipping over the target prefix.
1 parent 2f43e65 commit 6786928

File tree

5 files changed

+37
-28
lines changed

5 files changed

+37
-28
lines changed

llvm/include/llvm/IR/Intrinsics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ namespace Intrinsic {
9595
/// match for Name or a prefix of Name followed by a dot, its index in
9696
/// NameTable is returned. Otherwise, -1 is returned.
9797
int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
98-
StringRef Name);
98+
StringRef Name, StringRef Target = "");
9999

100100
/// Map a Clang builtin name to an intrinsic ID.
101101
ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, StringRef BuiltinName);

llvm/lib/IR/Function.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -940,8 +940,8 @@ void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
940940
}
941941

942942
/// Table of string intrinsic names indexed by enum value.
943-
static const char * const IntrinsicNameTable[] = {
944-
"not_intrinsic",
943+
static constexpr const char *const IntrinsicNameTable[] = {
944+
"not_intrinsic",
945945
#define GET_INTRINSIC_NAME_TABLE
946946
#include "llvm/IR/IntrinsicImpl.inc"
947947
#undef GET_INTRINSIC_NAME_TABLE
@@ -963,8 +963,9 @@ bool Function::isTargetIntrinsic() const {
963963
/// Find the segment of \c IntrinsicNameTable for intrinsics with the same
964964
/// target as \c Name, or the generic table if \c Name is not target specific.
965965
///
966-
/// Returns the relevant slice of \c IntrinsicNameTable
967-
static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
966+
/// Returns the relevant slice of \c IntrinsicNameTable and the target name.
967+
static std::pair<ArrayRef<const char *>, StringRef>
968+
findTargetSubtable(StringRef Name) {
968969
assert(Name.starts_with("llvm."));
969970

970971
ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos);
@@ -976,14 +977,14 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
976977
// We've either found the target or just fall back to the generic set, which
977978
// is always first.
978979
const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
979-
return ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count);
980+
return {ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count), TI.Name};
980981
}
981982

982-
/// This does the actual lookup of an intrinsic ID which
983-
/// matches the given function name.
983+
/// This does the actual lookup of an intrinsic ID which matches the given
984+
/// function name.
984985
Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
985-
ArrayRef<const char *> NameTable = findTargetSubtable(Name);
986-
int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
986+
auto [NameTable, Target] = findTargetSubtable(Name);
987+
int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name, Target);
987988
if (Idx == -1)
988989
return Intrinsic::not_intrinsic;
989990

llvm/lib/IR/IntrinsicInst.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,10 @@ void DbgAssignIntrinsic::setValue(Value *V) {
237237
}
238238

239239
int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
240-
StringRef Name) {
240+
StringRef Name,
241+
StringRef Target) {
241242
assert(Name.starts_with("llvm.") && "Unexpected intrinsic prefix");
243+
assert(Name.drop_front(5).starts_with(Target) && "Unexpected target");
242244

243245
// Do successive binary searches of the dotted name components. For
244246
// "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
@@ -248,6 +250,9 @@ int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
248250
// identical. By using strncmp we consider names with differing suffixes to
249251
// be part of the equal range.
250252
size_t CmpEnd = 4; // Skip the "llvm" component.
253+
if (!Target.empty())
254+
CmpEnd += 1 + Target.size(); // skip the .target component.
255+
251256
const char *const *Low = NameTable.begin();
252257
const char *const *High = NameTable.end();
253258
const char *const *LastLow = Low;

llvm/lib/Transforms/Coroutines/Coroutines.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ static const char *const CoroIntrinsics[] = {
9797

9898
#ifndef NDEBUG
9999
static bool isCoroutineIntrinsicName(StringRef Name) {
100-
return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
100+
return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name, "coro") !=
101+
-1;
101102
}
102103
#endif
103104

llvm/unittests/IR/IntrinsicsTest.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ using namespace llvm;
3131

3232
namespace {
3333

34-
static const char *const NameTable1[] = {
35-
"llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
36-
};
37-
3834
class IntrinsicsTest : public ::testing::Test {
3935
LLVMContext Context;
4036
std::unique_ptr<Module> M;
@@ -67,18 +63,24 @@ class IntrinsicsTest : public ::testing::Test {
6763
};
6864

6965
TEST(IntrinsicNameLookup, Basic) {
70-
int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo");
71-
EXPECT_EQ(0, I);
72-
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64");
73-
EXPECT_EQ(0, I);
74-
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b");
75-
EXPECT_EQ(2, I);
76-
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b.a");
77-
EXPECT_EQ(3, I);
78-
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c");
79-
EXPECT_EQ(4, I);
80-
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c.f64");
81-
EXPECT_EQ(4, I);
66+
static constexpr const char *const NameTable1[] = {
67+
"llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
68+
};
69+
70+
static constexpr std::pair<const char *, int> Tests[] = {
71+
{"llvm.foo", 0}, {"llvm.foo.f64", 0}, {"llvm.foo.b", 2},
72+
{"llvm.foo.b.a", 3}, {"llvm.foo.c", 4}, {"llvm.foo.c.f64", 4},
73+
{"llvm.bar", -1},
74+
};
75+
76+
for (const auto &[Name, ExpectedIdx] : Tests) {
77+
int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name);
78+
EXPECT_EQ(ExpectedIdx, Idx);
79+
if (!StringRef(Name).starts_with("llvm.foo"))
80+
continue;
81+
Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name, "foo");
82+
EXPECT_EQ(ExpectedIdx, Idx);
83+
}
8284
}
8385

8486
// Tests to verify getIntrinsicForClangBuiltin.

0 commit comments

Comments
 (0)