MLIR  19.0.0git
EnableArmStreaming.cpp
Go to the documentation of this file.
1 //===- EnableArmStreaming.cpp - Enable Armv9 Streaming SVE mode -----------===//
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 //
9 // This pass enables the Armv9 Scalable Matrix Extension (SME) Streaming SVE
10 // (SSVE) mode [1][2] by adding either of the following attributes to
11 // 'func.func' ops:
12 //
13 // * 'arm_streaming' (default)
14 // * 'arm_locally_streaming'
15 //
16 // It can also optionally enable the ZA storage array.
17 //
18 // Streaming-mode is part of the interface (ABI) for functions with the
19 // first attribute and it's the responsibility of the caller to manage
20 // PSTATE.SM on entry/exit to functions with this attribute [3]. The LLVM
21 // backend will emit 'smstart sm' / 'smstop sm' [4] around calls to
22 // streaming functions.
23 //
24 // In locally streaming functions PSTATE.SM is kept internal and managed by
25 // the callee on entry/exit. The LLVM backend will emit 'smstart sm' /
26 // 'smstop sm' in the prologue / epilogue for functions with this
27 // attribute.
28 //
29 // [1] https://developer.arm.com/documentation/ddi0616/aa
30 // [2] https://llvm.org/docs/AArch64SME.html
31 // [3] https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#671pstatesm-interfaces
32 // [4] https://developer.arm.com/documentation/ddi0602/2023-03/Base-Instructions/SMSTART--Enables-access-to-Streaming-SVE-mode-and-SME-architectural-state--an-alias-of-MSR--immediate--
33 //
34 //===----------------------------------------------------------------------===//
35 
38 #include "mlir/Dialect/ArmSME/Transforms/PassesEnums.cpp.inc"
39 
41 
42 #define DEBUG_TYPE "enable-arm-streaming"
43 
44 namespace mlir {
45 namespace arm_sme {
46 #define GEN_PASS_DEF_ENABLEARMSTREAMING
47 #include "mlir/Dialect/ArmSME/Transforms/Passes.h.inc"
48 } // namespace arm_sme
49 } // namespace mlir
50 
51 using namespace mlir;
52 using namespace mlir::arm_sme;
53 namespace {
54 
55 constexpr StringLiteral
56  kEnableArmStreamingIgnoreAttr("enable_arm_streaming_ignore");
57 
58 struct EnableArmStreamingPass
59  : public arm_sme::impl::EnableArmStreamingBase<EnableArmStreamingPass> {
60  EnableArmStreamingPass(ArmStreamingMode streamingMode, ArmZaMode zaMode,
61  bool onlyIfRequiredByOps) {
62  this->streamingMode = streamingMode;
63  this->zaMode = zaMode;
64  this->onlyIfRequiredByOps = onlyIfRequiredByOps;
65  }
66  void runOnOperation() override {
67  auto op = getOperation();
68 
69  if (onlyIfRequiredByOps) {
70  bool foundTileOp = false;
71  op.walk([&](Operation *op) {
72  if (llvm::isa<ArmSMETileOpInterface>(op)) {
73  foundTileOp = true;
74  return WalkResult::interrupt();
75  }
76  return WalkResult::advance();
77  });
78  if (!foundTileOp)
79  return;
80  }
81 
82  if (op->getAttr(kEnableArmStreamingIgnoreAttr) ||
83  streamingMode == ArmStreamingMode::Disabled)
84  return;
85 
86  auto unitAttr = UnitAttr::get(&getContext());
87 
88  op->setAttr(stringifyArmStreamingMode(streamingMode), unitAttr);
89 
90  // The pass currently only supports enabling ZA when in streaming-mode, but
91  // ZA can be accessed by the SME LDR, STR and ZERO instructions when not in
92  // streaming-mode (see section B1.1.1, IDGNQM of spec [1]). It may be worth
93  // supporting this later.
94  if (zaMode != ArmZaMode::Disabled)
95  op->setAttr(stringifyArmZaMode(zaMode), unitAttr);
96  }
97 };
98 } // namespace
99 
101  const ArmStreamingMode streamingMode, const ArmZaMode zaMode,
102  bool onlyIfRequiredByOps) {
103  return std::make_unique<EnableArmStreamingPass>(streamingMode, zaMode,
104  onlyIfRequiredByOps);
105 }
static MLIRContext * getContext(OpFoldResult val)
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:529
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
Definition: Operation.h:793
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition: Operation.h:577
static WalkResult advance()
Definition: Visitors.h:52
static WalkResult interrupt()
Definition: Visitors.h:51
std::unique_ptr< Pass > createEnableArmStreamingPass(const ArmStreamingMode=ArmStreamingMode::Streaming, const ArmZaMode=ArmZaMode::Disabled, bool onlyIfRequiredByOps=false)
Pass to enable Armv9 Streaming SVE mode.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...