brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 085c858 Raw
146 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "AArch64SMEAttributes.h"10#include "AArch64ISelLowering.h"11#include "llvm/IR/InstrTypes.h"12#include "llvm/IR/RuntimeLibcalls.h"13#include <cassert>14 15using namespace llvm;16 17void SMEAttrs::validate() const {18  // Streaming Mode Attrs19  assert(!(hasStreamingInterface() && hasStreamingCompatibleInterface()) &&20         "SM_Enabled and SM_Compatible are mutually exclusive");21 22  // ZA Attrs23  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 Attrs32  assert(33      (isNewZT0() + isInZT0() + isOutZT0() + isInOutZT0() + isPreservesZT0()) <=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 38  assert(!(hasAgnosticZAInterface() && hasSharedZAInterface()) &&39         "Function cannot have a shared-ZA interface and an agnostic-ZA "40         "interface");41}42 43SMEAttrs::SMEAttrs(const AttributeList &Attrs) {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"))58    Bitmask |= encodeZAState(StateValue::Out);59  if (Attrs.hasFnAttr("aarch64_inout_za"))60    Bitmask |= encodeZAState(StateValue::InOut);61  if (Attrs.hasFnAttr("aarch64_preserves_za"))62    Bitmask |= encodeZAState(StateValue::Preserved);63  if (Attrs.hasFnAttr("aarch64_new_za"))64    Bitmask |= encodeZAState(StateValue::New);65  if (Attrs.hasFnAttr("aarch64_in_zt0"))66    Bitmask |= encodeZT0State(StateValue::In);67  if (Attrs.hasFnAttr("aarch64_out_zt0"))68    Bitmask |= encodeZT0State(StateValue::Out);69  if (Attrs.hasFnAttr("aarch64_inout_zt0"))70    Bitmask |= encodeZT0State(StateValue::InOut);71  if (Attrs.hasFnAttr("aarch64_preserves_zt0"))72    Bitmask |= encodeZT0State(StateValue::Preserved);73  if (Attrs.hasFnAttr("aarch64_new_zt0"))74    Bitmask |= encodeZT0State(StateValue::New);75}76 77void SMEAttrs::addKnownFunctionAttrs(StringRef FuncName,78                                     const RTLIB::RuntimeLibcallsInfo &RTLCI) {79  RTLIB::LibcallImpl Impl = RTLCI.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:91    KnownAttrs |= SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine;92    break;93  case RTLIB::SMEABI_ZA_DISABLE:94  case RTLIB::SMEABI_TPIDR2_RESTORE:95    KnownAttrs |= SMEAttrs::SM_Compatible | encodeZAState(StateValue::In) |96                  SMEAttrs::SME_ABI_Routine;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 110bool SMECallAttrs::requiresSMChange() const {111  if (callee().hasStreamingCompatibleInterface())112    return false;113 114  // Both non-streaming115  if (caller().hasNonStreamingInterfaceAndBody() &&116      callee().hasNonStreamingInterface())117    return false;118 119  // Both streaming120  if (caller().hasStreamingInterfaceOrBody() &&121      callee().hasStreamingInterface())122    return false;123 124  return true;125}126 127SMECallAttrs::SMECallAttrs(const CallBase &CB,128                           const RTLIB::RuntimeLibcallsInfo *RTLCI)129    : CallerFn(*CB.getFunction()), CalledFn(SMEAttrs::Normal),130      Callsite(CB.getAttributes()), IsIndirect(CB.isIndirectCall()) {131  if (auto *CalledFunction = CB.getCalledFunction())132    CalledFn = SMEAttrs(*CalledFunction, RTLCI);133 134  // FIXME: We probably should not allow SME attributes on direct calls but135  // clang duplicates streaming mode attributes at each callsite.136  assert((IsIndirect ||137          ((Callsite.withoutPerCallsiteFlags() | CalledFn) == CalledFn)) &&138         "SME attributes at callsite do not match declaration");139 140  // An `invoke` of an agnostic ZA function may not return normally (it may141  // resume in an exception block). In this case, it acts like a private ZA142  // callee and may require a ZA save to be set up before it is called.143  if (isa<InvokeInst>(CB))144    CalledFn.set(SMEAttrs::ZA_State_Agnostic, /*Enable=*/false);145}146