CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
206 lines
6.9 KiB
C++
206 lines
6.9 KiB
C++
//===-- AArch64SMEAttributes.h - 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64SMEATTRIBUTES_H
|
|
#define LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64SMEATTRIBUTES_H
|
|
|
|
#include "llvm/IR/Function.h"
|
|
|
|
namespace llvm {
|
|
namespace RTLIB {
|
|
struct RuntimeLibcallsInfo;
|
|
}
|
|
|
|
class Function;
|
|
class CallBase;
|
|
class AttributeList;
|
|
|
|
/// SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
|
|
/// It helps determine a function's requirements for PSTATE.ZA and PSTATE.SM.
|
|
class SMEAttrs {
|
|
unsigned Bitmask = Normal;
|
|
|
|
public:
|
|
enum class StateValue {
|
|
None = 0,
|
|
In = 1, // aarch64_in_zt0
|
|
Out = 2, // aarch64_out_zt0
|
|
InOut = 3, // aarch64_inout_zt0
|
|
Preserved = 4, // aarch64_preserves_zt0
|
|
New = 5 // aarch64_new_zt0
|
|
};
|
|
|
|
// Enum with bitmasks for each individual SME feature.
|
|
enum Mask {
|
|
Normal = 0,
|
|
SM_Enabled = 1 << 0, // aarch64_pstate_sm_enabled
|
|
SM_Compatible = 1 << 1, // aarch64_pstate_sm_compatible
|
|
SM_Body = 1 << 2, // aarch64_pstate_sm_body
|
|
SME_ABI_Routine = 1 << 3, // Used for SME ABI routines to avoid lazy saves
|
|
ZA_State_Agnostic = 1 << 4,
|
|
ZA_Shift = 6,
|
|
ZA_Mask = 0b111 << ZA_Shift,
|
|
ZT0_Shift = 9,
|
|
ZT0_Mask = 0b111 << ZT0_Shift
|
|
};
|
|
|
|
SMEAttrs() = default;
|
|
SMEAttrs(unsigned Mask) { set(Mask); }
|
|
SMEAttrs(const Function &F, const RTLIB::RuntimeLibcallsInfo *RTLCI = nullptr)
|
|
: SMEAttrs(F.getAttributes()) {
|
|
if (RTLCI)
|
|
addKnownFunctionAttrs(F.getName(), *RTLCI);
|
|
}
|
|
SMEAttrs(const AttributeList &L);
|
|
SMEAttrs(StringRef FuncName, const RTLIB::RuntimeLibcallsInfo &RTLCI) {
|
|
addKnownFunctionAttrs(FuncName, RTLCI);
|
|
};
|
|
|
|
void set(unsigned M, bool Enable = true) {
|
|
if (Enable)
|
|
Bitmask |= M;
|
|
else
|
|
Bitmask &= ~M;
|
|
#ifndef NDEBUG
|
|
validate();
|
|
#endif
|
|
}
|
|
|
|
// Interfaces to query PSTATE.SM
|
|
bool hasStreamingBody() const { return Bitmask & SM_Body; }
|
|
bool hasStreamingInterface() const { return Bitmask & SM_Enabled; }
|
|
bool hasStreamingInterfaceOrBody() const {
|
|
return hasStreamingBody() || hasStreamingInterface();
|
|
}
|
|
bool hasStreamingCompatibleInterface() const {
|
|
return Bitmask & SM_Compatible;
|
|
}
|
|
bool hasNonStreamingInterface() const {
|
|
return !hasStreamingInterface() && !hasStreamingCompatibleInterface();
|
|
}
|
|
bool hasNonStreamingInterfaceAndBody() const {
|
|
return hasNonStreamingInterface() && !hasStreamingBody();
|
|
}
|
|
|
|
// Interfaces to query ZA
|
|
static StateValue decodeZAState(unsigned Bitmask) {
|
|
return static_cast<StateValue>((Bitmask & ZA_Mask) >> ZA_Shift);
|
|
}
|
|
static unsigned encodeZAState(StateValue S) {
|
|
return static_cast<unsigned>(S) << ZA_Shift;
|
|
}
|
|
|
|
bool isNewZA() const { return decodeZAState(Bitmask) == StateValue::New; }
|
|
bool isInZA() const { return decodeZAState(Bitmask) == StateValue::In; }
|
|
bool isOutZA() const { return decodeZAState(Bitmask) == StateValue::Out; }
|
|
bool isInOutZA() const { return decodeZAState(Bitmask) == StateValue::InOut; }
|
|
bool isPreservesZA() const {
|
|
return decodeZAState(Bitmask) == StateValue::Preserved;
|
|
}
|
|
bool sharesZA() const {
|
|
StateValue State = decodeZAState(Bitmask);
|
|
return State == StateValue::In || State == StateValue::Out ||
|
|
State == StateValue::InOut || State == StateValue::Preserved;
|
|
}
|
|
bool hasAgnosticZAInterface() const { return Bitmask & ZA_State_Agnostic; }
|
|
bool hasSharedZAInterface() const { return sharesZA() || sharesZT0(); }
|
|
bool hasPrivateZAInterface() const {
|
|
return !hasSharedZAInterface() && !hasAgnosticZAInterface();
|
|
}
|
|
bool hasZAState() const { return isNewZA() || sharesZA(); }
|
|
bool isSMEABIRoutine() const { return Bitmask & SME_ABI_Routine; }
|
|
|
|
// Interfaces to query ZT0 State
|
|
static StateValue decodeZT0State(unsigned Bitmask) {
|
|
return static_cast<StateValue>((Bitmask & ZT0_Mask) >> ZT0_Shift);
|
|
}
|
|
static unsigned encodeZT0State(StateValue S) {
|
|
return static_cast<unsigned>(S) << ZT0_Shift;
|
|
}
|
|
|
|
bool isNewZT0() const { return decodeZT0State(Bitmask) == StateValue::New; }
|
|
bool isInZT0() const { return decodeZT0State(Bitmask) == StateValue::In; }
|
|
bool isOutZT0() const { return decodeZT0State(Bitmask) == StateValue::Out; }
|
|
bool isInOutZT0() const {
|
|
return decodeZT0State(Bitmask) == StateValue::InOut;
|
|
}
|
|
bool isPreservesZT0() const {
|
|
return decodeZT0State(Bitmask) == StateValue::Preserved;
|
|
}
|
|
bool sharesZT0() const {
|
|
StateValue State = decodeZT0State(Bitmask);
|
|
return State == StateValue::In || State == StateValue::Out ||
|
|
State == StateValue::InOut || State == StateValue::Preserved;
|
|
}
|
|
bool hasZT0State() const { return isNewZT0() || sharesZT0(); }
|
|
|
|
SMEAttrs operator|(SMEAttrs Other) const {
|
|
SMEAttrs Merged(*this);
|
|
Merged.set(Other.Bitmask);
|
|
return Merged;
|
|
}
|
|
|
|
bool operator==(SMEAttrs const &Other) const {
|
|
return Bitmask == Other.Bitmask;
|
|
}
|
|
|
|
private:
|
|
void addKnownFunctionAttrs(StringRef FuncName,
|
|
const RTLIB::RuntimeLibcallsInfo &RTLCI);
|
|
void validate() const;
|
|
};
|
|
|
|
/// SMECallAttrs is a utility class to hold the SMEAttrs for a callsite. It has
|
|
/// interfaces to query whether a streaming mode change or lazy-save mechanism
|
|
/// is required when going from one function to another (e.g. through a call).
|
|
class SMECallAttrs {
|
|
SMEAttrs CallerFn;
|
|
SMEAttrs CalledFn;
|
|
SMEAttrs Callsite;
|
|
bool IsIndirect = false;
|
|
|
|
public:
|
|
SMECallAttrs(SMEAttrs Caller, SMEAttrs Callee,
|
|
SMEAttrs Callsite = SMEAttrs::Normal)
|
|
: CallerFn(Caller), CalledFn(Callee), Callsite(Callsite) {}
|
|
|
|
SMECallAttrs(const CallBase &CB, const RTLIB::RuntimeLibcallsInfo *RTLCI);
|
|
|
|
SMEAttrs &caller() { return CallerFn; }
|
|
SMEAttrs &callee() { return IsIndirect ? Callsite : CalledFn; }
|
|
SMEAttrs &callsite() { return Callsite; }
|
|
SMEAttrs const &caller() const { return CallerFn; }
|
|
SMEAttrs const &callee() const {
|
|
return const_cast<SMECallAttrs *>(this)->callee();
|
|
}
|
|
SMEAttrs const &callsite() const { return Callsite; }
|
|
|
|
/// \return true if a call from Caller -> Callee requires a change in
|
|
/// streaming mode.
|
|
bool requiresSMChange() const;
|
|
|
|
bool requiresLazySave() const {
|
|
return caller().hasZAState() && callee().hasPrivateZAInterface() &&
|
|
!callee().isSMEABIRoutine();
|
|
}
|
|
|
|
bool requiresPreservingZT0() const {
|
|
return caller().hasZT0State() && !callee().sharesZT0() &&
|
|
!callee().hasAgnosticZAInterface();
|
|
}
|
|
|
|
bool requiresPreservingAllZAState() const {
|
|
return caller().hasAgnosticZAInterface() &&
|
|
!callee().hasAgnosticZAInterface() && !callee().isSMEABIRoutine();
|
|
}
|
|
};
|
|
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64SMEATTRIBUTES_H
|