[llvm] Revert "[AArch64][SME] Split SMECallAttrs out of SMEAttrs" (PR #138664)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 6 02:28:27 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Benjamin Maxwell (MacDue)
<details>
<summary>Changes</summary>
Reverts llvm/llvm-project#<!-- -->137239
This broke implementing SME ABI routines in C/C++ (used for some stubs), see: https://lab.llvm.org/buildbot/#/builders/94/builds/6859
---
Patch is 43.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138664.diff
8 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+38-38)
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (+12-13)
- (modified) llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp (+29-35)
- (modified) llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.h (+31-83)
- (modified) llvm/test/CodeGen/AArch64/sme-peephole-opts.ll (+11-12)
- (modified) llvm/test/CodeGen/AArch64/sme-vg-to-stack.ll (+2-2)
- (modified) llvm/test/CodeGen/AArch64/sme-zt0-state.ll (+35-33)
- (modified) llvm/unittests/Target/AArch64/SMEAttributesTest.cpp (+53-53)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ab577e130ad9c..1c889d67c81e0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -8636,16 +8636,6 @@ static void analyzeCallOperands(const AArch64TargetLowering &TLI,
}
}
-static SMECallAttrs
-getSMECallAttrs(const Function &Function,
- const TargetLowering::CallLoweringInfo &CLI) {
- if (CLI.CB)
- return SMECallAttrs(*CLI.CB);
- if (auto *ES = dyn_cast<ExternalSymbolSDNode>(CLI.Callee))
- return SMECallAttrs(SMEAttrs(Function), SMEAttrs(ES->getSymbol()));
- return SMECallAttrs(SMEAttrs(Function), SMEAttrs(SMEAttrs::Normal));
-}
-
bool AArch64TargetLowering::isEligibleForTailCallOptimization(
const CallLoweringInfo &CLI) const {
CallingConv::ID CalleeCC = CLI.CallConv;
@@ -8664,10 +8654,12 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
// SME Streaming functions are not eligible for TCO as they may require
// the streaming mode or ZA to be restored after returning from the call.
- SMECallAttrs CallAttrs = getSMECallAttrs(CallerF, CLI);
- if (CallAttrs.requiresSMChange() || CallAttrs.requiresLazySave() ||
- CallAttrs.requiresPreservingAllZAState() ||
- CallAttrs.caller().hasStreamingBody())
+ SMEAttrs CallerAttrs(MF.getFunction());
+ auto CalleeAttrs = CLI.CB ? SMEAttrs(*CLI.CB) : SMEAttrs(SMEAttrs::Normal);
+ if (CallerAttrs.requiresSMChange(CalleeAttrs) ||
+ CallerAttrs.requiresLazySave(CalleeAttrs) ||
+ CallerAttrs.requiresPreservingAllZAState(CalleeAttrs) ||
+ CallerAttrs.hasStreamingBody())
return false;
// Functions using the C or Fast calling convention that have an SVE signature
@@ -8959,13 +8951,14 @@ static SDValue emitSMEStateSaveRestore(const AArch64TargetLowering &TLI,
return TLI.LowerCallTo(CLI).second;
}
-static unsigned getSMCondition(const SMECallAttrs &CallAttrs) {
- if (!CallAttrs.caller().hasStreamingCompatibleInterface() ||
- CallAttrs.caller().hasStreamingBody())
+static unsigned getSMCondition(const SMEAttrs &CallerAttrs,
+ const SMEAttrs &CalleeAttrs) {
+ if (!CallerAttrs.hasStreamingCompatibleInterface() ||
+ CallerAttrs.hasStreamingBody())
return AArch64SME::Always;
- if (CallAttrs.callee().hasNonStreamingInterface())
+ if (CalleeAttrs.hasNonStreamingInterface())
return AArch64SME::IfCallerIsStreaming;
- if (CallAttrs.callee().hasStreamingInterface())
+ if (CalleeAttrs.hasStreamingInterface())
return AArch64SME::IfCallerIsNonStreaming;
llvm_unreachable("Unsupported attributes");
@@ -9098,7 +9091,11 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
}
// Determine whether we need any streaming mode changes.
- SMECallAttrs CallAttrs = getSMECallAttrs(MF.getFunction(), CLI);
+ SMEAttrs CalleeAttrs, CallerAttrs(MF.getFunction());
+ if (CLI.CB)
+ CalleeAttrs = SMEAttrs(*CLI.CB);
+ else if (auto *ES = dyn_cast<ExternalSymbolSDNode>(CLI.Callee))
+ CalleeAttrs = SMEAttrs(ES->getSymbol());
auto DescribeCallsite =
[&](OptimizationRemarkAnalysis &R) -> OptimizationRemarkAnalysis & {
@@ -9113,8 +9110,9 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
return R;
};
- bool RequiresLazySave = CallAttrs.requiresLazySave();
- bool RequiresSaveAllZA = CallAttrs.requiresPreservingAllZAState();
+ bool RequiresLazySave = CallerAttrs.requiresLazySave(CalleeAttrs);
+ bool RequiresSaveAllZA =
+ CallerAttrs.requiresPreservingAllZAState(CalleeAttrs);
if (RequiresLazySave) {
const TPIDR2Object &TPIDR2 = FuncInfo->getTPIDR2Obj();
MachinePointerInfo MPI =
@@ -9142,18 +9140,18 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
return DescribeCallsite(R) << " sets up a lazy save for ZA";
});
} else if (RequiresSaveAllZA) {
- assert(!CallAttrs.callee().hasSharedZAInterface() &&
+ assert(!CalleeAttrs.hasSharedZAInterface() &&
"Cannot share state that may not exist");
Chain = emitSMEStateSaveRestore(*this, DAG, FuncInfo, DL, Chain,
/*IsSave=*/true);
}
SDValue PStateSM;
- bool RequiresSMChange = CallAttrs.requiresSMChange();
+ bool RequiresSMChange = CallerAttrs.requiresSMChange(CalleeAttrs);
if (RequiresSMChange) {
- if (CallAttrs.caller().hasStreamingInterfaceOrBody())
+ if (CallerAttrs.hasStreamingInterfaceOrBody())
PStateSM = DAG.getConstant(1, DL, MVT::i64);
- else if (CallAttrs.caller().hasNonStreamingInterface())
+ else if (CallerAttrs.hasNonStreamingInterface())
PStateSM = DAG.getConstant(0, DL, MVT::i64);
else
PStateSM = getRuntimePStateSM(DAG, Chain, DL, MVT::i64);
@@ -9170,7 +9168,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
SDValue ZTFrameIdx;
MachineFrameInfo &MFI = MF.getFrameInfo();
- bool ShouldPreserveZT0 = CallAttrs.requiresPreservingZT0();
+ bool ShouldPreserveZT0 = CallerAttrs.requiresPreservingZT0(CalleeAttrs);
// If the caller has ZT0 state which will not be preserved by the callee,
// spill ZT0 before the call.
@@ -9186,7 +9184,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// If caller shares ZT0 but the callee is not shared ZA, we need to stop
// PSTATE.ZA before the call if there is no lazy-save active.
- bool DisableZA = CallAttrs.requiresDisablingZABeforeCall();
+ bool DisableZA = CallerAttrs.requiresDisablingZABeforeCall(CalleeAttrs);
assert((!DisableZA || !RequiresLazySave) &&
"Lazy-save should have PSTATE.SM=1 on entry to the function");
@@ -9468,9 +9466,9 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
InGlue = Chain.getValue(1);
}
- SDValue NewChain =
- changeStreamingMode(DAG, DL, CallAttrs.callee().hasStreamingInterface(),
- Chain, InGlue, getSMCondition(CallAttrs), PStateSM);
+ SDValue NewChain = changeStreamingMode(
+ DAG, DL, CalleeAttrs.hasStreamingInterface(), Chain, InGlue,
+ getSMCondition(CallerAttrs, CalleeAttrs), PStateSM);
Chain = NewChain.getValue(0);
InGlue = NewChain.getValue(1);
}
@@ -9649,8 +9647,8 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
if (RequiresSMChange) {
assert(PStateSM && "Expected a PStateSM to be set");
Result = changeStreamingMode(
- DAG, DL, !CallAttrs.callee().hasStreamingInterface(), Result, InGlue,
- getSMCondition(CallAttrs), PStateSM);
+ DAG, DL, !CalleeAttrs.hasStreamingInterface(), Result, InGlue,
+ getSMCondition(CallerAttrs, CalleeAttrs), PStateSM);
if (!Subtarget->isTargetDarwin() || Subtarget->hasSVE()) {
InGlue = Result.getValue(1);
@@ -9660,7 +9658,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
}
}
- if (CallAttrs.requiresEnablingZAAfterCall())
+ if (CallerAttrs.requiresEnablingZAAfterCall(CalleeAttrs))
// Unconditionally resume ZA.
Result = DAG.getNode(
AArch64ISD::SMSTART, DL, MVT::Other, Result,
@@ -28520,10 +28518,12 @@ bool AArch64TargetLowering::fallBackToDAGISel(const Instruction &Inst) const {
// Checks to allow the use of SME instructions
if (auto *Base = dyn_cast<CallBase>(&Inst)) {
- auto CallAttrs = SMECallAttrs(*Base);
- if (CallAttrs.requiresSMChange() || CallAttrs.requiresLazySave() ||
- CallAttrs.requiresPreservingZT0() ||
- CallAttrs.requiresPreservingAllZAState())
+ auto CallerAttrs = SMEAttrs(*Inst.getFunction());
+ auto CalleeAttrs = SMEAttrs(*Base);
+ if (CallerAttrs.requiresSMChange(CalleeAttrs) ||
+ CallerAttrs.requiresLazySave(CalleeAttrs) ||
+ CallerAttrs.requiresPreservingZT0(CalleeAttrs) ||
+ CallerAttrs.requiresPreservingAllZAState(CalleeAttrs))
return true;
}
return false;
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 34fb76e66ec00..5b3a1df9dfd7c 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -268,21 +268,22 @@ const FeatureBitset AArch64TTIImpl::InlineInverseFeatures = {
bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
const Function *Callee) const {
- SMECallAttrs CallAttrs(*Caller, *Callee);
+ SMEAttrs CallerAttrs(*Caller), CalleeAttrs(*Callee);
// When inlining, we should consider the body of the function, not the
// interface.
- if (CallAttrs.callee().hasStreamingBody()) {
- CallAttrs.callee().set(SMEAttrs::SM_Compatible, false);
- CallAttrs.callee().set(SMEAttrs::SM_Enabled, true);
+ if (CalleeAttrs.hasStreamingBody()) {
+ CalleeAttrs.set(SMEAttrs::SM_Compatible, false);
+ CalleeAttrs.set(SMEAttrs::SM_Enabled, true);
}
- if (CallAttrs.callee().isNewZA() || CallAttrs.callee().isNewZT0())
+ if (CalleeAttrs.isNewZA() || CalleeAttrs.isNewZT0())
return false;
- if (CallAttrs.requiresLazySave() || CallAttrs.requiresSMChange() ||
- CallAttrs.requiresPreservingZT0() ||
- CallAttrs.requiresPreservingAllZAState()) {
+ if (CallerAttrs.requiresLazySave(CalleeAttrs) ||
+ CallerAttrs.requiresSMChange(CalleeAttrs) ||
+ CallerAttrs.requiresPreservingZT0(CalleeAttrs) ||
+ CallerAttrs.requiresPreservingAllZAState(CalleeAttrs)) {
if (hasPossibleIncompatibleOps(Callee))
return false;
}
@@ -348,14 +349,12 @@ AArch64TTIImpl::getInlineCallPenalty(const Function *F, const CallBase &Call,
// streaming-mode change, and the call to G from F would also require a
// streaming-mode change, then there is benefit to do the streaming-mode
// change only once and avoid inlining of G into F.
-
SMEAttrs FAttrs(*F);
- SMECallAttrs CallAttrs(Call);
-
- if (SMECallAttrs(FAttrs, CallAttrs.callee()).requiresSMChange()) {
+ SMEAttrs CalleeAttrs(Call);
+ if (FAttrs.requiresSMChange(CalleeAttrs)) {
if (F == Call.getCaller()) // (1)
return CallPenaltyChangeSM * DefaultCallPenalty;
- if (SMECallAttrs(FAttrs, CallAttrs.caller()).requiresSMChange()) // (2)
+ if (FAttrs.requiresSMChange(SMEAttrs(*Call.getCaller()))) // (2)
return InlineCallPenaltyChangeSM * DefaultCallPenalty;
}
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp b/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp
index 16ae5434e596a..76d2ac6a601e5 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp
@@ -27,14 +27,15 @@ void SMEAttrs::set(unsigned M, bool Enable) {
"ZA_New and SME_ABI_Routine are mutually exclusive");
assert(
- (isNewZA() + isInZA() + isOutZA() + isInOutZA() + isPreservesZA()) <= 1 &&
+ (!sharesZA() ||
+ (isNewZA() ^ isInZA() ^ isInOutZA() ^ isOutZA() ^ isPreservesZA())) &&
"Attributes 'aarch64_new_za', 'aarch64_in_za', 'aarch64_out_za', "
"'aarch64_inout_za' and 'aarch64_preserves_za' are mutually exclusive");
// ZT0 Attrs
assert(
- (isNewZT0() + isInZT0() + isOutZT0() + isInOutZT0() + isPreservesZT0()) <=
- 1 &&
+ (!sharesZT0() || (isNewZT0() ^ isInZT0() ^ isInOutZT0() ^ isOutZT0() ^
+ isPreservesZT0())) &&
"Attributes 'aarch64_new_zt0', 'aarch64_in_zt0', 'aarch64_out_zt0', "
"'aarch64_inout_zt0' and 'aarch64_preserves_zt0' are mutually exclusive");
@@ -43,6 +44,27 @@ void SMEAttrs::set(unsigned M, bool Enable) {
"interface");
}
+SMEAttrs::SMEAttrs(const CallBase &CB) {
+ *this = SMEAttrs(CB.getAttributes());
+ if (auto *F = CB.getCalledFunction()) {
+ set(SMEAttrs(*F).Bitmask | SMEAttrs(F->getName()).Bitmask);
+ }
+}
+
+SMEAttrs::SMEAttrs(StringRef FuncName) : Bitmask(0) {
+ if (FuncName == "__arm_tpidr2_save" || FuncName == "__arm_sme_state")
+ Bitmask |= (SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine);
+ if (FuncName == "__arm_tpidr2_restore")
+ Bitmask |= SMEAttrs::SM_Compatible | encodeZAState(StateValue::In) |
+ SMEAttrs::SME_ABI_Routine;
+ if (FuncName == "__arm_sc_memcpy" || FuncName == "__arm_sc_memset" ||
+ FuncName == "__arm_sc_memmove" || FuncName == "__arm_sc_memchr")
+ Bitmask |= SMEAttrs::SM_Compatible;
+ if (FuncName == "__arm_sme_save" || FuncName == "__arm_sme_restore" ||
+ FuncName == "__arm_sme_state_size")
+ Bitmask |= SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine;
+}
+
SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
Bitmask = 0;
if (Attrs.hasFnAttr("aarch64_pstate_sm_enabled"))
@@ -77,45 +99,17 @@ SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
Bitmask |= encodeZT0State(StateValue::New);
}
-void SMEAttrs::addKnownFunctionAttrs(StringRef FuncName) {
- unsigned KnownAttrs = SMEAttrs::Normal;
- if (FuncName == "__arm_tpidr2_save" || FuncName == "__arm_sme_state")
- KnownAttrs |= (SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine);
- if (FuncName == "__arm_tpidr2_restore")
- KnownAttrs |= SMEAttrs::SM_Compatible | encodeZAState(StateValue::In) |
- SMEAttrs::SME_ABI_Routine;
- if (FuncName == "__arm_sc_memcpy" || FuncName == "__arm_sc_memset" ||
- FuncName == "__arm_sc_memmove" || FuncName == "__arm_sc_memchr")
- KnownAttrs |= SMEAttrs::SM_Compatible;
- if (FuncName == "__arm_sme_save" || FuncName == "__arm_sme_restore" ||
- FuncName == "__arm_sme_state_size")
- KnownAttrs |= SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine;
- set(KnownAttrs, /*Enable=*/true);
-}
-
-bool SMECallAttrs::requiresSMChange() const {
- if (callee().hasStreamingCompatibleInterface())
+bool SMEAttrs::requiresSMChange(const SMEAttrs &Callee) const {
+ if (Callee.hasStreamingCompatibleInterface())
return false;
// Both non-streaming
- if (caller().hasNonStreamingInterfaceAndBody() &&
- callee().hasNonStreamingInterface())
+ if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface())
return false;
// Both streaming
- if (caller().hasStreamingInterfaceOrBody() &&
- callee().hasStreamingInterface())
+ if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface())
return false;
return true;
}
-
-SMECallAttrs::SMECallAttrs(const CallBase &CB)
- : CallerFn(*CB.getFunction()), CalledFn(CB.getCalledFunction()),
- Callsite(CB.getAttributes()), IsIndirect(CB.isIndirectCall()) {
- // FIXME: We probably should not allow SME attributes on direct calls but
- // clang duplicates streaming mode attributes at each callsite.
- assert((IsIndirect ||
- ((Callsite.withoutPerCallsiteFlags() | CalledFn) == CalledFn)) &&
- "SME attributes at callsite do not match declaration");
-}
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.h b/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.h
index c4f132ba6ddf1..1691d4fec8b68 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.h
@@ -18,9 +18,12 @@ class CallBase;
class AttributeList;
/// SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
-/// It helps determine a function's requirements for PSTATE.ZA and PSTATE.SM.
+/// It helps determine a function's requirements for PSTATE.ZA and PSTATE.SM. It
+/// has interfaces to query whether a streaming mode change or lazy-save
+/// mechanism is required when going from one function to another (e.g. through
+/// a call).
class SMEAttrs {
- unsigned Bitmask = Normal;
+ unsigned Bitmask;
public:
enum class StateValue {
@@ -40,24 +43,18 @@ class SMEAttrs {
SM_Body = 1 << 2, // aarch64_pstate_sm_body
SME_ABI_Routine = 1 << 3, // Used for SME ABI routines to avoid lazy saves
ZA_State_Agnostic = 1 << 4,
- ZT0_Undef = 1 << 5, // Use to mark ZT0 as undef to avoid spills
+ ZT0_Undef = 1 << 5, // Use to mark ZT0 as undef to avoid spills
ZA_Shift = 6,
ZA_Mask = 0b111 << ZA_Shift,
ZT0_Shift = 9,
- ZT0_Mask = 0b111 << ZT0_Shift,
- Callsite_Flags = ZT0_Undef
+ ZT0_Mask = 0b111 << ZT0_Shift
};
- SMEAttrs() = default;
- SMEAttrs(unsigned Mask) { set(Mask); }
- SMEAttrs(const Function *F)
- : SMEAttrs(F ? F->getAttributes() : AttributeList()) {
- if (F)
- addKnownFunctionAttrs(F->getName());
- }
- SMEAttrs(const Function &F) : SMEAttrs(&F) {}
+ SMEAttrs(unsigned Mask = Normal) : Bitmask(0) { set(Mask); }
+ SMEAttrs(const Function &F) : SMEAttrs(F.getAttributes()) {}
+ SMEAttrs(const CallBase &CB);
SMEAttrs(const AttributeList &L);
- SMEAttrs(StringRef FuncName) { addKnownFunctionAttrs(FuncName); };
+ SMEAttrs(StringRef FuncName);
void set(unsigned M, bool Enable = true);
@@ -77,6 +74,10 @@ class SMEAttrs {
return hasNonStreamingInterface() && !hasStreamingBody();
}
+ /// \return true if a call from Caller -> Callee requires a change in
+ /// streaming mode.
+ bool requiresSMChange(const SMEAttrs &Callee) const;
+
// Interfaces to query ZA
static StateValue decodeZAState(unsigned Bitmask) {
return static_cast<StateValue>((Bitmask & ZA_Mask) >> ZA_Shift);
@@ -103,7 +104,10 @@ class SMEAttrs {
return !hasSharedZAInterface() && !hasAgnosticZAInterface();
}
bool hasZAState() const { return isNewZA() || sharesZA(); }
- bool isSMEABIRoutine() const { return Bitmask & SME_ABI_Routine; }
+ bool requiresLazySave(const SMEAttrs &Callee) const {
+ return hasZAState() && Callee.hasPrivateZAInterface() &&
+ !(Callee.Bitmask & SME_ABI_Routine);
+ }
// Interfaces to query ZT0 State
static StateValue decodeZT0State(unsigned Bitmask) {
@@ -122,83 +126,27 @@ class SMEAttrs {
bool isPreservesZT0() const {
return decodeZT0State(Bitmask) == StateValue::Preserved;
}
- bool hasUndefZT0() const { return Bitmask & ZT0_Undef; }
+ bool isUndefZT0() const { return Bitmask & ZT0_Undef; }
bool sharesZT0() const {
StateValue State = decodeZT0State(Bitmask);
return State == StateValue::In || State == StateValue::Out ||
State == StateValue::InOut || State == StateValue::Preserved;
}
bool hasZT0State() const { return isNewZT0() || sharesZT0(); }
-
- SMEAttrs operator|(SMEAttrs Other) const {
- SMEAttrs Merged(*this);
- Merged.set(Other.Bitmask, /*Enable=*/true);
- return Merged;
- }
-
- SMEAttrs withoutPerCallsiteFlags() const {
- return (Bitmask & ~Callsite_Flags);
- }
-
- bool operator==(SMEAttrs const &Other) const {
- return Bitmask == Other.Bitmask;
- }
-
-private:
- void addKnownFunctionAttrs(StringRef FuncName);
-};
-
-/// SMECallAttrs is a utility class to hold the SMEAttrs for a callsite. It has
-/// interfaces to query whether a streaming mode change or lazy-save mechanism
-/// is required when going from one function to another (e.g. through a call).
-class SMECallAttrs {
- SMEAttrs CallerFn;
- SMEAttrs CalledFn;
- SMEAttrs Callsite;
- bool IsIndirect = false;
-
-public:
- SMECallAttrs(SMEAttrs Caller, SMEAttrs Callee,
- SMEAttrs Callsite = SMEAttrs::Normal)
- : CallerFn(Caller), CalledFn(Callee), Callsite(Callsite) {}
-
- SMECallAttrs(const CallBase &CB);
-
- SMEAttrs &caller() { return CallerFn; }
- SMEAttrs &callee() { return IsIndirect ? Callsite : CalledFn; }
- SMEAttrs &callsite() { return Callsite; }
- SMEAttrs const &caller() const { return CallerFn; }
- SMEAttrs const &callee() const {
- return const_cast<SMECallAttrs *>(this)->callee();
- }
- SMEAttrs const &callsite() const { return Callsite; }
-
- /// \return true if a call from Caller -> Callee requires a change in
- /// streaming mode.
- bool requiresSMChange() const;
-
- bool requiresLazySave() const {
- return caller().hasZAState() && callee().hasPrivateZAInterface() &&
- !callee().isSMEABIRoutine();
+ bool requiresPreservingZT0(const SMEAttrs &Callee) const {
+ return hasZT0State() && !Callee.isUndefZT0() && !Callee.sharesZT0() &&
+ !Callee.hasAgnosticZAInterface();
}
-
- bool requiresPreservingZT0() const {
- return caller().hasZT0State() && !callsite().hasUndefZT0() &&
- !callee().sharesZT0() && !callee().hasAgnosticZAInterface();
+ bool requiresDisablingZABeforeCall(const SMEAttrs &Callee) const {
+ return hasZT0State() && !hasZAState() && Callee.ha...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/138664
More information about the llvm-commits
mailing list