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