llvm-project/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp
Sander de Smalen cf72dddaef [AArch64][SME] Add utility class for handling SME attributes.
This patch adds a utility class that will be used in subsequent patches
for parsing the function/callsite attributes and determining whether
changes to PSTATE.SM are needed, or whether a lazy-save mechanism is
required.

It also implements some of the restrictions on the SME attributes
in the IR Verifier pass.

More details about the SME attributes and design can be found
in D131562.

Reviewed By: david-arm, aemerson

Differential Revision: https://reviews.llvm.org/D131570
2022-09-12 12:41:30 +00:00

74 lines
2.4 KiB
C++

//===-- AArch64SMEAttributes.cpp - Helper for interpreting SME attributes -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "AArch64SMEAttributes.h"
#include "llvm/ADT/None.h"
#include "llvm/IR/InstrTypes.h"
#include <cassert>
using namespace llvm;
void SMEAttrs::set(unsigned M, bool Enable) {
if (Enable)
Bitmask |= M;
else
Bitmask &= ~M;
assert(!(hasStreamingInterface() && hasStreamingCompatibleInterface()) &&
"SM_Enabled and SM_Compatible are mutually exclusive");
assert(!(hasNewZAInterface() && hasSharedZAInterface()) &&
"ZA_New and ZA_Shared are mutually exclusive");
assert(!(hasNewZAInterface() && preservesZA()) &&
"ZA_New and ZA_Preserved are mutually exclusive");
}
SMEAttrs::SMEAttrs(const CallBase &CB) {
*this = SMEAttrs(CB.getAttributes());
if (auto *F = CB.getCalledFunction())
set(SMEAttrs(*F).Bitmask);
}
SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
Bitmask = 0;
if (Attrs.hasFnAttr("aarch64_pstate_sm_enabled"))
Bitmask |= SM_Enabled;
if (Attrs.hasFnAttr("aarch64_pstate_sm_compatible"))
Bitmask |= SM_Compatible;
if (Attrs.hasFnAttr("aarch64_pstate_sm_body"))
Bitmask |= SM_Body;
if (Attrs.hasFnAttr("aarch64_pstate_za_shared"))
Bitmask |= ZA_Shared;
if (Attrs.hasFnAttr("aarch64_pstate_za_new"))
Bitmask |= ZA_New;
if (Attrs.hasFnAttr("aarch64_pstate_za_preserved"))
Bitmask |= ZA_Preserved;
}
Optional<bool> SMEAttrs::requiresSMChange(const SMEAttrs &Callee,
bool BodyOverridesInterface) const {
// If the transition is not through a call (e.g. when considering inlining)
// and Callee has a streaming body, then we can ignore the interface of
// Callee.
if (BodyOverridesInterface && Callee.hasStreamingBody()) {
return hasStreamingInterfaceOrBody() ? None : Optional<bool>(true);
}
if (Callee.hasStreamingCompatibleInterface())
return None;
// Both non-streaming
if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface())
return None;
// Both streaming
if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface())
return None;
return Callee.hasStreamingInterface();
}