AArch64SMEAttributes.cpp 2.4 KB

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