Skip to content

[TableGen] Rework EmitIntrinsicToBuiltinMap #104681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
set(LLVM_LINK_COMPONENTS
Core
Support)

add_benchmark(DummyYAML DummyYAML.cpp PARTIAL_SOURCES_INTENDED)
add_benchmark(xxhash xxhash.cpp PARTIAL_SOURCES_INTENDED)
add_benchmark(GetIntrinsicForClangBuiltin GetIntrinsicForClangBuiltin.cpp PARTIAL_SOURCES_INTENDED)
50 changes: 50 additions & 0 deletions llvm/benchmarks/GetIntrinsicForClangBuiltin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "benchmark/benchmark.h"
#include "llvm/IR/Intrinsics.h"

using namespace llvm;
using namespace Intrinsic;

// Benchmark intrinsic lookup from a variety of targets.
static void BM_GetIntrinsicForClangBuiltin(benchmark::State &state) {
static const char *Builtins[] = {
"__builtin_adjust_trampoline",
"__builtin_trap",
"__builtin_arm_ttest",
"__builtin_amdgcn_cubetc",
"__builtin_amdgcn_udot2",
"__builtin_arm_stc",
"__builtin_bpf_compare",
"__builtin_HEXAGON_A2_max",
"__builtin_lasx_xvabsd_b",
"__builtin_mips_dlsa",
"__nvvm_floor_f",
"__builtin_altivec_vslb",
"__builtin_r600_read_tgid_x",
"__builtin_riscv_aes64im",
"__builtin_s390_vcksm",
"__builtin_ve_vl_pvfmksge_Mvl",
"__builtin_ia32_axor64",
"__builtin_bitrev",
};
static const char *Targets[] = {"", "aarch64", "amdgcn", "mips",
"nvvm", "r600", "riscv"};

for (auto _ : state) {
for (auto Builtin : Builtins)
for (auto Target : Targets)
getIntrinsicForClangBuiltin(Target, Builtin);
}
}

static void
BM_GetIntrinsicForClangBuiltinHexagonFirst(benchmark::State &state) {
// Exercise the worst case by looking for the first builtin for a target
// that has a lot of builtins.
for (auto _ : state)
getIntrinsicForClangBuiltin("hexagon", "__builtin_HEXAGON_A2_abs");
}

BENCHMARK(BM_GetIntrinsicForClangBuiltin);
BENCHMARK(BM_GetIntrinsicForClangBuiltinHexagonFirst);

BENCHMARK_MAIN();
4 changes: 2 additions & 2 deletions llvm/include/llvm/IR/Intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ namespace Intrinsic {
StringRef Name);

/// Map a Clang builtin name to an intrinsic ID.
ID getIntrinsicForClangBuiltin(const char *Prefix, StringRef BuiltinName);
ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, StringRef BuiltinName);

/// Map a MS builtin name to an intrinsic ID.
ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName);
ID getIntrinsicForMSBuiltin(StringRef TargetPrefix, StringRef BuiltinName);

/// Returns true if the intrinsic ID is for one of the "Constrained
/// Floating-Point Intrinsics".
Expand Down
13 changes: 12 additions & 1 deletion llvm/include/llvm/TableGen/StringToOffsetTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <optional>

namespace llvm {

Expand All @@ -26,7 +27,8 @@ class StringToOffsetTable {
std::string AggregateString;

public:
bool Empty() const { return StringOffset.empty(); }
bool empty() const { return StringOffset.empty(); }
size_t size() const { return AggregateString.size(); }

unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) {
auto IterBool =
Expand All @@ -41,6 +43,15 @@ class StringToOffsetTable {
return IterBool.first->second;
}

// Returns the offset of `Str` in the table if its preset, else return
// std::nullopt.
std::optional<unsigned> GetStringOffset(StringRef Str) const {
auto II = StringOffset.find(Str);
if (II == StringOffset.end())
return std::nullopt;
return II->second;
}

void EmitString(raw_ostream &O) {
// Escape the string.
SmallString<256> Str;
Expand Down
59 changes: 59 additions & 0 deletions llvm/unittests/IR/IntrinsicsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@
#include "llvm/IR/Constant.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsBPF.h"
#include "llvm/IR/IntrinsicsDirectX.h"
#include "llvm/IR/IntrinsicsHexagon.h"
#include "llvm/IR/IntrinsicsLoongArch.h"
#include "llvm/IR/IntrinsicsMips.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsS390.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/Module.h"
#include "gtest/gtest.h"

Expand Down Expand Up @@ -68,6 +81,51 @@ TEST(IntrinsicNameLookup, Basic) {
EXPECT_EQ(4, I);
}

// Tests to verify getIntrinsicForClangBuiltin.
TEST(IntrinsicNameLookup, ClangBuiltinLookup) {
using namespace Intrinsic;
static constexpr std::tuple<StringRef, StringRef, ID> ClangTests[] = {
{"__builtin_adjust_trampoline", "", adjust_trampoline},
{"__builtin_trap", "", trap},
{"__builtin_arm_chkfeat", "aarch64", aarch64_chkfeat},
{"__builtin_amdgcn_alignbyte", "amdgcn", amdgcn_alignbyte},
{"__builtin_amdgcn_workgroup_id_z", "amdgcn", amdgcn_workgroup_id_z},
{"__builtin_arm_cdp", "arm", arm_cdp},
{"__builtin_bpf_preserve_type_info", "bpf", bpf_preserve_type_info},
{"__builtin_hlsl_create_handle", "dx", dx_create_handle},
{"__builtin_HEXAGON_A2_tfr", "hexagon", hexagon_A2_tfr},
{"__builtin_lasx_xbz_w", "loongarch", loongarch_lasx_xbz_w},
{"__builtin_mips_bitrev", "mips", mips_bitrev},
{"__nvvm_add_rn_d", "nvvm", nvvm_add_rn_d},
{"__builtin_altivec_dss", "ppc", ppc_altivec_dss},
{"__builtin_riscv_sha512sum1r", "riscv", riscv_sha512sum1r},
{"__builtin_tend", "s390", s390_tend},
{"__builtin_ia32_pause", "x86", x86_sse2_pause},

{"__does_not_exist", "", not_intrinsic},
{"__does_not_exist", "arm", not_intrinsic},
{"__builtin_arm_cdp", "", not_intrinsic},
{"__builtin_arm_cdp", "x86", not_intrinsic},
};

for (const auto &[Builtin, Target, ID] : ClangTests)
EXPECT_EQ(ID, getIntrinsicForClangBuiltin(Target, Builtin));
}

// Tests to verify getIntrinsicForMSBuiltin.
TEST(IntrinsicNameLookup, MSBuiltinLookup) {
using namespace Intrinsic;
static constexpr std::tuple<StringRef, StringRef, ID> MSTests[] = {
{"__dmb", "aarch64", aarch64_dmb},
{"__dmb", "arm", arm_dmb},
{"__dmb", "", not_intrinsic},
{"__does_not_exist", "", not_intrinsic},
{"__does_not_exist", "arm", not_intrinsic},
};
for (const auto &[Builtin, Target, ID] : MSTests)
EXPECT_EQ(ID, getIntrinsicForMSBuiltin(Target, Builtin));
}

TEST_F(IntrinsicsTest, InstrProfInheritance) {
auto isInstrProfInstBase = [](const Instruction &I) {
return isa<InstrProfInstBase>(I);
Expand Down Expand Up @@ -106,4 +164,5 @@ TEST_F(IntrinsicsTest, InstrProfInheritance) {
EXPECT_TRUE(Checker(*Intr));
}
}

} // end namespace
Loading
Loading