LLVM 22.0.0git
AArch64SMEAttributes.h
Go to the documentation of this file.
1//===-- AArch64SMEAttributes.h - Helper for interpreting SME attributes -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64SMEATTRIBUTES_H
10#define LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64SMEATTRIBUTES_H
11
12#include "llvm/IR/Function.h"
13
14namespace llvm {
15
17
18class Function;
19class CallBase;
20class AttributeList;
21
22/// SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
23/// It helps determine a function's requirements for PSTATE.ZA and PSTATE.SM.
24class SMEAttrs {
25 unsigned Bitmask = Normal;
26
27public:
28 enum class StateValue {
29 None = 0,
30 In = 1, // aarch64_in_zt0
31 Out = 2, // aarch64_out_zt0
32 InOut = 3, // aarch64_inout_zt0
33 Preserved = 4, // aarch64_preserves_zt0
34 New = 5 // aarch64_new_zt0
35 };
36
37 // Enum with bitmasks for each individual SME feature.
38 enum Mask {
39 Normal = 0,
40 SM_Enabled = 1 << 0, // aarch64_pstate_sm_enabled
41 SM_Compatible = 1 << 1, // aarch64_pstate_sm_compatible
42 SM_Body = 1 << 2, // aarch64_pstate_sm_body
43 SME_ABI_Routine = 1 << 3, // Used for SME ABI routines to avoid lazy saves
45 ZT0_Undef = 1 << 5, // Use to mark ZT0 as undef to avoid spills
47 ZA_Mask = 0b111 << ZA_Shift,
49 ZT0_Mask = 0b111 << ZT0_Shift,
51 };
52
53 SMEAttrs() = default;
54 SMEAttrs(unsigned Mask) { set(Mask); }
55 SMEAttrs(const Function &F, const AArch64TargetLowering *TLI = nullptr)
56 : SMEAttrs(F.getAttributes()) {
57 if (TLI)
58 addKnownFunctionAttrs(F.getName(), *TLI);
59 }
60 SMEAttrs(const AttributeList &L);
62 addKnownFunctionAttrs(FuncName, TLI);
63 };
64
65 void set(unsigned M, bool Enable = true) {
66 if (Enable)
67 Bitmask |= M;
68 else
69 Bitmask &= ~M;
70#ifndef NDEBUG
71 validate();
72#endif
73 }
74
75 // Interfaces to query PSTATE.SM
76 bool hasStreamingBody() const { return Bitmask & SM_Body; }
77 bool hasStreamingInterface() const { return Bitmask & SM_Enabled; }
82 return Bitmask & SM_Compatible;
83 }
90
91 // Interfaces to query ZA
92 static StateValue decodeZAState(unsigned Bitmask) {
93 return static_cast<StateValue>((Bitmask & ZA_Mask) >> ZA_Shift);
94 }
95 static unsigned encodeZAState(StateValue S) {
96 return static_cast<unsigned>(S) << ZA_Shift;
97 }
98
99 bool isNewZA() const { return decodeZAState(Bitmask) == StateValue::New; }
100 bool isInZA() const { return decodeZAState(Bitmask) == StateValue::In; }
101 bool isOutZA() const { return decodeZAState(Bitmask) == StateValue::Out; }
102 bool isInOutZA() const { return decodeZAState(Bitmask) == StateValue::InOut; }
103 bool isPreservesZA() const {
104 return decodeZAState(Bitmask) == StateValue::Preserved;
105 }
106 bool sharesZA() const {
107 StateValue State = decodeZAState(Bitmask);
108 return State == StateValue::In || State == StateValue::Out ||
109 State == StateValue::InOut || State == StateValue::Preserved;
110 }
111 bool hasAgnosticZAInterface() const { return Bitmask & ZA_State_Agnostic; }
112 bool hasSharedZAInterface() const { return sharesZA() || sharesZT0(); }
115 }
116 bool hasZAState() const { return isNewZA() || sharesZA(); }
117 bool isSMEABIRoutine() const { return Bitmask & SME_ABI_Routine; }
118
119 // Interfaces to query ZT0 State
120 static StateValue decodeZT0State(unsigned Bitmask) {
121 return static_cast<StateValue>((Bitmask & ZT0_Mask) >> ZT0_Shift);
122 }
123 static unsigned encodeZT0State(StateValue S) {
124 return static_cast<unsigned>(S) << ZT0_Shift;
125 }
126
127 bool isNewZT0() const { return decodeZT0State(Bitmask) == StateValue::New; }
128 bool isInZT0() const { return decodeZT0State(Bitmask) == StateValue::In; }
129 bool isOutZT0() const { return decodeZT0State(Bitmask) == StateValue::Out; }
130 bool isInOutZT0() const {
131 return decodeZT0State(Bitmask) == StateValue::InOut;
132 }
133 bool isPreservesZT0() const {
134 return decodeZT0State(Bitmask) == StateValue::Preserved;
135 }
136 bool hasUndefZT0() const { return Bitmask & ZT0_Undef; }
137 bool sharesZT0() const {
138 StateValue State = decodeZT0State(Bitmask);
139 return State == StateValue::In || State == StateValue::Out ||
140 State == StateValue::InOut || State == StateValue::Preserved;
141 }
142 bool hasZT0State() const { return isNewZT0() || sharesZT0(); }
143
145 SMEAttrs Merged(*this);
146 Merged.set(Other.Bitmask);
147 return Merged;
148 }
149
151 return (Bitmask & ~CallSiteFlags_Mask);
152 }
153
154 bool operator==(SMEAttrs const &Other) const {
155 return Bitmask == Other.Bitmask;
156 }
157
158private:
159 void addKnownFunctionAttrs(StringRef FuncName,
160 const AArch64TargetLowering &TLI);
161 void validate() const;
162};
163
164/// SMECallAttrs is a utility class to hold the SMEAttrs for a callsite. It has
165/// interfaces to query whether a streaming mode change or lazy-save mechanism
166/// is required when going from one function to another (e.g. through a call).
168 SMEAttrs CallerFn;
169 SMEAttrs CalledFn;
170 SMEAttrs Callsite;
171 bool IsIndirect = false;
172
173public:
175 SMEAttrs Callsite = SMEAttrs::Normal)
176 : CallerFn(Caller), CalledFn(Callee), Callsite(Callsite) {}
177
178 SMECallAttrs(const CallBase &CB, const AArch64TargetLowering *TLI);
179
180 SMEAttrs &caller() { return CallerFn; }
181 SMEAttrs &callee() { return IsIndirect ? Callsite : CalledFn; }
182 SMEAttrs &callsite() { return Callsite; }
183 SMEAttrs const &caller() const { return CallerFn; }
184 SMEAttrs const &callee() const {
185 return const_cast<SMECallAttrs *>(this)->callee();
186 }
187 SMEAttrs const &callsite() const { return Callsite; }
188
189 /// \return true if a call from Caller -> Callee requires a change in
190 /// streaming mode.
191 bool requiresSMChange() const;
192
193 bool requiresLazySave() const {
194 return caller().hasZAState() && callee().hasPrivateZAInterface() &&
196 }
197
199 return caller().hasZT0State() && !callsite().hasUndefZT0() &&
201 }
202
207
211
216};
217
218} // namespace llvm
219
220#endif // LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64SMEATTRIBUTES_H
#define F(x, y, z)
Definition MD5.cpp:55
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
bool isPreservesZT0() const
bool hasStreamingInterface() const
static unsigned encodeZAState(StateValue S)
bool hasNonStreamingInterfaceAndBody() const
SMEAttrs()=default
SMEAttrs(unsigned Mask)
bool hasStreamingCompatibleInterface() const
SMEAttrs operator|(SMEAttrs Other) const
bool hasAgnosticZAInterface() const
SMEAttrs(const Function &F, const AArch64TargetLowering *TLI=nullptr)
bool hasStreamingInterfaceOrBody() const
static StateValue decodeZAState(unsigned Bitmask)
bool hasNonStreamingInterface() const
bool isSMEABIRoutine() const
bool operator==(SMEAttrs const &Other) const
static StateValue decodeZT0State(unsigned Bitmask)
bool hasStreamingBody() const
bool isPreservesZA() const
SMEAttrs withoutPerCallsiteFlags() const
bool hasPrivateZAInterface() const
void set(unsigned M, bool Enable=true)
bool hasSharedZAInterface() const
SMEAttrs(StringRef FuncName, const AArch64TargetLowering &TLI)
static unsigned encodeZT0State(StateValue S)
bool requiresEnablingZAAfterCall() const
bool requiresPreservingZT0() const
SMEAttrs const & callsite() const
SMECallAttrs(SMEAttrs Caller, SMEAttrs Callee, SMEAttrs Callsite=SMEAttrs::Normal)
bool requiresDisablingZABeforeCall() const
SMEAttrs const & caller() const
SMEAttrs const & callee() const
bool requiresPreservingAllZAState() const
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
This is an optimization pass for GlobalISel generic memory operations.
@ Other
Any other memory.
Definition ModRef.h:68
@ Enable
Enable colors.
Definition WithColor.h:47