-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV] Add support for getHostCPUFeatures using hwprobe #94352
Conversation
Co-authored-by: Yangyu Chen <[email protected]>
Do you offer an alternative/default implementation when __NR_riscv_hwprobe is not available, e.g., in docker containers? |
Is |
I think it is a bad idea. Some vendor custom kernels, such as t-head kernel, regard |
Ping. |
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-clang-driver Author: Yingwei Zheng (dtcxzyw) ChangesThis patch adds support for
Co-authored-by: @cyyself Full diff: https://github.com/llvm/llvm-project/pull/94352.diff 2 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 2e2bce8494672..bf34b6e3f2ea4 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -86,8 +86,14 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
// and other features (ex. mirco architecture feature) from mcpu
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
StringRef CPU = A->getValue();
- if (CPU == "native")
+ if (CPU == "native") {
CPU = llvm::sys::getHostCPUName();
+ llvm::StringMap<bool> HostFeatures;
+ if (llvm::sys::getHostCPUFeatures(HostFeatures))
+ for (auto &F : HostFeatures)
+ Features.push_back(
+ Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+ }
getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);
}
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 68155acd9e5bc..b99e1443ef5e5 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1998,6 +1998,75 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
return true;
}
+#elif defined(__linux__) && defined(__riscv)
+// struct riscv_hwprobe
+struct RISCVHwProbe {
+ int64_t Key;
+ uint64_t Value;
+};
+bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
+ RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
+ {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}};
+ int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
+ /*pair_count=*/std::size(Query), /*cpu_count=*/0,
+ /*cpus=*/0, /*flags=*/0);
+ if (Ret != 0)
+ return false;
+
+ uint64_t BaseMask = Query[0].Value;
+ // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set.
+ if (BaseMask & 1) {
+ Features["i"] = true;
+ Features["m"] = true;
+ Features["a"] = true;
+ }
+
+ uint64_t ExtMask = Query[1].Value;
+ Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
+ Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
+ Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C
+ Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V
+ Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA
+ Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB
+ Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS
+ Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ
+ Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC
+ Features["zbkb"] = ExtMask & (1 << 8); // RISCV_HWPROBE_EXT_ZBKB
+ Features["zbkc"] = ExtMask & (1 << 9); // RISCV_HWPROBE_EXT_ZBKC
+ Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX
+ Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND
+ Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE
+ Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH
+ Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED
+ Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH
+ Features["zkt"] = ExtMask & (1 << 16); // RISCV_HWPROBE_EXT_ZKT
+ Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB
+ Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC
+ Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB
+ Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG
+ Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED
+ Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA
+ Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB
+ Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED
+ Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH
+ Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT
+ Features["zfh"] = ExtMask & (1 << 27); // RISCV_HWPROBE_EXT_ZFH
+ Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN
+ Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL
+ Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH
+ Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
+ Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA
+ Features["ztso"] = ExtMask & (1ULL << 33); // RISCV_HWPROBE_EXT_ZTSO
+ Features["zacas"] = ExtMask & (1ULL << 34); // RISCV_HWPROBE_EXT_ZACAS
+ Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
+ Features["zihintpause"] =
+ ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
+
+ // TODO: set unaligned-scalar-mem if RISCV_HWPROBE_KEY_MISALIGNED_PERF returns
+ // RISCV_HWPROBE_MISALIGNED_FAST.
+
+ return true;
+}
#else
bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
#endif
|
CPU = llvm::sys::getHostCPUName(); | ||
llvm::StringMap<bool> HostFeatures; | ||
if (llvm::sys::getHostCPUFeatures(HostFeatures)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open discussion here: CPU
may fail and return generic
. Should we failback to use getHostCPUFeatures
if getHostCPUName
fails? Or we should use getHostCPUFeatures
all the time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think hwprobe is more reliable than cpu name because some RV cpus are not recognized by LLVM (e.g., T-head's cores). However, cpu name is still useful even if getHostCPUFeatures
returns true because it may provide scheduling model.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This reverts commit 7563384.
✅ With the latest revision this PR passed the C/C++ code formatter. |
…`. NFC. (#97965) See the discussion in #94352 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I will rebase on the top of #97824. |
|
Ping @wangpc-pp @topperc @preames |
…`. NFC. (llvm#97965) See the discussion in llvm#94352 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Summary: This patch adds support for `sys::getHostCPUFeatures` using the RISC-V hardware probing interface. References: + Loongarch patch: e53f41c + asm/hwprobe.h: https://github.com/torvalds/linux/blob/2ab79514109578fc4b6df90633d500cf281eb689/arch/riscv/include/uapi/asm/hwprobe.h + glibc support: https://inbox.sourceware.org/glibc-cvs/[email protected]/T/#Z2e.:..:20240301151728.AD5963858C53::40sourceware.org:1sysdeps:unix:sysv:linux:riscv:sys:hwprobe.h + __NR_riscv_hwprobe syscall tutorial: https://github.com/cyyself/hwprobe + hwprobe docs: https://docs.kernel.org/arch/riscv/hwprobe.html --------- Co-authored-by: Yangyu Chen <[email protected]> Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251727
This patch is the follow-up of #94352 with some updates: 1. Add support for more extensions for `zve*`, `zimop`, `zc*`, `zcmop` and `zawrs`. 2. Use `RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF` to check whether the processor supports fast misaligned scalar memory access. #108551 reminds me that the patch https://lore.kernel.org/all/[email protected]/T/ has been merged. Address comment #94352 (comment). References: 1. constants: https://github.com/torvalds/linux/blame/v6.11-rc7/arch/riscv/include/uapi/asm/hwprobe.h 2. https://docs.kernel.org/arch/riscv/hwprobe.html 3. Related commits: 1. `zve*` support: torvalds/linux@de8f828 2. `zimop` support: torvalds/linux@36f8960 3. `zc*` support: torvalds/linux@0ad70db 4. `zcmop` support: torvalds/linux@fc078ea 5. `zawrs` support: torvalds/linux@244c18f 6. scalar misaligned perf: torvalds/linux@c42e2f0 and torvalds/linux@1f52888
This patch adds support for
sys::getHostCPUFeatures
using the RISC-V hardware probing interface.References:
Co-authored-by: @cyyself