xref: /llvm-project/mlir/lib/ExecutionEngine/ArmRunnerUtils.cpp (revision e280c287e42065736d9c343306603ea07430a82b)
1*e280c287SBenjamin Maxwell //===- ArmRunnerUtils.cpp - Utilities for configuring architecture properties //
2*e280c287SBenjamin Maxwell //
3*e280c287SBenjamin Maxwell // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e280c287SBenjamin Maxwell // See https://llvm.org/LICENSE.txt for license information.
5*e280c287SBenjamin Maxwell // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e280c287SBenjamin Maxwell //
7*e280c287SBenjamin Maxwell //===----------------------------------------------------------------------===//
8*e280c287SBenjamin Maxwell 
9*e280c287SBenjamin Maxwell #include "llvm/Support/MathExtras.h"
10*e280c287SBenjamin Maxwell #include <iostream>
11*e280c287SBenjamin Maxwell #include <stdint.h>
12*e280c287SBenjamin Maxwell #include <string_view>
13*e280c287SBenjamin Maxwell 
14*e280c287SBenjamin Maxwell #if (defined(_WIN32) || defined(__CYGWIN__))
15*e280c287SBenjamin Maxwell #define MLIR_ARMRUNNERUTILS_EXPORTED __declspec(dllexport)
16*e280c287SBenjamin Maxwell #else
17*e280c287SBenjamin Maxwell #define MLIR_ARMRUNNERUTILS_EXPORTED __attribute__((visibility("default")))
18*e280c287SBenjamin Maxwell #endif
19*e280c287SBenjamin Maxwell 
20*e280c287SBenjamin Maxwell #ifdef __linux__
21*e280c287SBenjamin Maxwell #include <sys/prctl.h>
22*e280c287SBenjamin Maxwell #endif
23*e280c287SBenjamin Maxwell 
24*e280c287SBenjamin Maxwell extern "C" {
25*e280c287SBenjamin Maxwell 
26*e280c287SBenjamin Maxwell // Defines for prctl() calls. These may not necessarily exist in the host
27*e280c287SBenjamin Maxwell // <sys/prctl.h>, but will still be useable under emulation.
28*e280c287SBenjamin Maxwell //
29*e280c287SBenjamin Maxwell // https://www.kernel.org/doc/html/v5.3/arm64/sve.html#prctl-extensions
30*e280c287SBenjamin Maxwell #ifndef PR_SVE_SET_VL
31*e280c287SBenjamin Maxwell #define PR_SVE_SET_VL 50
32*e280c287SBenjamin Maxwell #endif
33*e280c287SBenjamin Maxwell // https://docs.kernel.org/arch/arm64/sme.html#prctl-extensions
34*e280c287SBenjamin Maxwell #ifndef PR_SME_SET_VL
35*e280c287SBenjamin Maxwell #define PR_SME_SET_VL 63
36*e280c287SBenjamin Maxwell #endif
37*e280c287SBenjamin Maxwell // Note: This mask is the same as both PR_SME_VL_LEN_MASK and
38*e280c287SBenjamin Maxwell // PR_SVE_VL_LEN_MASK.
39*e280c287SBenjamin Maxwell #define PR_VL_LEN_MASK 0xffff
40*e280c287SBenjamin Maxwell 
setArmVectorLength(std::string_view helper_name,int option,uint32_t bits)41*e280c287SBenjamin Maxwell static void setArmVectorLength(std::string_view helper_name, int option,
42*e280c287SBenjamin Maxwell                                uint32_t bits) {
43*e280c287SBenjamin Maxwell #if defined(__linux__) && defined(__aarch64__)
44*e280c287SBenjamin Maxwell   if (bits < 128 || bits > 2048 || !llvm::isPowerOf2_32(bits)) {
45*e280c287SBenjamin Maxwell     std::cerr << "[error] Attempted to set an invalid vector length (" << bits
46*e280c287SBenjamin Maxwell               << "-bit)" << std::endl;
47*e280c287SBenjamin Maxwell     abort();
48*e280c287SBenjamin Maxwell   }
49*e280c287SBenjamin Maxwell   uint32_t vl = bits / 8;
50*e280c287SBenjamin Maxwell   if (auto ret = prctl(option, vl & PR_VL_LEN_MASK); ret < 0) {
51*e280c287SBenjamin Maxwell     std::cerr << "[error] prctl failed (" << ret << ")" << std::endl;
52*e280c287SBenjamin Maxwell     abort();
53*e280c287SBenjamin Maxwell   }
54*e280c287SBenjamin Maxwell #else
55*e280c287SBenjamin Maxwell   std::cerr << "[error] " << helper_name << " is unsupported" << std::endl;
56*e280c287SBenjamin Maxwell   abort();
57*e280c287SBenjamin Maxwell #endif
58*e280c287SBenjamin Maxwell }
59*e280c287SBenjamin Maxwell 
60*e280c287SBenjamin Maxwell /// Sets the SVE vector length (in bits) to `bits`.
setArmVLBits(uint32_t bits)61*e280c287SBenjamin Maxwell void MLIR_ARMRUNNERUTILS_EXPORTED setArmVLBits(uint32_t bits) {
62*e280c287SBenjamin Maxwell   setArmVectorLength(__func__, PR_SVE_SET_VL, bits);
63*e280c287SBenjamin Maxwell }
64*e280c287SBenjamin Maxwell 
65*e280c287SBenjamin Maxwell /// Sets the SME streaming vector length (in bits) to `bits`.
setArmSVLBits(uint32_t bits)66*e280c287SBenjamin Maxwell void MLIR_ARMRUNNERUTILS_EXPORTED setArmSVLBits(uint32_t bits) {
67*e280c287SBenjamin Maxwell   setArmVectorLength(__func__, PR_SME_SET_VL, bits);
68*e280c287SBenjamin Maxwell }
69*e280c287SBenjamin Maxwell }
70