[llvm] [IntrinsicEmitter] Make AttributesMap bits adaptive (PR #157965)
Elvin Wang via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 11:53:14 PDT 2025
https://github.com/elvinw-intel updated https://github.com/llvm/llvm-project/pull/157965
>From d45c1a1a5a2a506633e60a9630d5f4c79a4be7da Mon Sep 17 00:00:00 2001
From: "Wang, Elvin" <elvin.wang at intel.com>
Date: Tue, 9 Sep 2025 16:52:38 -0700
Subject: [PATCH] [IntrinsicEmitter] Make AttributesMap bits adaptive
Make IntrinsicsToAttributesMap's func. and arg. fields be able to have
adaptive sizes based on input other than hardcodded 8bits/8bits.
This will ease the pressure for adding new intrinsics in private
downstreams.
---
llvm/lib/IR/Intrinsics.cpp | 8 ----
llvm/test/TableGen/intrinsic-attrs.td | 4 +-
.../utils/TableGen/Basic/IntrinsicEmitter.cpp | 41 ++++++++++++-------
3 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index 58a1f745a7122..4d2e8fadff4f7 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -740,14 +740,6 @@ Intrinsic::ID Intrinsic::lookupIntrinsicID(StringRef Name) {
#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_ATTRIBUTES
-AttributeSet Intrinsic::getFnAttributes(LLVMContext &C, ID id) {
- if (id == 0)
- return AttributeSet();
- uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
- uint8_t FnAttrID = PackedID >> 8;
- return getIntrinsicFnAttributeSet(C, FnAttrID);
-}
-
Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
ArrayRef<Type *> Tys) {
// There can never be multiple globals with the same name of different types,
diff --git a/llvm/test/TableGen/intrinsic-attrs.td b/llvm/test/TableGen/intrinsic-attrs.td
index bcded0cd2e9f1..ab808445f40a2 100644
--- a/llvm/test/TableGen/intrinsic-attrs.td
+++ b/llvm/test/TableGen/intrinsic-attrs.td
@@ -25,8 +25,8 @@ def int_deref_ptr_ret : Intrinsic<[llvm_ptr_ty], [], [Dereferenceable<RetIndex,
// CHECK-NEXT: });
// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
-// CHECK: 0 << 8 | 0, // llvm.deref.ptr.ret
-// CHECK: 1 << 8 | 1, // llvm.random.gen
+// CHECK: 0 << 2 | 0, // llvm.deref.ptr.ret
+// CHECK: 1 << 2 | 1, // llvm.random.gen
// CHECK: }; // IntrinsicsToAttributesMap
// CHECK: static constexpr ArgNoAttrIDPair ArgAttrIdTable[] = {
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index 09d29b8522f54..a702838afe463 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -629,21 +629,24 @@ static constexpr uint16_t IntrinsicsToAttributesMap[] = {)";
UniqAttributes.try_emplace(&Int, ID);
}
- constexpr uint16_t NoFunctionAttrsID = 255;
- if (UniqAttributes.size() > 256)
- PrintFatalError("Too many unique argument attributes for table!");
- // Note, ID 255 is used to indicate no function attributes.
- if (UniqFnAttributes.size() > 255)
- PrintFatalError("Too many unique function attributes for table!");
-
- // Assign a 16-bit packed ID for each intrinsic. The lower 8-bits will be its
- // "argument attribute ID" (index in UniqAttributes) and upper 8 bits will be
+ const uint8_t UniqAttributesBitSize = Log2_32_Ceil(UniqAttributes.size() + 1);
+ // Note, ID `-1` is used to indicate no function attributes.
+ const uint8_t UniqFnAttributesBitSize =
+ Log2_32_Ceil(UniqFnAttributes.size() + 2);
+ const uint16_t NoFunctionAttrsID =
+ maskTrailingOnes<uint16_t>(UniqFnAttributesBitSize);
+ if (UniqAttributesBitSize + UniqFnAttributesBitSize > 16)
+ PrintFatalError(
+ "More than 16 bits are used for IntrinsicsToAttributesMap's entry!");
+
+ // Assign a 16-bit packed ID for each intrinsic. The lower bits will be its
+ // "argument attribute ID" (index in UniqAttributes) and upper bits will be
// its "function attribute ID" (index in UniqFnAttributes).
for (const CodeGenIntrinsic &Int : Ints) {
uint16_t FnAttrIndex =
hasFnAttributes(Int) ? UniqFnAttributes[&Int] : NoFunctionAttrsID;
- OS << formatv("\n {} << 8 | {}, // {}", FnAttrIndex,
- UniqAttributes[&Int], Int.Name);
+ OS << formatv("\n {} << {} | {}, // {}", FnAttrIndex,
+ UniqAttributesBitSize, UniqAttributes[&Int], Int.Name);
}
OS << R"(
@@ -749,8 +752,8 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id,
return AttributeList();
uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
- uint8_t FnAttrID = PackedID >> 8;
- uint8_t ArgAttrID = PackedID & 0xFF;
+ uint16_t FnAttrID = PackedID >> ({});
+ uint16_t ArgAttrID = PackedID & ({});
using PairTy = std::pair<unsigned, AttributeSet>;
alignas(PairTy) char ASStorage[sizeof(PairTy) * {}];
PairTy *AS = reinterpret_cast<PairTy *>(ASStorage);
@@ -772,10 +775,20 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id,
}
return AttributeList::get(C, ArrayRef(AS, NumAttrs));
}
+
+AttributeSet Intrinsic::getFnAttributes(LLVMContext &C, ID id) {
+ if (id == 0)
+ return AttributeSet();
+ uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
+ uint16_t FnAttrID = PackedID >> ({});
+ return getIntrinsicFnAttributeSet(C, FnAttrID);
+}
#endif // GET_INTRINSIC_ATTRIBUTES
)",
- MaxNumAttrs, NoFunctionAttrsID);
+ UniqAttributesBitSize,
+ maskTrailingOnes<uint16_t>(UniqAttributesBitSize), MaxNumAttrs,
+ NoFunctionAttrsID, UniqAttributesBitSize);
}
void IntrinsicEmitter::EmitIntrinsicToBuiltinMap(
More information about the llvm-commits
mailing list