[llvm] [ARM] Specify inlining behavior in TableGen (PR #205763)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 25 03:02:00 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: Nikita Popov (nikic)
<details>
<summary>Changes</summary>
Move the ARM inlining feature whitelist into the SubtargetFeature definitions. For this purpose, add a new InlineMustMatch inlining behavior, for features where no differences between caller/callee are allowed.
This is intended as an NFC patch to build future changes on top of: All the features in the whitelist are explicitly annotated as InlineDefault. All other features are explicitly annotated as InlineMustMatch, with a TODO to evaluate whether that is correct in a following change (except for the three that were explicitly called out as requiring those semantics).
---
Patch is 74.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/205763.diff
9 Files Affected:
- (modified) llvm/include/llvm/CodeGen/BasicTTIImpl.h (+7)
- (modified) llvm/include/llvm/CodeGen/TargetSubtargetInfo.h (+2)
- (modified) llvm/include/llvm/Target/Target.td (+3)
- (modified) llvm/lib/Target/ARM/ARMArchitectures.td (+3-1)
- (modified) llvm/lib/Target/ARM/ARMFeatures.td (+265-137)
- (modified) llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp (-67)
- (modified) llvm/lib/Target/ARM/ARMTargetTransformInfo.h (-134)
- (modified) llvm/unittests/CodeGen/MFCommon.inc (+5)
- (modified) llvm/utils/TableGen/SubtargetEmitter.cpp (+2)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 8c4df6664cf1d..5b3638803a3a1 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -401,6 +401,9 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
const TargetSubtargetInfo *CalleeSTI = TM.getSubtargetImpl(*Callee);
FeatureBitset InlineIgnoreFeatures = CallerSTI->getInlineIgnoreFeatures();
FeatureBitset InlineInverseFeatures = CallerSTI->getInlineInverseFeatures();
+ FeatureBitset InlineMustMatchFeatures =
+ CallerSTI->getInlineMustMatchFeatures();
+
FeatureBitset CallerBits =
(CallerSTI->getFeatureBits() ^ InlineInverseFeatures) &
~InlineIgnoreFeatures;
@@ -408,6 +411,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
(CalleeSTI->getFeatureBits() ^ InlineInverseFeatures) &
~InlineIgnoreFeatures;
+ if ((CallerBits & InlineMustMatchFeatures) !=
+ (CalleeBits & InlineMustMatchFeatures))
+ return false;
+
// Inline a callee if its target-features are a subset of the callers
// target-features.
return (CallerBits & CalleeBits) == CalleeBits;
diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
index fe71a17146184..52bd274b86a84 100644
--- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
@@ -370,6 +370,8 @@ class LLVM_ABI TargetSubtargetInfo : public MCSubtargetInfo {
/// Target features where the callee may have an additional feature,
/// instead of the caller.
virtual const FeatureBitset &getInlineInverseFeatures() const = 0;
+ /// Target features where all mismatches prevent inlining.
+ virtual const FeatureBitset &getInlineMustMatchFeatures() const = 0;
};
} // end namespace llvm
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 455b9f40f8b72..cb97ab5d1bae4 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -534,6 +534,9 @@ def InlineDefault : InlineBehavior;
// A callee without this feature enabled cannot be inlined into a caller with
// it enabled.
def InlineInverse : InlineBehavior;
+// The feature must be either enabled in both caller and callee, or disabled in
+// both.
+def InlineMustMatch : InlineBehavior;
//===----------------------------------------------------------------------===//
// SubtargetFeature - A characteristic of the chip set.
diff --git a/llvm/lib/Target/ARM/ARMArchitectures.td b/llvm/lib/Target/ARM/ARMArchitectures.td
index bfcecfe27091f..25e5e28168a59 100644
--- a/llvm/lib/Target/ARM/ARMArchitectures.td
+++ b/llvm/lib/Target/ARM/ARMArchitectures.td
@@ -1,6 +1,8 @@
+// TODO: Does this need to be InlineMustMatch?
class Architecture<string fname, string aname, list<SubtargetFeature> features>
: SubtargetFeature<fname, "ARMArch", aname,
- !strconcat(aname, " architecture"), features>;
+ !strconcat(aname, " architecture"), features,
+ InlineMustMatch>;
//===----------------------------------------------------------------------===//
// ARM architectures
diff --git a/llvm/lib/Target/ARM/ARMFeatures.td b/llvm/lib/Target/ARM/ARMFeatures.td
index e562b2170db5c..a1e93baf008ac 100644
--- a/llvm/lib/Target/ARM/ARMFeatures.td
+++ b/llvm/lib/Target/ARM/ARMFeatures.td
@@ -4,12 +4,14 @@
// True if compiling for Thumb, false for ARM.
def ModeThumb : SubtargetFeature<"thumb-mode", "IsThumb",
- "true", "Thumb mode">;
+ "true", "Thumb mode",
+ [], InlineMustMatch>;
// True if we're using software floating point features.
def ModeSoftFloat : SubtargetFeature<"soft-float","UseSoftFloat",
"true", "Use software floating "
- "point features.">;
+ "point features.",
+ [], InlineMustMatch>;
//===----------------------------------------------------------------------===//
// ARM Subtarget features.
@@ -32,27 +34,29 @@ class Extension<
// FP loads/stores/moves, shared between VFP and MVE (even in the integer-only
// version).
def FeatureFPRegs : SubtargetFeature<"fpregs", "HasFPRegs", "true",
- "Enable FP registers">;
+ "Enable FP registers",
+ [], InlineDefault>;
// 16-bit FP loads/stores/moves, shared between VFP (with the v8.2A FP16
// extension) and MVE (even in the integer-only version).
def FeatureFPRegs16 : SubtargetFeature<"fpregs16", "HasFPRegs16", "true",
"Enable 16-bit FP registers",
- [FeatureFPRegs]>;
+ [FeatureFPRegs], InlineDefault>;
def FeatureFPRegs64 : SubtargetFeature<"fpregs64", "HasFPRegs64", "true",
"Enable 64-bit FP registers",
- [FeatureFPRegs]>;
+ [FeatureFPRegs], InlineDefault>;
// True if the floating point unit supports double precision.
def FeatureFP64 : SubtargetFeature<"fp64", "HasFP64", "true",
"Floating point unit supports "
"double precision",
- [FeatureFPRegs64]>;
+ [FeatureFPRegs64], InlineDefault>;
// True if subtarget has the full 32 double precision FP registers for VFPv3.
def FeatureD32 : SubtargetFeature<"d32", "HasD32", "true",
- "Extend FP to 32 double registers">;
+ "Extend FP to 32 double registers",
+ [], InlineDefault>;
/// Versions of the VFP flags restricted to single precision, or to
/// 16 d-registers, or both.
@@ -65,45 +69,50 @@ multiclass VFPver<string name, string query, string description,
description#" with only 16 d-registers and no double precision",
!foreach(v, prev, !cast<SubtargetFeature>(v # "_D16_SP")) #
!foreach(v, vfp2prev, !cast<SubtargetFeature>(v # "_SP")) #
- otherimplies>;
+ otherimplies, InlineDefault>;
def _SP: SubtargetFeature<
name#"sp", query#"SP", "true",
description#" with no double precision",
!foreach(v, prev, !cast<SubtargetFeature>(v # "_SP")) #
- otherimplies # [FeatureD32, !cast<SubtargetFeature>(NAME # "_D16_SP")]>;
+ otherimplies # [FeatureD32, !cast<SubtargetFeature>(NAME # "_D16_SP")],
+ InlineDefault>;
def _D16: SubtargetFeature<
name#"d16", query#"D16", "true",
description#" with only 16 d-registers",
!foreach(v, prev, !cast<SubtargetFeature>(v # "_D16")) #
vfp2prev #
- otherimplies # [FeatureFP64, !cast<SubtargetFeature>(NAME # "_D16_SP")]>;
+ otherimplies # [FeatureFP64, !cast<SubtargetFeature>(NAME # "_D16_SP")],
+ InlineDefault>;
def "": SubtargetFeature<
name, query, "true", description,
prev # otherimplies # [
!cast<SubtargetFeature>(NAME # "_D16"),
- !cast<SubtargetFeature>(NAME # "_SP")]>;
+ !cast<SubtargetFeature>(NAME # "_SP")],
+ InlineDefault>;
}
def FeatureVFP2_SP : SubtargetFeature<"vfp2sp", "HasVFPv2SP", "true",
"Enable VFP2 instructions with "
"no double precision",
- [FeatureFPRegs]>;
+ [FeatureFPRegs], InlineDefault>;
def FeatureVFP2 : SubtargetFeature<"vfp2", "HasVFPv2", "true",
"Enable VFP2 instructions",
- [FeatureFP64, FeatureVFP2_SP]>;
+ [FeatureFP64, FeatureVFP2_SP],
+ InlineDefault>;
defm FeatureVFP3: VFPver<"vfp3", "HasVFPv3", "Enable VFP3 instructions",
[], [], [FeatureVFP2]>;
def FeatureNEON : SubtargetFeature<"neon", "HasNEON", "true",
"Enable NEON instructions",
- [FeatureVFP3]>;
+ [FeatureVFP3], InlineDefault>;
// True if subtarget supports half-precision FP conversions.
def FeatureFP16 : SubtargetFeature<"fp16", "HasFP16", "true",
"Enable half-precision "
- "floating point">;
+ "floating point",
+ [], InlineDefault>;
defm FeatureVFP4: VFPver<"vfp4", "HasVFPv4", "Enable VFP4 instructions",
[FeatureVFP3], [FeatureFP16]>;
@@ -115,55 +124,64 @@ defm FeatureFPARMv8: VFPver<"fp-armv8", "HasFPARMv8", "Enable ARMv8 FP",
def FeatureFullFP16 : SubtargetFeature<"fullfp16", "HasFullFP16", "true",
"Enable full half-precision "
"floating point",
- [FeatureFPARMv8_D16_SP, FeatureFPRegs16]>;
+ [FeatureFPARMv8_D16_SP, FeatureFPRegs16],
+ InlineDefault>;
// True if subtarget supports half-precision FP fml operations.
def FeatureFP16FML : SubtargetFeature<"fp16fml", "HasFP16FML", "true",
"Enable full half-precision "
"floating point fml instructions",
- [FeatureFullFP16]>;
+ [FeatureFullFP16], InlineDefault>;
// True if subtarget supports [su]div in Thumb mode.
def FeatureHWDivThumb : SubtargetFeature<"hwdiv",
"HasDivideInThumbMode", "true",
- "Enable divide instructions in Thumb">;
+ "Enable divide instructions in Thumb",
+ [], InlineDefault>;
// True if subtarget supports [su]div in ARM mode.
def FeatureHWDivARM : SubtargetFeature<"hwdiv-arm",
"HasDivideInARMMode", "true",
- "Enable divide instructions in ARM mode">;
+ "Enable divide instructions in ARM mode",
+ [], InlineDefault>;
// Atomic Support
// True if the subtarget supports DMB / DSB data barrier instructions.
def FeatureDB : SubtargetFeature<"db", "HasDataBarrier", "true",
- "Has data barrier (dmb/dsb) instructions">;
+ "Has data barrier (dmb/dsb) instructions",
+ [], InlineDefault>;
// True if the subtarget supports CLREX instructions.
def FeatureV7Clrex : SubtargetFeature<"v7clrex", "HasV7Clrex", "true",
- "Has v7 clrex instruction">;
+ "Has v7 clrex instruction",
+ [], InlineDefault>;
// True if the subtarget supports DFB data barrier instruction.
def FeatureDFB : SubtargetFeature<"dfb", "HasFullDataBarrier", "true",
- "Has full data barrier (dfb) instruction">;
+ "Has full data barrier (dfb) instruction",
+ [], InlineDefault>;
// True if the subtarget supports v8 atomics (LDA/LDAEX etc) instructions.
def FeatureAcquireRelease : SubtargetFeature<"acquire-release",
"HasAcquireRelease", "true",
"Has v8 acquire/release (lda/ldaex "
- " etc) instructions">;
+ " etc) instructions",
+ [], InlineDefault>;
// True if floating point compare + branch is slow.
def FeatureSlowFPBrcc : SubtargetFeature<"slow-fp-brcc", "IsFPBrccSlow", "true",
- "FP compare + branch is slow">;
+ "FP compare + branch is slow",
+ [], InlineDefault>;
// True if the processor supports the Performance Monitor Extensions. These
// include a generic cycle-counter as well as more fine-grained (often
// implementation-specific) events.
def FeaturePerfMon : SubtargetFeature<"perfmon", "HasPerfMon", "true",
"Enable support for Performance "
- "Monitor extensions">;
+ "Monitor extensions",
+ [], InlineDefault>;
// TrustZone Security Extensions
@@ -171,106 +189,129 @@ def FeaturePerfMon : SubtargetFeature<"perfmon", "HasPerfMon", "true",
// True if processor supports TrustZone security extensions.
def FeatureTrustZone : SubtargetFeature<"trustzone", "HasTrustZone", "true",
"Enable support for TrustZone "
- "security extensions">;
+ "security extensions",
+ [], InlineDefault>;
// True if processor supports ARMv8-M Security Extensions.
def Feature8MSecExt : SubtargetFeature<"8msecext", "Has8MSecExt", "true",
"Enable support for ARMv8-M "
- "Security Extensions">;
+ "Security Extensions",
+ [], InlineDefault>;
// True if processor supports SHA1 and SHA256.
def FeatureSHA2 : SubtargetFeature<"sha2", "HasSHA2", "true",
- "Enable SHA1 and SHA256 support", [FeatureNEON]>;
+ "Enable SHA1 and SHA256 support",
+ [FeatureNEON], InlineDefault>;
def FeatureAES : SubtargetFeature<"aes", "HasAES", "true",
- "Enable AES support", [FeatureNEON]>;
+ "Enable AES support",
+ [FeatureNEON], InlineDefault>;
// True if processor supports Cryptography extensions.
def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true",
"Enable support for "
"Cryptography extensions",
- [FeatureNEON, FeatureSHA2, FeatureAES]>;
+ [FeatureNEON, FeatureSHA2, FeatureAES],
+ InlineDefault>;
// True if processor supports CRC instructions.
def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true",
- "Enable support for CRC instructions">;
+ "Enable support for CRC instructions",
+ [], InlineDefault>;
// True if the ARMv8.2A dot product instructions are supported.
def FeatureDotProd : SubtargetFeature<"dotprod", "HasDotProd", "true",
"Enable support for dot product instructions",
- [FeatureNEON]>;
+ [FeatureNEON], InlineDefault>;
// True if the processor supports RAS extensions.
// Not to be confused with FeatureHasRetAddrStack (return address stack).
def FeatureRAS : SubtargetFeature<"ras", "HasRAS", "true",
"Enable Reliability, Availability "
- "and Serviceability extensions">;
+ "and Serviceability extensions",
+ [], InlineDefault>;
// Fast computation of non-negative address offsets.
// True if processor does positive address offset computation faster.
def FeatureFPAO : SubtargetFeature<"fpao", "HasFPAO", "true",
"Enable fast computation of "
- "positive address offsets">;
+ "positive address offsets",
+ [], InlineDefault>;
// Fast execution of AES crypto operations.
// True if processor executes back to back AES instruction pairs faster.
def FeatureFuseAES : SubtargetFeature<"fuse-aes", "HasFuseAES", "true",
- "CPU fuses AES crypto operations">;
+ "CPU fuses AES crypto operations",
+ [], InlineDefault>;
// Fast execution of bottom and top halves of literal generation.
// True if processor executes back to back bottom and top halves of literal generation faster.
def FeatureFuseLiterals : SubtargetFeature<"fuse-literals", "HasFuseLiterals", "true",
- "CPU fuses literal generation operations">;
+ "CPU fuses literal generation operations",
+ [], InlineDefault>;
// Choice of hardware register to use as the thread pointer, if any.
+// TODO: Does this need to be InlineMustMatch?
def FeatureReadTpTPIDRURW : SubtargetFeature<"read-tp-tpidrurw", "IsReadTPTPIDRURW", "true",
- "Reading thread pointer from TPIDRURW register">;
+ "Reading thread pointer from TPIDRURW register",
+ [], InlineMustMatch>;
+// TODO: Does this need to be InlineMustMatch?
def FeatureReadTpTPIDRURO : SubtargetFeature<"read-tp-tpidruro", "IsReadTPTPIDRURO", "true",
- "Reading thread pointer from TPIDRURO register">;
+ "Reading thread pointer from TPIDRURO register",
+ [], InlineMustMatch>;
+// TODO: Does this need to be InlineMustMatch?
def FeatureReadTpTPIDRPRW : SubtargetFeature<"read-tp-tpidrprw", "IsReadTPTPIDRPRW", "true",
- "Reading thread pointer from TPIDRPRW register">;
+ "Reading thread pointer from TPIDRPRW register",
+ [], InlineMustMatch>;
// Cyclone can zero VFP registers in 0 cycles.
// True if the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are
// particularly effective at zeroing a VFP register.
def FeatureZCZeroing : SubtargetFeature<"zcz", "HasZeroCycleZeroing", "true",
- "Has zero-cycle zeroing instructions">;
+ "Has zero-cycle zeroing instructions",
+ [], InlineDefault>;
// Whether it is profitable to unpredic...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/205763
More information about the llvm-commits
mailing list