LLVM 22.0.0git
AArch64SMEAttributes.cpp
Go to the documentation of this file.
1//===-- AArch64SMEAttributes.cpp - 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
10#include "AArch64ISelLowering.h"
11#include "llvm/IR/InstrTypes.h"
13#include <cassert>
14
15using namespace llvm;
16
17void SMEAttrs::validate() const {
18 // Streaming Mode Attrs
20 "SM_Enabled and SM_Compatible are mutually exclusive");
21
22 // ZA Attrs
23 assert(!(isNewZA() && (Bitmask & SME_ABI_Routine)) &&
24 "ZA_New and SME_ABI_Routine are mutually exclusive");
25
26 assert(
27 (isNewZA() + isInZA() + isOutZA() + isInOutZA() + isPreservesZA()) <= 1 &&
28 "Attributes 'aarch64_new_za', 'aarch64_in_za', 'aarch64_out_za', "
29 "'aarch64_inout_za' and 'aarch64_preserves_za' are mutually exclusive");
30
31 // ZT0 Attrs
32 assert(
34 1 &&
35 "Attributes 'aarch64_new_zt0', 'aarch64_in_zt0', 'aarch64_out_zt0', "
36 "'aarch64_inout_zt0' and 'aarch64_preserves_zt0' are mutually exclusive");
37
39 "Function cannot have a shared-ZA interface and an agnostic-ZA "
40 "interface");
41}
42
44 Bitmask = 0;
45 if (Attrs.hasFnAttr("aarch64_pstate_sm_enabled"))
46 Bitmask |= SM_Enabled;
47 if (Attrs.hasFnAttr("aarch64_pstate_sm_compatible"))
48 Bitmask |= SM_Compatible;
49 if (Attrs.hasFnAttr("aarch64_pstate_sm_body"))
50 Bitmask |= SM_Body;
51 if (Attrs.hasFnAttr("aarch64_za_state_agnostic"))
52 Bitmask |= ZA_State_Agnostic;
53 if (Attrs.hasFnAttr("aarch64_zt0_undef"))
54 Bitmask |= ZT0_Undef;
55 if (Attrs.hasFnAttr("aarch64_in_za"))
56 Bitmask |= encodeZAState(StateValue::In);
57 if (Attrs.hasFnAttr("aarch64_out_za"))
59 if (Attrs.hasFnAttr("aarch64_inout_za"))
61 if (Attrs.hasFnAttr("aarch64_preserves_za"))
63 if (Attrs.hasFnAttr("aarch64_new_za"))
65 if (Attrs.hasFnAttr("aarch64_in_zt0"))
67 if (Attrs.hasFnAttr("aarch64_out_zt0"))
69 if (Attrs.hasFnAttr("aarch64_inout_zt0"))
71 if (Attrs.hasFnAttr("aarch64_preserves_zt0"))
73 if (Attrs.hasFnAttr("aarch64_new_zt0"))
75}
76
77void SMEAttrs::addKnownFunctionAttrs(StringRef FuncName,
78 const AArch64TargetLowering &TLI) {
79 RTLIB::LibcallImpl Impl = TLI.getSupportedLibcallImpl(FuncName);
80 if (Impl == RTLIB::Unsupported)
81 return;
82 unsigned KnownAttrs = SMEAttrs::Normal;
83 RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
84 switch (LC) {
85 case RTLIB::SMEABI_SME_STATE:
86 case RTLIB::SMEABI_TPIDR2_SAVE:
87 case RTLIB::SMEABI_GET_CURRENT_VG:
88 case RTLIB::SMEABI_SME_STATE_SIZE:
89 case RTLIB::SMEABI_SME_SAVE:
90 case RTLIB::SMEABI_SME_RESTORE:
92 break;
93 case RTLIB::SMEABI_ZA_DISABLE:
94 case RTLIB::SMEABI_TPIDR2_RESTORE:
97 break;
98 case RTLIB::SC_MEMCPY:
99 case RTLIB::SC_MEMMOVE:
100 case RTLIB::SC_MEMSET:
101 case RTLIB::SC_MEMCHR:
102 KnownAttrs |= SMEAttrs::SM_Compatible;
103 break;
104 default:
105 break;
106 }
107 set(KnownAttrs);
108}
109
111 if (callee().hasStreamingCompatibleInterface())
112 return false;
113
114 // Both non-streaming
115 if (caller().hasNonStreamingInterfaceAndBody() &&
116 callee().hasNonStreamingInterface())
117 return false;
118
119 // Both streaming
120 if (caller().hasStreamingInterfaceOrBody() &&
121 callee().hasStreamingInterface())
122 return false;
123
124 return true;
125}
126
128 : CallerFn(*CB.getFunction()), CalledFn(SMEAttrs::Normal),
129 Callsite(CB.getAttributes()), IsIndirect(CB.isIndirectCall()) {
130 if (auto *CalledFunction = CB.getCalledFunction())
131 CalledFn = SMEAttrs(*CalledFunction, TLI);
132
133 // FIXME: We probably should not allow SME attributes on direct calls but
134 // clang duplicates streaming mode attributes at each callsite.
135 assert((IsIndirect ||
136 ((Callsite.withoutPerCallsiteFlags() | CalledFn) == CalledFn)) &&
137 "SME attributes at callsite do not match declaration");
138}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1348
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
bool isPreservesZT0() const
bool hasStreamingInterface() const
static unsigned encodeZAState(StateValue S)
SMEAttrs()=default
bool hasStreamingCompatibleInterface() const
bool hasAgnosticZAInterface() const
bool isInOutZT0() const
bool isInOutZA() const
bool isPreservesZA() const
SMEAttrs withoutPerCallsiteFlags() const
bool isNewZA() const
void set(unsigned M, bool Enable=true)
bool hasSharedZAInterface() const
static unsigned encodeZT0State(StateValue S)
SMECallAttrs(SMEAttrs Caller, SMEAttrs Callee, SMEAttrs Callsite=SMEAttrs::Normal)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const
Check if this is valid libcall for the current module, otherwise RTLIB::Unsupported.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
static bool isIndirectCall(const MachineInstr &MI)
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl)
Return the libcall provided by Impl.