Skip to content

Commit 1264849

Browse files
committed
[mlir] Add pass to enable Armv9 Streaming SVE mode
This patch adds a pass 'enable-arm-streaming' that enables the Armv9 Scalable Matrix Extension (SME) Streaming SVE (SSVE) mode [1] by adding either of the following attributes to 'func.func' ops: * arm_streaming (default) * arm_locally_streaming PATCH [2 / 2] in series for RFC: https://discourse.llvm.org/t/rfc-supporting-armv9-scalable-matrix-extension-sme-streaming-sve-ssve-mode-in-mlir/70678 [1] https://developer.arm.com/documentation/ddi0616/aa Reviewed By: awarzynski, dcaballe Differential Revision: https://reviews.llvm.org/D150934
1 parent 7d46590 commit 1264849

File tree

11 files changed

+190
-0
lines changed

11 files changed

+190
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(Transforms)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
set(LLVM_TARGET_DEFINITIONS Passes.td)
2+
mlir_tablegen(Passes.h.inc -gen-pass-decls -name ArmSME)
3+
add_public_tablegen_target(MLIRArmSMETransformsIncGen)
4+
5+
add_mlir_doc(Passes ArmSMEPasses ./ -gen-pass-doc)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===- Passes.h - Pass Entrypoints ------------------------------*- C++ -*-===//
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+
#ifndef MLIR_DIALECT_ARMSME_TRANSFORMS_PASSES_H
10+
#define MLIR_DIALECT_ARMSME_TRANSFORMS_PASSES_H
11+
12+
#include "mlir/Pass/Pass.h"
13+
14+
namespace mlir {
15+
16+
class RewritePatternSet;
17+
18+
namespace arm_sme {
19+
// Options for Armv9 Streaming SVE mode. By default, streaming-mode is part of
20+
// the function interface (ABI) and the caller manages PSTATE.SM on entry/exit.
21+
// In a locally streaming function PSTATE.SM is kept internal and the callee
22+
// manages it on entry/exit.
23+
enum class ArmStreaming { Default = 0, Locally = 1 };
24+
25+
#define GEN_PASS_DECL
26+
#include "mlir/Dialect/ArmSME/Transforms/Passes.h.inc"
27+
28+
/// Pass to enable Armv9 Streaming SVE mode.
29+
std::unique_ptr<Pass>
30+
createEnableArmStreamingPass(const ArmStreaming mode = ArmStreaming::Default);
31+
32+
//===----------------------------------------------------------------------===//
33+
// Registration
34+
//===----------------------------------------------------------------------===//
35+
36+
/// Generate the code for registering passes.
37+
#define GEN_PASS_REGISTRATION
38+
#include "mlir/Dialect/ArmSME/Transforms/Passes.h.inc"
39+
40+
} // namespace arm_sme
41+
} // namespace mlir
42+
43+
#endif // MLIR_DIALECT_ARMSME_TRANSFORMS_PASSES_H
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===-- Passes.td - ArmSME pass definition file ------------*- tablegen -*-===//
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+
#ifndef MLIR_DIALECT_ARMSME_TRANSFORMS_PASSES_TD
10+
#define MLIR_DIALECT_ARMSME_TRANSFORMS_PASSES_TD
11+
12+
include "mlir/Pass/PassBase.td"
13+
14+
def EnableArmStreaming
15+
: Pass<"enable-arm-streaming", "mlir::func::FuncOp"> {
16+
let summary = "Enable Armv9 Streaming SVE mode";
17+
let description = [{
18+
Enables the Armv9 Streaming SVE mode [1] for func.func ops by annotating
19+
them with attributes. See options for more details.
20+
21+
[1] https://developer.arm.com/documentation/ddi0616/aa
22+
}];
23+
let constructor = "mlir::arm_sme::createEnableArmStreamingPass()";
24+
let options = [
25+
Option<"mode", "mode", "mlir::arm_sme::ArmStreaming",
26+
/*default=*/"mlir::arm_sme::ArmStreaming::Default",
27+
"Select how streaming-mode is managed at the function-level.",
28+
[{::llvm::cl::values(
29+
clEnumValN(mlir::arm_sme::ArmStreaming::Default, "default",
30+
"Streaming mode is part of the function interface "
31+
"(ABI), caller manages PSTATE.SM on entry/exit."),
32+
clEnumValN(mlir::arm_sme::ArmStreaming::Locally, "locally",
33+
"Streaming mode is internal to the function, callee "
34+
"manages PSTATE.SM on entry/exit.")
35+
)}]>,
36+
];
37+
let dependentDialects = ["func::FuncDialect"];
38+
}
39+
40+
#endif // MLIR_DIALECT_ARMSME_TRANSFORMS_PASSES_TD

