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 9 #include "AArch64SMEAttributes.h" 10 #include "llvm/IR/InstrTypes.h" 11 #include <cassert> 12 13 using namespace llvm; 14 15 void SMEAttrs::set(unsigned M, bool Enable) { 16 if (Enable) 17 Bitmask |= M; 18 else 19 Bitmask &= ~M; 20 21 assert(!(hasStreamingInterface() && hasStreamingCompatibleInterface()) && 22 "SM_Enabled and SM_Compatible are mutually exclusive"); 23 assert(!(hasNewZAInterface() && hasSharedZAInterface()) && 24 "ZA_New and ZA_Shared are mutually exclusive"); 25 assert(!(hasNewZAInterface() && preservesZA()) && 26 "ZA_New and ZA_Preserved are mutually exclusive"); 27 } 28 29 SMEAttrs::SMEAttrs(const CallBase &CB) { 30 *this = SMEAttrs(CB.getAttributes()); 31 if (auto *F = CB.getCalledFunction()) 32 set(SMEAttrs(*F).Bitmask); 33 } 34 35 SMEAttrs::SMEAttrs(const AttributeList &Attrs) { 36 Bitmask = 0; 37 if (Attrs.hasFnAttr("aarch64_pstate_sm_enabled")) 38 Bitmask |= SM_Enabled; 39 if (Attrs.hasFnAttr("aarch64_pstate_sm_compatible")) 40 Bitmask |= SM_Compatible; 41 if (Attrs.hasFnAttr("aarch64_pstate_sm_body")) 42 Bitmask |= SM_Body; 43 if (Attrs.hasFnAttr("aarch64_pstate_za_shared")) 44 Bitmask |= ZA_Shared; 45 if (Attrs.hasFnAttr("aarch64_pstate_za_new")) 46 Bitmask |= ZA_New; 47 if (Attrs.hasFnAttr("aarch64_pstate_za_preserved")) 48 Bitmask |= ZA_Preserved; 49 } 50 51 std::optional<bool> 52 SMEAttrs::requiresSMChange(const SMEAttrs &Callee, 53 bool BodyOverridesInterface) const { 54 // If the transition is not through a call (e.g. when considering inlining) 55 // and Callee has a streaming body, then we can ignore the interface of 56 // Callee. 57 if (BodyOverridesInterface && Callee.hasStreamingBody()) { 58 return hasStreamingInterfaceOrBody() ? std::nullopt 59 : std::optional<bool>(true); 60 } 61 62 if (Callee.hasStreamingCompatibleInterface()) 63 return std::nullopt; 64 65 // Both non-streaming 66 if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface()) 67 return std::nullopt; 68 69 // Both streaming 70 if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface()) 71 return std::nullopt; 72 73 return Callee.hasStreamingInterface(); 74 } 75