[llvm] [CodeGen] Compact cost table entries (PR #202836)

David Zbarsky via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 20:00:42 PDT 2026


https://github.com/dzbarsky created https://github.com/llvm/llvm-project/pull/202836

Store cost table operation numbers in `uint16_t` fields and MVT numbers in `uint8_t` fields. Aggregate initialization rejects out-of-range entries at compile time, while lookup remains direct scalar comparison; layout assertions cover the common and X86 entry types.

A native AArch64 Release `opt` shrinks by 54,080 bytes, with `__TEXT` down 32,768 bytes and chained fixups unchanged.

All five direct target consumers compile, all 108 AArch64 cost-model tests pass, oversized initializer checks fail as intended, and a mixed hit/miss lookup benchmark found no measurable regression.

Work towards #202616

AI tool disclosure: Co-authored with OpenAI Codex.


>From 9ace56e3a113ea95f5b3bf6dda8c4d344d28cf6c Mon Sep 17 00:00:00 2001
From: David Zbarsky <dzbarsky at gmail.com>
Date: Tue, 9 Jun 2026 22:59:44 -0400
Subject: [PATCH] [CodeGen] Compact cost table entries

Store cost table operation numbers in uint16_t fields and MVT numbers in uint8_t fields. Cost tables use aggregate initialization, so an entry outside either range is rejected as a narrowing conversion. Keep the lookup as direct scalar comparisons and add layout assertions for the common and X86 cost types.

Across the X86, AArch64, ARM, RISCV, and WebAssembly target transform objects, this removes 15,168 bytes, including 15,424 bytes from __const. A native AArch64 Release opt shrinks by 54,080 bytes, with __TEXT down 32,768 bytes and chained fixups unchanged.

A mixed hit/miss 128-entry lookup benchmark showed median changes of -0.2% for CostTableLookup and -0.3% for ConvertCostTableLookup, within roughly +/-3% run-to-run noise. All five direct consumers compile, all 108 AArch64 cost-model tests pass, and explicit oversized operation and MVT initializers fail compilation.
---
 llvm/include/llvm/CodeGen/CostTable.h         | 31 ++++++++++++-------
 .../lib/Target/X86/X86TargetTransformInfo.cpp |  2 ++
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/CostTable.h b/llvm/include/llvm/CodeGen/CostTable.h
index 490de79d18997..48c8bf4adc6d8 100644
--- a/llvm/include/llvm/CodeGen/CostTable.h
+++ b/llvm/include/llvm/CodeGen/CostTable.h
@@ -17,24 +17,29 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGenTypes/MachineValueType.h"
+#include <cstdint>
 
 namespace llvm {
 
 /// Cost Table Entry
-template <typename CostType>
-struct CostTblEntryT {
-  int ISD;
-  MVT::SimpleValueType Type;
+template <typename CostType> struct CostTblEntryT {
+  // Cost tables use aggregate initialization, so values that do not fit in
+  // these fields are rejected as narrowing conversions at compile time.
+  uint16_t ISD;
+  uint8_t Type;
   CostType Cost;
 };
 using CostTblEntry = CostTblEntryT<unsigned>;
+static_assert(sizeof(CostTblEntry) == 8);
+static_assert(sizeof(CostTblEntry::ISD) == 2);
+static_assert(sizeof(CostTblEntry::Type) == 1);
 
 /// Find in cost table.
 template <class CostType>
 inline const CostTblEntryT<CostType> *
 CostTableLookup(ArrayRef<CostTblEntryT<CostType>> Tbl, int ISD, MVT Ty) {
   auto I = find_if(Tbl, [=](const CostTblEntryT<CostType> &Entry) {
-    return ISD == Entry.ISD && Ty == Entry.Type;
+    return ISD == Entry.ISD && Ty.SimpleTy == Entry.Type;
   });
   if (I != Tbl.end())
     return I;
@@ -51,14 +56,17 @@ CostTableLookup(const CostTblEntryT<CostType> (&Table)[N], int ISD, MVT Ty) {
 }
 
 /// Type Conversion Cost Table
-template <typename CostType>
-struct TypeConversionCostTblEntryT {
-  int ISD;
-  MVT::SimpleValueType Dst;
-  MVT::SimpleValueType Src;
+template <typename CostType> struct TypeConversionCostTblEntryT {
+  uint16_t ISD;
+  uint8_t Dst;
+  uint8_t Src;
   CostType Cost;
 };
 using TypeConversionCostTblEntry = TypeConversionCostTblEntryT<unsigned>;
+static_assert(sizeof(TypeConversionCostTblEntry) == 8);
+static_assert(sizeof(TypeConversionCostTblEntry::ISD) == 2);
+static_assert(sizeof(TypeConversionCostTblEntry::Dst) == 1);
+static_assert(sizeof(TypeConversionCostTblEntry::Src) == 1);
 
 /// Find in type conversion cost table.
 template <class CostType>
@@ -67,7 +75,8 @@ ConvertCostTableLookup(ArrayRef<TypeConversionCostTblEntryT<CostType>> Tbl,
                        int ISD, MVT Dst, MVT Src) {
   auto I =
       find_if(Tbl, [=](const TypeConversionCostTblEntryT<CostType> &Entry) {
-        return ISD == Entry.ISD && Src == Entry.Src && Dst == Entry.Dst;
+        return ISD == Entry.ISD && Src.SimpleTy == Entry.Src &&
+               Dst.SimpleTy == Entry.Dst;
       });
   if (I != Tbl.end())
     return I;
diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
index 0e9d8679ca9ec..f3a6992d49c5e 100644
--- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
+++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
@@ -100,6 +100,8 @@ struct CostKindCosts {
 };
 using CostKindTblEntry = CostTblEntryT<CostKindCosts>;
 using TypeConversionCostKindTblEntry = TypeConversionCostTblEntryT<CostKindCosts>;
+static_assert(sizeof(CostKindTblEntry) == 20);
+static_assert(sizeof(TypeConversionCostKindTblEntry) == 20);
 
 TargetTransformInfo::PopcntSupportKind
 X86TTIImpl::getPopcntSupport(unsigned TyWidth) const {



More information about the llvm-commits mailing list