xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.h (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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 
14 namespace llvm {
15 
16 class Function;
17 class CallBase;
18 class AttributeList;
19 
20 /// SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
21 /// It helps determine a function's requirements for PSTATE.ZA and PSTATE.SM. It
22 /// has interfaces to query whether a streaming mode change or lazy-save
23 /// mechanism is required when going from one function to another (e.g. through
24 /// a call).
25 class SMEAttrs {
26   unsigned Bitmask;
27 
28 public:
29   // Enum with bitmasks for each individual SME feature.
30   enum Mask {
31     Normal = 0,
32     SM_Enabled = 1 << 0,    // aarch64_pstate_sm_enabled
33     SM_Compatible = 1 << 1, // aarch64_pstate_sm_compatible
34     SM_Body = 1 << 2,       // aarch64_pstate_sm_body
35     ZA_Shared = 1 << 3,     // aarch64_pstate_sm_shared
36     ZA_New = 1 << 4,        // aarch64_pstate_sm_new
37     ZA_Preserved = 1 << 5,  // aarch64_pstate_sm_preserved
38     ZA_NoLazySave = 1 << 6, // Used for SME ABI routines to avoid lazy saves
39     All = ZA_Preserved - 1
40   };
41 
42   SMEAttrs(unsigned Mask = Normal) : Bitmask(0) { set(Mask); }
43   SMEAttrs(const Function &F) : SMEAttrs(F.getAttributes()) {}
44   SMEAttrs(const CallBase &CB);
45   SMEAttrs(const AttributeList &L);
46   SMEAttrs(StringRef FuncName);
47 
48   void set(unsigned M, bool Enable = true);
49 
50   // Interfaces to query PSTATE.SM
51   bool hasStreamingBody() const { return Bitmask & SM_Body; }
52   bool hasStreamingInterface() const { return Bitmask & SM_Enabled; }
53   bool hasStreamingInterfaceOrBody() const {
54     return hasStreamingBody() || hasStreamingInterface();
55   }
56   bool hasStreamingCompatibleInterface() const {
57     return Bitmask & SM_Compatible;
58   }
59   bool hasNonStreamingInterface() const {
60     return !hasStreamingInterface() && !hasStreamingCompatibleInterface();
61   }
62   bool hasNonStreamingInterfaceAndBody() const {
63     return hasNonStreamingInterface() && !hasStreamingBody();
64   }
65 
66   /// \return true if a call from Caller -> Callee requires a change in
67   /// streaming mode.
68   /// If \p BodyOverridesInterface is true and Callee has a streaming body,
69   /// then requiresSMChange considers a call to Callee as having a Streaming
70   /// interface. This can be useful when considering e.g. inlining, where we
71   /// explicitly want the body to overrule the interface (because after inlining
72   /// the interface is no longer relevant).
73   std::optional<bool>
74   requiresSMChange(const SMEAttrs &Callee,
75                    bool BodyOverridesInterface = false) const;
76 
77   // Interfaces to query PSTATE.ZA
78   bool hasNewZABody() const { return Bitmask & ZA_New; }
79   bool hasSharedZAInterface() const { return Bitmask & ZA_Shared; }
80   bool hasPrivateZAInterface() const { return !hasSharedZAInterface(); }
81   bool preservesZA() const { return Bitmask & ZA_Preserved; }
82   bool hasZAState() const {
83     return hasNewZABody() || hasSharedZAInterface();
84   }
85   bool requiresLazySave(const SMEAttrs &Callee) const {
86     return hasZAState() && Callee.hasPrivateZAInterface() &&
87            !(Callee.Bitmask & ZA_NoLazySave);
88   }
89 };
90 
91 } // namespace llvm
92 
93 #endif // LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64SMEATTRIBUTES_H
94