Author: David Zbarsky Date: 2026-06-17T17:53:37+01:00 New Revision: d4b22fba2cedf7d6d7ce332837129a857f987a77
URL: https://github.com/llvm/llvm-project/commit/d4b22fba2cedf7d6d7ce332837129a857f987a77 DIFF: https://github.com/llvm/llvm-project/commit/d4b22fba2cedf7d6d7ce332837129a857f987a77.diff LOG: [AArch64] Compact scalable-vector intrinsic maps (#202618) SVE and SME code generation only reads BuiltinID, LLVMIntrinsic, and TypeModifier from its generated intrinsic maps. Store those fields in a 16-byte ARMScalableVectorIntrinsicInfo instead of the 32-byte ARMVectorIntrinsicInfo used by NEON and SISD code generation. Update both the classic and CIR consumers. On an LLVM 22.1.7 arm64 release build, stripped standalone clang shrinks from 115,097,192 to 114,816,456 bytes, saving 280,736 bytes (0.244%). Work towards #202616 AI tool disclosure: Co-authored with OpenAI Codex. Added: Modified: clang/include/clang/Basic/AArch64CodeGenUtils.h clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp clang/lib/CodeGen/TargetBuiltins/ARM.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/AArch64CodeGenUtils.h b/clang/include/clang/Basic/AArch64CodeGenUtils.h index 3b9145920bd5f..d6a4df66ad232 100644 --- a/clang/include/clang/Basic/AArch64CodeGenUtils.h +++ b/clang/include/clang/Basic/AArch64CodeGenUtils.h @@ -49,7 +49,14 @@ enum { AddRetType | VectorizeRetType | Add1ArgType | InventFloatType }; -struct ARMVectorIntrinsicInfo { +/// Describes an ARM or AArch64 NEON intrinsic, or an AArch64 SISD intrinsic. +/// +/// NEON and SISD code generation use NameHint and AltLLVMIntrinsic in addition +/// to BuiltinID, LLVMIntrinsic, and TypeModifier. SVE and SME code generation +/// does not use those fields, so AArch64SVEAndSMEVectorIntrinsicInfo omits +/// them. On 64-bit hosts, the separate structure reduces each SVE and SME map +/// entry from 32 to 16 bytes and avoids storing a name pointer for each entry. +struct ARMNeonVectorIntrinsicInfo { const char *NameHint; unsigned BuiltinID; unsigned LLVMIntrinsic; @@ -59,11 +66,32 @@ struct ARMVectorIntrinsicInfo { bool operator<(unsigned RHSBuiltinID) const { return BuiltinID < RHSBuiltinID; } - bool operator<(const ARMVectorIntrinsicInfo &TE) const { + bool operator<(const ARMNeonVectorIntrinsicInfo &TE) const { return BuiltinID < TE.BuiltinID; } }; +static_assert(sizeof(ARMNeonVectorIntrinsicInfo) == 16 + 2 * sizeof(void *)); + +/// Describes an AArch64 SVE or SME intrinsic. +/// +/// See ARMNeonVectorIntrinsicInfo for the reason that SVE and SME use a +/// separate structure. +struct AArch64SVEAndSMEVectorIntrinsicInfo { + unsigned BuiltinID; + unsigned LLVMIntrinsic; + uint64_t TypeModifier; + + bool operator<(unsigned RHSBuiltinID) const { + return BuiltinID < RHSBuiltinID; + } + bool operator<(const AArch64SVEAndSMEVectorIntrinsicInfo &TE) const { + return BuiltinID < TE.BuiltinID; + } +}; + +static_assert(sizeof(AArch64SVEAndSMEVectorIntrinsicInfo) == 16); + #define NEONMAP0(NameBase) \ {#NameBase, NEON::BI__builtin_neon_##NameBase, 0, 0, 0} @@ -77,7 +105,7 @@ struct ARMVectorIntrinsicInfo { TypeModifier} // clang-format off -const inline ARMVectorIntrinsicInfo AArch64SIMDIntrinsicMap [] = { +const inline ARMNeonVectorIntrinsicInfo AArch64SIMDIntrinsicMap [] = { NEONMAP0(splat_lane_v), NEONMAP0(splat_laneq_v), NEONMAP0(splatq_lane_v), @@ -373,7 +401,7 @@ const inline ARMVectorIntrinsicInfo AArch64SIMDIntrinsicMap [] = { // // TODO: Either rename this table to better reflect its contents, or // restrict it to true SISD intrinsics only. -const inline ARMVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = { +const inline ARMNeonVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = { NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType), NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType), NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType), diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 2a7ba08f3f135..b52e978fa0f4d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -45,12 +45,11 @@ static mlir::Value genVscaleTimesFactor(mlir::Location loc, } #define SVEMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ - {#NameBase, SVE::BI__builtin_sve_##NameBase, Intrinsic::LLVMIntrinsic, 0, \ - TypeModifier} + {SVE::BI__builtin_sve_##NameBase, Intrinsic::LLVMIntrinsic, TypeModifier} #define SVEMAP2(NameBase, TypeModifier) \ - {#NameBase, SVE::BI__builtin_sve_##NameBase, 0, 0, TypeModifier} -static const ARMVectorIntrinsicInfo aarch64SVEIntrinsicMap[] = { + {SVE::BI__builtin_sve_##NameBase, 0, TypeModifier} +static const AArch64SVEAndSMEVectorIntrinsicInfo aarch64SVEIntrinsicMap[] = { #define GET_SVE_LLVM_INTRINSIC_MAP #include "clang/Basic/arm_sve_builtin_cg.inc" #undef GET_SVE_LLVM_INTRINSIC_MAP @@ -62,8 +61,9 @@ static bool aarch64SVEIntrinsicsProvenSorted = false; // Check if Builtin `builtinId` is present in `intrinsicMap`. If yes, returns // the corresponding info struct. -static const ARMVectorIntrinsicInfo * -findARMVectorIntrinsicInMap(ArrayRef<ARMVectorIntrinsicInfo> intrinsicMap, +template <typename IntrinsicInfo> +static const IntrinsicInfo * +findARMVectorIntrinsicInMap(ArrayRef<IntrinsicInfo> intrinsicMap, unsigned builtinID, bool &mapProvenSorted) { #ifndef NDEBUG @@ -73,8 +73,7 @@ findARMVectorIntrinsicInMap(ArrayRef<ARMVectorIntrinsicInfo> intrinsicMap, } #endif - const ARMVectorIntrinsicInfo *info = - llvm::lower_bound(intrinsicMap, builtinID); + const IntrinsicInfo *info = llvm::lower_bound(intrinsicMap, builtinID); if (info != intrinsicMap.end() && info->BuiltinID == builtinID) return info; @@ -260,7 +259,7 @@ static cir::VectorType getNeonPairwiseWidenInputType(cir::VectorType resType, // Derive the LLVM intrinsic's per-operand argument types and its result // type for use when emitting the intrinsic call. // -// `modifier` is the TypeModifier bitmask from `ARMVectorIntrinsicInfo` +// `modifier` is the TypeModifier bitmask from `ARMNeonVectorIntrinsicInfo` // (callers pass `info.TypeModifier`; see AArch64CodeGenUtils.h). It encodes // how the intrinsic's argument and return types relate to the builtin's // scalar types. For SISD builtins the key flags are: @@ -320,7 +319,7 @@ deriveNeonSISDIntrinsicOperandTypes(CIRGenFunction &cgf, unsigned modifier, } static mlir::Value emitCommonNeonSISDBuiltinExpr( - CIRGenFunction &cgf, const ARMVectorIntrinsicInfo &info, + CIRGenFunction &cgf, const ARMNeonVectorIntrinsicInfo &info, llvm::SmallVectorImpl<mlir::Value> &ops, const CallExpr *expr) { assert(info.LLVMIntrinsic && "Generic code assumes a valid intrinsic"); @@ -1201,8 +1200,9 @@ CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID, assert(!cir::MissingFeatures::aarch64SVEIntrinsics()); - auto *builtinIntrInfo = findARMVectorIntrinsicInMap( - aarch64SVEIntrinsicMap, builtinID, aarch64SVEIntrinsicsProvenSorted); + auto *builtinIntrInfo = + findARMVectorIntrinsicInMap(ArrayRef(aarch64SVEIntrinsicMap), builtinID, + aarch64SVEIntrinsicsProvenSorted); // The operands of the builtin call llvm::SmallVector<mlir::Value> ops; @@ -2348,8 +2348,9 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, emitScalarOrConstFoldImmArg(iceArguments, i, expr->getArg(i))); } - const ARMVectorIntrinsicInfo *builtin = findARMVectorIntrinsicInMap( - AArch64SISDIntrinsicMap, builtinID, aarch64SISDIntrinsicsProvenSorted); + const ARMNeonVectorIntrinsicInfo *builtin = + findARMVectorIntrinsicInMap(ArrayRef(AArch64SISDIntrinsicMap), builtinID, + aarch64SISDIntrinsicsProvenSorted); if (builtin) return emitCommonNeonSISDBuiltinExpr(*this, *builtin, ops, expr); @@ -2373,8 +2374,9 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, // Not all intrinsics handled by the common case work for AArch64 yet, so only // defer to common code if it's been added to our special map. - builtin = findARMVectorIntrinsicInMap(AArch64SIMDIntrinsicMap, builtinID, - aarch64SIMDIntrinsicsProvenSorted); + builtin = + findARMVectorIntrinsicInMap(ArrayRef(AArch64SIMDIntrinsicMap), builtinID, + aarch64SIMDIntrinsicsProvenSorted); if (builtin) return emitCommonNeonBuiltinExpr( *this, builtin->BuiltinID, builtin->LLVMIntrinsic, diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp index 6d6f87a9439df..dd355821fe5ff 100644 --- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp @@ -537,7 +537,7 @@ Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, } // clang-format off -static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { +static const ARMNeonVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { NEONMAP1(__a32_vcvt_bf16_f32, arm_neon_vcvtfp2bf, 0), NEONMAP0(splat_lane_v), NEONMAP0(splat_laneq_v), @@ -1008,14 +1008,11 @@ static const std::pair<unsigned, unsigned> NEONEquivalentIntrinsicMap[] = { #undef NEONMAP2 #define SVEMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ - { \ - #NameBase, SVE::BI__builtin_sve_##NameBase, Intrinsic::LLVMIntrinsic, 0, \ - TypeModifier \ - } + {SVE::BI__builtin_sve_##NameBase, Intrinsic::LLVMIntrinsic, TypeModifier} #define SVEMAP2(NameBase, TypeModifier) \ - { #NameBase, SVE::BI__builtin_sve_##NameBase, 0, 0, TypeModifier } -static const ARMVectorIntrinsicInfo AArch64SVEIntrinsicMap[] = { + {SVE::BI__builtin_sve_##NameBase, 0, TypeModifier} +static const AArch64SVEAndSMEVectorIntrinsicInfo AArch64SVEIntrinsicMap[] = { #define GET_SVE_LLVM_INTRINSIC_MAP #include "clang/Basic/arm_sve_builtin_cg.inc" #include "clang/Basic/BuiltinsAArch64NeonSVEBridge_cg.def" @@ -1026,14 +1023,11 @@ static const ARMVectorIntrinsicInfo AArch64SVEIntrinsicMap[] = { #undef SVEMAP2 #define SMEMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ - { \ - #NameBase, SME::BI__builtin_sme_##NameBase, Intrinsic::LLVMIntrinsic, 0, \ - TypeModifier \ - } + {SME::BI__builtin_sme_##NameBase, Intrinsic::LLVMIntrinsic, TypeModifier} #define SMEMAP2(NameBase, TypeModifier) \ - { #NameBase, SME::BI__builtin_sme_##NameBase, 0, 0, TypeModifier } -static const ARMVectorIntrinsicInfo AArch64SMEIntrinsicMap[] = { + {SME::BI__builtin_sme_##NameBase, 0, TypeModifier} +static const AArch64SVEAndSMEVectorIntrinsicInfo AArch64SMEIntrinsicMap[] = { #define GET_SME_LLVM_INTRINSIC_MAP #include "clang/Basic/arm_sme_builtin_cg.inc" #undef GET_SME_LLVM_INTRINSIC_MAP @@ -1051,8 +1045,9 @@ static bool AArch64SMEIntrinsicsProvenSorted = false; // Check if Builtin `BuiltinId` is present in `IntrinsicMap`. If yes, returns // the corresponding info struct. -static const ARMVectorIntrinsicInfo * -findARMVectorIntrinsicInMap(ArrayRef<ARMVectorIntrinsicInfo> IntrinsicMap, +template <typename IntrinsicInfo> +static const IntrinsicInfo * +findARMVectorIntrinsicInMap(ArrayRef<IntrinsicInfo> IntrinsicMap, unsigned BuiltinID, bool &MapProvenSorted) { #ifndef NDEBUG @@ -1062,8 +1057,7 @@ findARMVectorIntrinsicInMap(ArrayRef<ARMVectorIntrinsicInfo> IntrinsicMap, } #endif - const ARMVectorIntrinsicInfo *Builtin = - llvm::lower_bound(IntrinsicMap, BuiltinID); + const IntrinsicInfo *Builtin = llvm::lower_bound(IntrinsicMap, BuiltinID); if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) return Builtin; @@ -1114,7 +1108,7 @@ Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, // Emit-helpers //===----------------------------------------------------------------------===// static Value *EmitCommonNeonSISDBuiltinExpr( - CodeGenFunction &CGF, const ARMVectorIntrinsicInfo &SISDInfo, + CodeGenFunction &CGF, const ARMNeonVectorIntrinsicInfo &SISDInfo, SmallVectorImpl<Value *> &Ops, const CallExpr *E) { assert(SISDInfo.LLVMIntrinsic && "Generic code assumes a valid intrinsic"); @@ -2723,7 +2717,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, // Many NEON builtins have identical semantics and uses in ARM and // AArch64. Emit these in a single function. auto IntrinsicMap = ArrayRef(ARMSIMDIntrinsicMap); - const ARMVectorIntrinsicInfo *Builtin = findARMVectorIntrinsicInMap( + const ARMNeonVectorIntrinsicInfo *Builtin = findARMVectorIntrinsicInMap( IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); if (Builtin) return EmitCommonNeonBuiltinExpr( @@ -4023,8 +4017,9 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, return EmitSVEReinterpret(Val, Ty); } - auto *Builtin = findARMVectorIntrinsicInMap(AArch64SVEIntrinsicMap, BuiltinID, - AArch64SVEIntrinsicsProvenSorted); + auto *Builtin = + findARMVectorIntrinsicInMap(ArrayRef(AArch64SVEIntrinsicMap), BuiltinID, + AArch64SVEIntrinsicsProvenSorted); llvm::SmallVector<Value *, 4> Ops; SVETypeFlags TypeFlags(Builtin->TypeModifier); @@ -4406,8 +4401,9 @@ static void swapCommutativeSMEOperands(unsigned BuiltinID, Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { - auto *Builtin = findARMVectorIntrinsicInMap(AArch64SMEIntrinsicMap, BuiltinID, - AArch64SMEIntrinsicsProvenSorted); + auto *Builtin = + findARMVectorIntrinsicInMap(ArrayRef(AArch64SMEIntrinsicMap), BuiltinID, + AArch64SMEIntrinsicsProvenSorted); llvm::SmallVector<Value *, 4> Ops; SVETypeFlags TypeFlags(Builtin->TypeModifier); @@ -5344,7 +5340,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, // Check whether this is an SISD builtin. auto SISDMap = ArrayRef(AArch64SISDIntrinsicMap); - const ARMVectorIntrinsicInfo *Builtin = findARMVectorIntrinsicInMap( + const ARMNeonVectorIntrinsicInfo *Builtin = findARMVectorIntrinsicInMap( SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted); bool IsSISD = (Builtin != nullptr); @@ -5408,8 +5404,9 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, // Not all intrinsics handled by the common case work for AArch64 yet, so only // defer to common code if it's been added to our special map. - Builtin = findARMVectorIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID, - AArch64SIMDIntrinsicsProvenSorted); + Builtin = + findARMVectorIntrinsicInMap(ArrayRef(AArch64SIMDIntrinsicMap), BuiltinID, + AArch64SIMDIntrinsicsProvenSorted); if (Builtin) return EmitCommonNeonBuiltinExpr( _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
