[llvm] [Analysis] Compact vector-library descriptors (PR #202665)
David Zbarsky via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 9 07:02:10 PDT 2026
https://github.com/dzbarsky created https://github.com/llvm/llvm-project/pull/202665
TargetLibraryInfo.cpp stores 1,449 vector-library mappings as VecDesc
objects. VecDesc is 64 bytes, and its non-constexpr constructor also emits a
large pre-main initializer for every mapping.
Store the static mappings as 32-byte VecDescInit records containing three
pointers, compile-time string lengths, a 16-bit vectorization factor and
calling convention, and two flags. Expand only the selected vector library
into the existing VecDesc lookup vectors. The runtime lookup representation
and sorting remain unchanged.
Assert the VecDescInit size, string lengths, vectorization-factor range, and
calling-convention range so the compact representation cannot silently
truncate new data.
TargetLibraryInfo.cpp.o loadable size changes from 234,323 to 110,255 bytes,
saving 124,068 bytes. The change removes 66,100 bytes of text, including
__GLOBAL__sub_I_TargetLibraryInfo.cpp, and 57,968 bytes of data.
In the LLVM 22 Bazel distribution, standalone opt changes from 84,391,120 to
84,374,672 bytes, saving 16,448 bytes (0.02%). The multicall binary changes
from 162,128,720 to 162,112,432 bytes, saving 16,288 bytes (0.01%).
The release-stripped opt changes from 71,538,128 to 71,521,536 bytes, saving
16,592 bytes, and release-stripped multicall changes from 132,174,016 to
132,157,584 bytes, saving 16,432 bytes.
All nine vector-library selections and four representative loop-vectorization
pipelines produced byte-identical LLVM 22 output.
A 40-pair alternating benchmark constructed every vector-library mapping
5,000 times. Mean user CPU changed from 1.0455 to 1.0410 seconds (-0.43%).
The paired median was -0.005 seconds, with a bootstrapped 95% interval of
-0.0150 to +0.00525 seconds.
Work towards #202616
>From 319e7760276c3ce55bc1b08ec6bf77d4647763cd Mon Sep 17 00:00:00 2001
From: David Zbarsky <dzbarsky at gmail.com>
Date: Tue, 9 Jun 2026 03:29:27 -0400
Subject: [PATCH] [Analysis] Compact vector-library descriptors
TargetLibraryInfo.cpp stores 1,449 vector-library mappings as VecDesc
objects. VecDesc is 64 bytes, and its non-constexpr constructor also emits a
large pre-main initializer for every mapping.
Store the static mappings as 32-byte VecDescInit records containing three
pointers, compile-time string lengths, a 16-bit vectorization factor and
calling convention, and two flags. Expand only the selected vector library
into the existing VecDesc lookup vectors. The runtime lookup representation
and sorting remain unchanged.
Assert the VecDescInit size, string lengths, vectorization-factor range, and
calling-convention range so the compact representation cannot silently
truncate new data.
TargetLibraryInfo.cpp.o loadable size changes from 234,323 to 110,255 bytes,
saving 124,068 bytes. The change removes 66,100 bytes of text, including
__GLOBAL__sub_I_TargetLibraryInfo.cpp, and 57,968 bytes of data.
In the LLVM 22 Bazel distribution, standalone opt changes from 84,391,120 to
84,374,672 bytes, saving 16,448 bytes (0.02%). The multicall binary changes
from 162,128,720 to 162,112,432 bytes, saving 16,288 bytes (0.01%).
The release-stripped opt changes from 71,538,128 to 71,521,536 bytes, saving
16,592 bytes, and release-stripped multicall changes from 132,174,016 to
132,157,584 bytes, saving 16,432 bytes.
All nine vector-library selections and four representative loop-vectorization
pipelines produced byte-identical LLVM 22 output.
A 40-pair alternating benchmark constructed every vector-library mapping
5,000 times. Mean user CPU changed from 1.0455 to 1.0410 seconds (-0.43%).
The paired median was -0.005 seconds, with a bootstrapped 95% interval of
-0.0150 to +0.00525 seconds.
---
llvm/lib/Analysis/TargetLibraryInfo.cpp | 109 ++++++++++++++++++------
1 file changed, 85 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 6b8f861392254..0daf38d4a1026 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1243,25 +1243,72 @@ void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {
llvm::sort(ScalarDescs, compareByVectorFnName);
}
-static const VecDesc VecFuncs_Accelerate[] = {
+namespace {
+
+struct VecDescInit {
+ const char *ScalarFnName;
+ const char *VectorFnName;
+ const char *VABIPrefix;
+ uint16_t VectorizationFactor;
+ uint16_t EncodedCC;
+ uint8_t ScalarFnNameSize;
+ uint8_t VectorFnNameSize;
+ uint8_t VABIPrefixSize;
+ uint8_t Flags;
+
+ template <size_t ScalarSize, size_t VectorSize, size_t PrefixSize>
+ constexpr VecDescInit(const char (&ScalarFnName)[ScalarSize],
+ const char (&VectorFnName)[VectorSize],
+ ElementCount VectorizationFactor, bool Masked,
+ const char (&VABIPrefix)[PrefixSize],
+ std::optional<CallingConv::ID> CC)
+ : ScalarFnName(ScalarFnName), VectorFnName(VectorFnName),
+ VABIPrefix(VABIPrefix),
+ VectorizationFactor(VectorizationFactor.getKnownMinValue()),
+ EncodedCC(CC ? *CC + 1 : 0),
+ ScalarFnNameSize(ScalarSize - 1), VectorFnNameSize(VectorSize - 1),
+ VABIPrefixSize(PrefixSize - 1),
+ Flags(VectorizationFactor.isScalable() | (Masked << 1)) {
+ static_assert(ScalarSize - 1 <= UINT8_MAX);
+ static_assert(VectorSize - 1 <= UINT8_MAX);
+ static_assert(PrefixSize - 1 <= UINT8_MAX);
+ assert(VectorizationFactor.getKnownMinValue() <= UINT16_MAX);
+ assert(!CC || *CC <= CallingConv::MaxID);
+ }
+
+ VecDesc expand() const {
+ return {StringRef(ScalarFnName, ScalarFnNameSize),
+ StringRef(VectorFnName, VectorFnNameSize),
+ ElementCount::get(VectorizationFactor, Flags & 1),
+ static_cast<bool>(Flags & 2),
+ StringRef(VABIPrefix, VABIPrefixSize),
+ EncodedCC ? std::optional<CallingConv::ID>(EncodedCC - 1)
+ : std::nullopt};
+ }
+};
+
+static_assert(CallingConv::MaxID < UINT16_MAX);
+static_assert(sizeof(VecDescInit) == 32);
+
+static constexpr VecDescInit VecFuncs_Accelerate[] = {
#define TLI_DEFINE_ACCELERATE_VECFUNCS
#include "llvm/Analysis/VecFuncs.def"
#undef TLI_DEFINE_ACCELERATE_VECFUNCS
};
-static const VecDesc VecFuncs_DarwinLibSystemM[] = {
+static constexpr VecDescInit VecFuncs_DarwinLibSystemM[] = {
#define TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS
#include "llvm/Analysis/VecFuncs.def"
#undef TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS
};
-static const VecDesc VecFuncs_LIBMVEC_X86[] = {
+static constexpr VecDescInit VecFuncs_LIBMVEC_X86[] = {
#define TLI_DEFINE_LIBMVEC_X86_VECFUNCS
#include "llvm/Analysis/VecFuncs.def"
#undef TLI_DEFINE_LIBMVEC_X86_VECFUNCS
};
-static const VecDesc VecFuncs_LIBMVEC_AARCH64[] = {
+static constexpr VecDescInit VecFuncs_LIBMVEC_AARCH64[] = {
#define TLI_DEFINE_LIBMVEC_AARCH64_VECFUNCS
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX, CC) \
{SCAL, VEC, VF, MASK, VABI_PREFIX, CC},
@@ -1269,33 +1316,33 @@ static const VecDesc VecFuncs_LIBMVEC_AARCH64[] = {
#undef TLI_DEFINE_LIBMVEC_AARCH64_VECFUNCS
};
-static const VecDesc VecFuncs_MASSV[] = {
+static constexpr VecDescInit VecFuncs_MASSV[] = {
#define TLI_DEFINE_MASSV_VECFUNCS
#include "llvm/Analysis/VecFuncs.def"
#undef TLI_DEFINE_MASSV_VECFUNCS
};
-static const VecDesc VecFuncs_SVML[] = {
+static constexpr VecDescInit VecFuncs_SVML[] = {
#define TLI_DEFINE_SVML_VECFUNCS
#include "llvm/Analysis/VecFuncs.def"
#undef TLI_DEFINE_SVML_VECFUNCS
};
-static const VecDesc VecFuncs_SLEEFGNUABI_VF2[] = {
+static constexpr VecDescInit VecFuncs_SLEEFGNUABI_VF2[] = {
#define TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \
{SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX, /* CC = */ std::nullopt},
#include "llvm/Analysis/VecFuncs.def"
#undef TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS
};
-static const VecDesc VecFuncs_SLEEFGNUABI_VF4[] = {
+static constexpr VecDescInit VecFuncs_SLEEFGNUABI_VF4[] = {
#define TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \
{SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX, /* CC = */ std::nullopt},
#include "llvm/Analysis/VecFuncs.def"
#undef TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS
};
-static const VecDesc VecFuncs_SLEEFGNUABI_VFScalable[] = {
+static constexpr VecDescInit VecFuncs_SLEEFGNUABI_VFScalable[] = {
#define TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \
{SCAL, VEC, VF, MASK, VABI_PREFIX, /* CC = */ std::nullopt},
@@ -1303,7 +1350,7 @@ static const VecDesc VecFuncs_SLEEFGNUABI_VFScalable[] = {
#undef TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS
};
-static const VecDesc VecFuncs_SLEEFGNUABI_VFScalableRISCV[] = {
+static constexpr VecDescInit VecFuncs_SLEEFGNUABI_VFScalableRISCV[] = {
#define TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS_RISCV
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \
{SCAL, VEC, VF, MASK, VABI_PREFIX, /* CC = */ std::nullopt},
@@ -1311,7 +1358,7 @@ static const VecDesc VecFuncs_SLEEFGNUABI_VFScalableRISCV[] = {
#undef TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS_RISCV
};
-static const VecDesc VecFuncs_ArmPL[] = {
+static constexpr VecDescInit VecFuncs_ArmPL[] = {
#define TLI_DEFINE_ARMPL_VECFUNCS
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX, CC) \
{SCAL, VEC, VF, MASK, VABI_PREFIX, CC},
@@ -1319,7 +1366,7 @@ static const VecDesc VecFuncs_ArmPL[] = {
#undef TLI_DEFINE_ARMPL_VECFUNCS
};
-const VecDesc VecFuncs_AMDLIBM[] = {
+static constexpr VecDescInit VecFuncs_AMDLIBM[] = {
#define TLI_DEFINE_AMDLIBM_VECFUNCS
#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \
{SCAL, VEC, VF, MASK, VABI_PREFIX, /* CC = */ std::nullopt},
@@ -1327,15 +1374,29 @@ const VecDesc VecFuncs_AMDLIBM[] = {
#undef TLI_DEFINE_AMDLIBM_VECFUNCS
};
+} // namespace
+
void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
enum VectorLibrary VecLib, const llvm::Triple &TargetTriple) {
+ auto AddVectorizableFunctions = [this](ArrayRef<VecDescInit> Fns) {
+ VectorDescs.reserve(VectorDescs.size() + Fns.size());
+ ScalarDescs.reserve(ScalarDescs.size() + Fns.size());
+ for (const VecDescInit &Fn : Fns) {
+ VecDesc Expanded = Fn.expand();
+ VectorDescs.push_back(Expanded);
+ ScalarDescs.push_back(Expanded);
+ }
+ llvm::sort(VectorDescs, compareByScalarFnName);
+ llvm::sort(ScalarDescs, compareByVectorFnName);
+ };
+
switch (VecLib) {
case VectorLibrary::Accelerate: {
- addVectorizableFunctions(VecFuncs_Accelerate);
+ AddVectorizableFunctions(VecFuncs_Accelerate);
break;
}
case VectorLibrary::DarwinLibSystemM: {
- addVectorizableFunctions(VecFuncs_DarwinLibSystemM);
+ AddVectorizableFunctions(VecFuncs_DarwinLibSystemM);
break;
}
case VectorLibrary::LIBMVEC: {
@@ -1344,21 +1405,21 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- addVectorizableFunctions(VecFuncs_LIBMVEC_X86);
+ AddVectorizableFunctions(VecFuncs_LIBMVEC_X86);
break;
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- addVectorizableFunctions(VecFuncs_LIBMVEC_AARCH64);
+ AddVectorizableFunctions(VecFuncs_LIBMVEC_AARCH64);
break;
}
break;
}
case VectorLibrary::MASSV: {
- addVectorizableFunctions(VecFuncs_MASSV);
+ AddVectorizableFunctions(VecFuncs_MASSV);
break;
}
case VectorLibrary::SVML: {
- addVectorizableFunctions(VecFuncs_SVML);
+ AddVectorizableFunctions(VecFuncs_SVML);
break;
}
case VectorLibrary::SLEEFGNUABI: {
@@ -1367,12 +1428,12 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
break;
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF2);
- addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF4);
- addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VFScalable);
+ AddVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF2);
+ AddVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF4);
+ AddVectorizableFunctions(VecFuncs_SLEEFGNUABI_VFScalable);
break;
case llvm::Triple::riscv64:
- addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VFScalableRISCV);
+ AddVectorizableFunctions(VecFuncs_SLEEFGNUABI_VFScalableRISCV);
break;
}
break;
@@ -1383,13 +1444,13 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
break;
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- addVectorizableFunctions(VecFuncs_ArmPL);
+ AddVectorizableFunctions(VecFuncs_ArmPL);
break;
}
break;
}
case VectorLibrary::AMDLIBM: {
- addVectorizableFunctions(VecFuncs_AMDLIBM);
+ AddVectorizableFunctions(VecFuncs_AMDLIBM);
break;
}
case VectorLibrary::NoLibrary:
More information about the llvm-commits
mailing list