Skip to content

[RISCV] Get host CPU name via hwprobe #142745

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

Merged
merged 1 commit into from
Jun 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/include/llvm/TargetParser/RISCVTargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ struct CPUModel {
uint32_t MVendorID;
uint64_t MArchID;
uint64_t MImpID;

bool isValid() const { return MVendorID != 0 && MArchID != 0 && MImpID != 0; }

bool operator==(const CPUModel &Other) const {
return MVendorID == Other.MVendorID && MArchID == Other.MArchID &&
MImpID == Other.MImpID;
}
};

struct CPUInfo {
Expand Down Expand Up @@ -58,6 +65,7 @@ LLVM_ABI bool hasFastScalarUnalignedAccess(StringRef CPU);
LLVM_ABI bool hasFastVectorUnalignedAccess(StringRef CPU);
LLVM_ABI bool hasValidCPUModel(StringRef CPU);
LLVM_ABI CPUModel getCPUModel(StringRef CPU);
LLVM_ABI StringRef getCPUNameFromCPUModel(const CPUModel &Model);

} // namespace RISCV

Expand Down
30 changes: 25 additions & 5 deletions llvm/lib/TargetParser/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/TargetParser/X86TargetParser.h"
#include <string.h>
Expand Down Expand Up @@ -1672,8 +1673,32 @@ StringRef sys::getHostCPUName() {
return "generic";
}
#elif defined(__riscv)
#if defined(__linux__)
// struct riscv_hwprobe
struct RISCVHwProbe {
int64_t Key;
uint64_t Value;
};
#endif

StringRef sys::getHostCPUName() {
#if defined(__linux__)
// Try the hwprobe way first.
RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_MVENDORID=*/0, 0},
{/*RISCV_HWPROBE_KEY_MARCHID=*/1, 0},
{/*RISCV_HWPROBE_KEY_MIMPID=*/2, 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) {
RISCV::CPUModel Model{static_cast<uint32_t>(Query[0].Value), Query[1].Value,
Query[2].Value};
StringRef Name = RISCV::getCPUNameFromCPUModel(Model);
if (!Name.empty())
return Name;
}

// Then try the cpuinfo way.
std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
StringRef Content = P ? P->getBuffer() : "";
StringRef Name = detail::getHostCPUNameForRISCV(Content);
Expand Down Expand Up @@ -2148,11 +2173,6 @@ const StringMap<bool> sys::getHostCPUFeatures() {
return Features;
}
#elif defined(__linux__) && defined(__riscv)
// struct riscv_hwprobe
struct RISCVHwProbe {
int64_t Key;
uint64_t Value;
};
const StringMap<bool> sys::getHostCPUFeatures() {
RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},
Expand Down
15 changes: 11 additions & 4 deletions llvm/lib/TargetParser/RISCVTargetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ bool hasFastVectorUnalignedAccess(StringRef CPU) {
return Info && Info->FastVectorUnalignedAccess;
}

bool hasValidCPUModel(StringRef CPU) {
const CPUModel Model = getCPUModel(CPU);
return Model.MVendorID != 0 && Model.MArchID != 0 && Model.MImpID != 0;
}
bool hasValidCPUModel(StringRef CPU) { return getCPUModel(CPU).isValid(); }

CPUModel getCPUModel(StringRef CPU) {
const CPUInfo *Info = getCPUInfoByName(CPU);
Expand All @@ -69,6 +66,16 @@ CPUModel getCPUModel(StringRef CPU) {
return Info->Model;
}

StringRef getCPUNameFromCPUModel(const CPUModel &Model) {
if (!Model.isValid())
return "";

for (auto &C : RISCVCPUInfo)
if (C.Model == Model)
return C.Name;
return "";
}

bool parseCPU(StringRef CPU, bool IsRV64) {
const CPUInfo *Info = getCPUInfoByName(CPU);

Expand Down
Loading