mlir/include/mlir/Dialect/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_subdirectory(AMX)
33
add_subdirectory(Affine)
44
add_subdirectory(Arith)
55
add_subdirectory(ArmNeon)
6+
add_subdirectory(ArmSME)
67
add_subdirectory(ArmSVE)
78
add_subdirectory(Async)
89
add_subdirectory(Bufferization)

mlir/include/mlir/InitAllPasses.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "mlir/Dialect/AMDGPU/Transforms/Passes.h"
1919
#include "mlir/Dialect/Affine/Passes.h"
2020
#include "mlir/Dialect/Arith/Transforms/Passes.h"
21+
#include "mlir/Dialect/ArmSME/Transforms/Passes.h"
2122
#include "mlir/Dialect/Async/Passes.h"
2223
#include "mlir/Dialect/Bufferization/Transforms/Passes.h"
2324
#include "mlir/Dialect/Func/Transforms/Passes.h"
@@ -77,6 +78,7 @@ inline void registerAllPasses() {
7778
tosa::registerTosaOptPasses();
7879
transform::registerTransformPasses();
7980
vector::registerVectorPasses();
81+
arm_sme::registerArmSMEPasses();
8082

8183
// Dialect pipelines
8284
sparse_tensor::registerSparseTensorPipelines();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(Transforms)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
add_mlir_dialect_library(MLIRArmSMETransforms
2+
EnableArmStreaming.cpp
3+
4+
ADDITIONAL_HEADER_DIRS
5+
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/ArmSME/Transforms
6+
7+
DEPENDS
8+
MLIRArmSMETransformsIncGen
9+
10+
LINK_LIBS PUBLIC
11+
MLIRFuncDialect
12+
MLIRPass
13+
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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+
// Streaming-mode is part of the interface (ABI) for functions with the
17+
// first attribute and it's the responsibility of the caller to manage
18+
// PSTATE.SM on entry/exit to functions with this attribute [3]. The LLVM
19+
// backend will emit 'smstart sm' / 'smstop sm' [4] around calls to
20+
// streaming functions.
21+
//
22+
// In locally streaming functions PSTATE.SM is kept internal and managed by
23+
// the callee on entry/exit. The LLVM backend will emit 'smstart sm' /
24+
// 'smstop sm' in the prologue / epilogue for functions with this
25+
// attribute.
26+
//
27+
// [1] https://developer.arm.com/documentation/ddi0616/aa
28+
// [2] https://llvm.org/docs/AArch64SME.html
29+
// [3] https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#671pstatesm-interfaces
30+
// [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--
31+
//
32+
//===----------------------------------------------------------------------===//
33+
34+
#include "mlir/Dialect/ArmSME/Transforms/Passes.h"
35+
36+
#include "mlir/Dialect/Func/IR/FuncOps.h"
37+
38+
#define DEBUG_TYPE "enable-arm-streaming"
39+
40+
namespace mlir {
41+
namespace arm_sme {
42+
#define GEN_PASS_DEF_ENABLEARMSTREAMING
43+
#include "mlir/Dialect/ArmSME/Transforms/Passes.h.inc"
44+
} // namespace arm_sme
45+
} // namespace mlir
46+
47+
using namespace mlir;
48+
using namespace mlir::arm_sme;
49+
50+
static constexpr char kArmStreamingAttr[] = "arm_streaming";
51+
static constexpr char kArmLocallyStreamingAttr[] = "arm_locally_streaming";
52+
53+
namespace {
54+
struct EnableArmStreamingPass
55+
: public arm_sme::impl::EnableArmStreamingBase<EnableArmStreamingPass> {
56+
EnableArmStreamingPass(ArmStreaming mode) { this->mode = mode; }
57+
void runOnOperation() override {
58+
std::string attr;
59+
switch (mode) {
60+
case ArmStreaming::Default:
61+
attr = kArmStreamingAttr;
62+
break;
63+
case ArmStreaming::Locally:
64+
attr = kArmLocallyStreamingAttr;
65+
break;
66+
}
67+
getOperation()->setAttr(attr, UnitAttr::get(&getContext()));
68+
}
69+
};
70+
} // namespace
71+
72+
std::unique_ptr<Pass>
73+
mlir::arm_sme::createEnableArmStreamingPass(const ArmStreaming mode) {
74+
return std::make_unique<EnableArmStreamingPass>(mode);
75+
}

mlir/lib/Dialect/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ add_subdirectory(Affine)
22
add_subdirectory(AMDGPU)
33
add_subdirectory(Arith)
44
add_subdirectory(ArmNeon)
5+
add_subdirectory(ArmSME)
56
add_subdirectory(ArmSVE)
67
add_subdirectory(Async)
78
add_subdirectory(AMX)

0 commit comments

Comments
 (0)