[llvm] [IntrinsicEmitter] Make AttributesMap PackedID type-adaptive (PR #158383)

Elvin Wang via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 18 14:47:24 PDT 2025


https://github.com/elvinw-intel updated https://github.com/llvm/llvm-project/pull/158383

>From 9f04195a805f12654452c691889d3a84269a1973 Mon Sep 17 00:00:00 2001
From: "Wang, Elvin" <elvin.wang at intel.com>
Date: Fri, 12 Sep 2025 16:03:24 -0700
Subject: [PATCH] [IntrinsicEmitter] Make AttributesMap PackedID type-adaptive

Following up #157965 which made this bit-adaptive, this patch attempts
to make this map able to choose type ranging from int8 to int64 based on
intrinsic inputs.
---
 llvm/test/TableGen/intrinsic-attrs.td         |  2 +-
 .../utils/TableGen/Basic/IntrinsicEmitter.cpp | 53 +++++++++++--------
 2 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/llvm/test/TableGen/intrinsic-attrs.td b/llvm/test/TableGen/intrinsic-attrs.td
index fbcc6aa0e9bf1..dcb3800cf91c7 100644
--- a/llvm/test/TableGen/intrinsic-attrs.td
+++ b/llvm/test/TableGen/intrinsic-attrs.td
@@ -24,7 +24,7 @@ def int_deref_ptr_ret : Intrinsic<[llvm_ptr_ty], [], [Dereferenceable<RetIndex,
 // CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
 // CHECK-NEXT: });
 
-// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
+// CHECK: static constexpr uint8_t IntrinsicsToAttributesMap[] = {
 // CHECK: 0 << 1 | 0, // llvm.deref.ptr.ret
 // CHECK: 1 << 1 | 1, // llvm.random.gen
 // CHECK: }; // IntrinsicsToAttributesMap
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index a597edb399464..d8dd368d58b9b 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -617,9 +617,7 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
   }
   OS << R"(
   }
-} // getIntrinsicFnAttributeSet
-
-static constexpr uint16_t IntrinsicsToAttributesMap[] = {)";
+} // getIntrinsicFnAttributeSet)";
 
   // Compute unique argument attributes.
   std::map<const CodeGenIntrinsic *, unsigned, AttributeComparator>
@@ -630,20 +628,29 @@ static constexpr uint16_t IntrinsicsToAttributesMap[] = {)";
   }
 
   const uint8_t UniqAttributesBitSize = Log2_32_Ceil(UniqAttributes.size());
-  // Note, ID `-1` is used to indicate no function attributes.
+  // Note, max value is used to indicate no function attributes.
   const uint8_t UniqFnAttributesBitSize =
       Log2_32_Ceil(UniqFnAttributes.size() + 1);
-  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
+  const uint32_t NoFunctionAttrsID =
+      maskTrailingOnes<uint32_t>(UniqFnAttributesBitSize);
+  uint8_t AttributesMapDataBitSize =
+      PowerOf2Ceil(UniqAttributesBitSize + UniqFnAttributesBitSize);
+  if (AttributesMapDataBitSize < 8)
+    AttributesMapDataBitSize = 8;
+  else if (AttributesMapDataBitSize > 64)
+    PrintFatalError("Packed ID of IntrinsicsToAttributesMap exceeds 64b!");
+  else if (AttributesMapDataBitSize > 16)
+    PrintWarning("Packed ID of IntrinsicsToAttributesMap exceeds 16b, "
+                 "this may cause performance drop (pr106809), "
+                 "please consider redesigning intrinsic sets!");
+
+  // Assign a 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).
+  OS << formatv("\nstatic constexpr uint{}_t IntrinsicsToAttributesMap[] = {{",
+                AttributesMapDataBitSize);
   for (const CodeGenIntrinsic &Int : Ints) {
-    uint16_t FnAttrIndex =
+    uint32_t FnAttrIndex =
         hasFnAttributes(Int) ? UniqFnAttributes[&Int] : NoFunctionAttrsID;
     OS << formatv("\n    {} << {} | {}, // {}", FnAttrIndex,
                   UniqAttributesBitSize, UniqAttributes[&Int], Int.Name);
@@ -746,14 +753,19 @@ static constexpr ArgAttributesInfo ArgAttributesInfoTable[] = {{
   // construct all the argument attributes (using the ArgAttributesInfoTable and
   // ArgAttrIdTable) and then add on the function attributes if any.
   OS << formatv(R"(
+
+template <typename IDTy>
+inline std::pair<uint32_t, uint32_t> unpackID(IDTy PackedID) {{
+  uint32_t FnAttrID = PackedID >> ({});
+  uint32_t ArgAttrID = PackedID & ({});
+  return {{FnAttrID, ArgAttrID};
+}
+
 AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id,
                                        FunctionType *FT) {{
   if (id == 0)
     return AttributeList();
-
-  uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
-  uint16_t FnAttrID = PackedID >> ({});
-  uint16_t ArgAttrID = PackedID & ({});
+  auto [FnAttrID, ArgAttrID] = unpackID(IntrinsicsToAttributesMap[id - 1]);
   using PairTy = std::pair<unsigned, AttributeSet>;
   alignas(PairTy) char ASStorage[sizeof(PairTy) * {}];
   PairTy *AS = reinterpret_cast<PairTy *>(ASStorage);
@@ -776,19 +788,18 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id,
   return AttributeList::get(C, ArrayRef(AS, NumAttrs));
 }
 
-AttributeSet Intrinsic::getFnAttributes(LLVMContext &C, ID id) {
+AttributeSet Intrinsic::getFnAttributes(LLVMContext &C, ID id) {{
   if (id == 0)
     return AttributeSet();
-  uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
-  uint16_t FnAttrID = PackedID >> ({});
+  auto [FnAttrID, ArgAttrID] = unpackID(IntrinsicsToAttributesMap[id - 1]);
   return getIntrinsicFnAttributeSet(C, FnAttrID);
 }
 #endif // GET_INTRINSIC_ATTRIBUTES
 
 )",
                 UniqAttributesBitSize,
-                maskTrailingOnes<uint16_t>(UniqAttributesBitSize), MaxNumAttrs,
-                NoFunctionAttrsID, UniqAttributesBitSize);
+                maskTrailingOnes<uint32_t>(UniqAttributesBitSize),
+                MaxNumAttrs, NoFunctionAttrsID);
 }
 
 void IntrinsicEmitter::EmitIntrinsicToBuiltinMap(



More information about the llvm-commits mailing list