[llvm] [Core] Skip over target name in intrinsic name lookup (PR #109971)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 25 07:28:55 PDT 2024
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/109971
>From 15afdf19ffb7f00a403b8b0473e2faba35ce7795 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 25 Sep 2024 05:23:14 -0700
Subject: [PATCH] [Core] Skip over target name in intrinsic name lookup
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.
---
llvm/include/llvm/IR/Intrinsics.h | 2 +-
llvm/lib/IR/Function.cpp | 19 ++++++-----
llvm/lib/IR/IntrinsicInst.cpp | 7 +++-
llvm/lib/Transforms/Coroutines/Coroutines.cpp | 3 +-
llvm/unittests/IR/IntrinsicsTest.cpp | 34 ++++++++++---------
5 files changed, 37 insertions(+), 28 deletions(-)
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 4bd7fda77f3132..0ec7e47812af44 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -95,7 +95,7 @@ namespace Intrinsic {
/// match for Name or a prefix of Name followed by a dot, its index in
/// NameTable is returned. Otherwise, -1 is returned.
int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
- StringRef Name);
+ StringRef Name, StringRef Target = "");
/// Map a Clang builtin name to an intrinsic ID.
ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, StringRef BuiltinName);
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 8767c2971f62c8..863900c3f14b2b 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -940,8 +940,8 @@ void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
}
/// Table of string intrinsic names indexed by enum value.
-static const char * const IntrinsicNameTable[] = {
- "not_intrinsic",
+static constexpr const char *const IntrinsicNameTable[] = {
+ "not_intrinsic",
#define GET_INTRINSIC_NAME_TABLE
#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_NAME_TABLE
@@ -963,8 +963,9 @@ bool Function::isTargetIntrinsic() const {
/// Find the segment of \c IntrinsicNameTable for intrinsics with the same
/// target as \c Name, or the generic table if \c Name is not target specific.
///
-/// Returns the relevant slice of \c IntrinsicNameTable
-static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
+/// Returns the relevant slice of \c IntrinsicNameTable and the target name.
+static std::pair<ArrayRef<const char *>, StringRef>
+findTargetSubtable(StringRef Name) {
assert(Name.starts_with("llvm."));
ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos);
@@ -976,14 +977,14 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
// We've either found the target or just fall back to the generic set, which
// is always first.
const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
- return ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count);
+ return {ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count), TI.Name};
}
-/// This does the actual lookup of an intrinsic ID which
-/// matches the given function name.
+/// This does the actual lookup of an intrinsic ID which matches the given
+/// function name.
Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
- ArrayRef<const char *> NameTable = findTargetSubtable(Name);
- int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
+ auto [NameTable, Target] = findTargetSubtable(Name);
+ int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name, Target);
if (Idx == -1)
return Intrinsic::not_intrinsic;
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index 7ed82c2ece464a..5654a3a3236c6d 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -237,8 +237,10 @@ void DbgAssignIntrinsic::setValue(Value *V) {
}
int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
- StringRef Name) {
+ StringRef Name,
+ StringRef Target) {
assert(Name.starts_with("llvm.") && "Unexpected intrinsic prefix");
+ assert(Name.drop_front(5).starts_with(Target) && "Unexpected target");
// Do successive binary searches of the dotted name components. For
// "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
@@ -248,6 +250,9 @@ int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
// identical. By using strncmp we consider names with differing suffixes to
// be part of the equal range.
size_t CmpEnd = 4; // Skip the "llvm" component.
+ if (!Target.empty())
+ CmpEnd += 1 + Target.size(); // skip the .target component.
+
const char *const *Low = NameTable.begin();
const char *const *High = NameTable.end();
const char *const *LastLow = Low;
diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
index 10e2e410960982..453736912a8c5b 100644
--- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp
+++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
@@ -97,7 +97,8 @@ static const char *const CoroIntrinsics[] = {
#ifndef NDEBUG
static bool isCoroutineIntrinsicName(StringRef Name) {
- return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
+ return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name, "coro") !=
+ -1;
}
#endif
diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp
index 5916a194f76d48..a92ffe3cdeb7ec 100644
--- a/llvm/unittests/IR/IntrinsicsTest.cpp
+++ b/llvm/unittests/IR/IntrinsicsTest.cpp
@@ -31,10 +31,6 @@ using namespace llvm;
namespace {
-static const char *const NameTable1[] = {
- "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
-};
-
class IntrinsicsTest : public ::testing::Test {
LLVMContext Context;
std::unique_ptr<Module> M;
@@ -67,18 +63,24 @@ class IntrinsicsTest : public ::testing::Test {
};
TEST(IntrinsicNameLookup, Basic) {
- int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo");
- EXPECT_EQ(0, I);
- I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64");
- EXPECT_EQ(0, I);
- I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b");
- EXPECT_EQ(2, I);
- I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b.a");
- EXPECT_EQ(3, I);
- I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c");
- EXPECT_EQ(4, I);
- I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c.f64");
- EXPECT_EQ(4, I);
+ static constexpr const char *const NameTable1[] = {
+ "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
+ };
+
+ static constexpr std::pair<const char *, int> Tests[] = {
+ {"llvm.foo", 0}, {"llvm.foo.f64", 0}, {"llvm.foo.b", 2},
+ {"llvm.foo.b.a", 3}, {"llvm.foo.c", 4}, {"llvm.foo.c.f64", 4},
+ {"llvm.bar", -1},
+ };
+
+ for (const auto &[Name, ExpectedIdx] : Tests) {
+ int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name);
+ EXPECT_EQ(ExpectedIdx, Idx);
+ if (!StringRef(Name).starts_with("llvm.foo"))
+ continue;
+ Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name, "foo");
+ EXPECT_EQ(ExpectedIdx, Idx);
+ }
}
// Tests to verify getIntrinsicForClangBuiltin.
More information about the llvm-commits
mailing list