From f0c374c169826c88d631f0f4b4f64ff7228e6cbc Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 12 Aug 2025 21:08:47 +0900 Subject: [PATCH] RuntimeLibcalls: Generate table of libcall name lengths Avoids strlen when constructing the returned StringRef. We were emitting these in the libcall name lookup anyway, so split out the offsets for general use. Currently emitted as a separate table, not sure if it would be better to change the string offset table to store pairs of offset and width instead. --- llvm/include/llvm/IR/RuntimeLibcalls.h | 5 +++- llvm/test/TableGen/RuntimeLibcallEmitter.td | 23 ++++++++++++---- .../TableGen/Basic/RuntimeLibcallsEmitter.cpp | 27 ++++++++++++------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index 620774fd296e3..308be543de2bd 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -85,7 +85,9 @@ struct RuntimeLibcallsInfo { static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl) { if (CallImpl == RTLIB::Unsupported) return StringRef(); - return RuntimeLibcallImplNameTable[RuntimeLibcallNameOffsetTable[CallImpl]]; + return StringRef(RuntimeLibcallImplNameTable.getCString( + RuntimeLibcallNameOffsetTable[CallImpl]), + RuntimeLibcallNameSizeTable[CallImpl]); } /// Return the lowering's selection of implementation call for \p Call @@ -182,6 +184,7 @@ struct RuntimeLibcallsInfo { LLVM_ABI static const char RuntimeLibcallImplNameTableStorage[]; LLVM_ABI static const StringTable RuntimeLibcallImplNameTable; LLVM_ABI static const uint16_t RuntimeLibcallNameOffsetTable[]; + LLVM_ABI static const uint8_t RuntimeLibcallNameSizeTable[]; /// Map from a concrete LibcallImpl implementation to its RTLIB::Libcall kind. LLVM_ABI static const RTLIB::Libcall ImplToLibcall[RTLIB::NumLibcallImpls]; diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td index 54ca3f97e2d4b..7c62402227f7d 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td @@ -137,6 +137,19 @@ def BlahLibrary : SystemRuntimeLibrary RTLIB::RuntimeLibcallsInfo::lookupLibcallImplNameImpl(StringRef Name) { -// CHECK: static constexpr std::pair HashTableNameToEnum[16] = { -// CHECK: {2, 9}, // 0x000000705301b8, ___memset -// CHECK: {0, 0}, -// CHECK: {6, 6}, // 0x0000001417a2af, calloc -// CHECK: {0, 0}, +// CHECK: static constexpr uint16_t HashTableNameToEnum[16] = { +// CHECK: 2, // 0x000000705301b8, ___memset +// CHECK: 0, +// CHECK: 6, // 0x0000001417a2af, calloc +// CHECK: 0, // CHECK: }; // CHECK: unsigned Idx = (hash(Name) % 8) * 2; diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp index 775cef22db0b6..c305e6323ca9d 100644 --- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp +++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp @@ -459,17 +459,14 @@ void RuntimeLibcallEmitter::emitNameMatchHashTable( OS << "iota_range RTLIB::RuntimeLibcallsInfo::" "lookupLibcallImplNameImpl(StringRef Name) {\n"; - // Emit pair of RTLIB::LibcallImpl, size of the string name. It's important to - // avoid strlen on the string table entries. - OS << " static constexpr std::pair HashTableNameToEnum[" - << Lookup.size() << "] = {\n"; + // Emit RTLIB::LibcallImpl values + OS << " static constexpr uint16_t HashTableNameToEnum[" << Lookup.size() + << "] = {\n"; for (auto [FuncName, Hash, TableVal] : Lookup) { - OS << " {" << TableVal << ", " << FuncName.size() << "},"; - - if (TableVal != 0) { + OS << " " << TableVal << ','; + if (TableVal != 0) OS << " // " << format_hex(Hash, 16) << ", " << FuncName; - } OS << '\n'; } @@ -480,11 +477,12 @@ void RuntimeLibcallEmitter::emitNameMatchHashTable( << ";\n\n" " for (int I = 0; I != " << Collisions << R"(; ++I) { - auto [Entry, StringSize] = HashTableNameToEnum[Idx + I]; + const uint16_t Entry = HashTableNameToEnum[Idx + I]; const uint16_t StrOffset = RuntimeLibcallNameOffsetTable[Entry]; + const uint8_t StrSize = RuntimeLibcallNameSizeTable[Entry]; StringRef Str( &RTLIB::RuntimeLibcallsInfo::RuntimeLibcallImplNameTableStorage[StrOffset], - StringSize); + StrSize); if (Str == Name) return libcallImplNameHit(Entry, StrOffset); } @@ -520,6 +518,15 @@ const uint16_t RTLIB::RuntimeLibcallsInfo::RuntimeLibcallNameOffsetTable[] = { } OS << "};\n"; + OS << R"( +const uint8_t RTLIB::RuntimeLibcallsInfo::RuntimeLibcallNameSizeTable[] = { +)"; + + OS << " 0,\n"; + for (const RuntimeLibcallImpl &LibCallImpl : RuntimeLibcallImplDefList) + OS << " " << LibCallImpl.getLibcallFuncName().size() << ",\n"; + OS << "};\n\n"; + // Emit the reverse mapping from implementation libraries to RTLIB::Libcall OS << "const RTLIB::Libcall llvm::RTLIB::RuntimeLibcallsInfo::" "ImplToLibcall[RTLIB::NumLibcallImpls] = {\n"