Skip to content

Commit ce62104

Browse files
authored
[RISCV] Get host CPU name via hwprobe (#142745)
We can get the `mvendorid/marchid/mimpid` via hwprobe and then we can compare these IDs with those defined in processors to find the CPU name. With this change, `-mcpu/-mtune=native` can set the proper name.
1 parent 5434b85 commit ce62104

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

llvm/include/llvm/TargetParser/RISCVTargetParser.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ struct CPUModel {
2929
uint32_t MVendorID;
3030
uint64_t MArchID;
3131
uint64_t MImpID;
32+
33+
bool isValid() const { return MVendorID != 0 && MArchID != 0 && MImpID != 0; }
34+
35+
bool operator==(const CPUModel &Other) const {
36+
return MVendorID == Other.MVendorID && MArchID == Other.MArchID &&
37+
MImpID == Other.MImpID;
38+
}
3239
};
3340

3441
struct CPUInfo {
@@ -58,6 +65,7 @@ LLVM_ABI bool hasFastScalarUnalignedAccess(StringRef CPU);
5865
LLVM_ABI bool hasFastVectorUnalignedAccess(StringRef CPU);
5966
LLVM_ABI bool hasValidCPUModel(StringRef CPU);
6067
LLVM_ABI CPUModel getCPUModel(StringRef CPU);
68+
LLVM_ABI StringRef getCPUNameFromCPUModel(const CPUModel &Model);
6169

6270
} // namespace RISCV
6371

llvm/lib/TargetParser/Host.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/Config/llvm-config.h"
1919
#include "llvm/Support/MemoryBuffer.h"
2020
#include "llvm/Support/raw_ostream.h"
21+
#include "llvm/TargetParser/RISCVTargetParser.h"
2122
#include "llvm/TargetParser/Triple.h"
2223
#include "llvm/TargetParser/X86TargetParser.h"
2324
#include <string.h>
@@ -1672,8 +1673,32 @@ StringRef sys::getHostCPUName() {
16721673
return "generic";
16731674
}
16741675
#elif defined(__riscv)
1676+
#if defined(__linux__)
1677+
// struct riscv_hwprobe
1678+
struct RISCVHwProbe {
1679+
int64_t Key;
1680+
uint64_t Value;
1681+
};
1682+
#endif
1683+
16751684
StringRef sys::getHostCPUName() {
16761685
#if defined(__linux__)
1686+
// Try the hwprobe way first.
1687+
RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_MVENDORID=*/0, 0},
1688+
{/*RISCV_HWPROBE_KEY_MARCHID=*/1, 0},
1689+
{/*RISCV_HWPROBE_KEY_MIMPID=*/2, 0}};
1690+
int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
1691+
/*pair_count=*/std::size(Query), /*cpu_count=*/0,
1692+
/*cpus=*/0, /*flags=*/0);
1693+
if (Ret == 0) {
1694+
RISCV::CPUModel Model{static_cast<uint32_t>(Query[0].Value), Query[1].Value,
1695+
Query[2].Value};
1696+
StringRef Name = RISCV::getCPUNameFromCPUModel(Model);
1697+
if (!Name.empty())
1698+
return Name;
1699+
}
1700+
1701+
// Then try the cpuinfo way.
16771702
std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
16781703
StringRef Content = P ? P->getBuffer() : "";
16791704
StringRef Name = detail::getHostCPUNameForRISCV(Content);
@@ -2148,11 +2173,6 @@ const StringMap<bool> sys::getHostCPUFeatures() {
21482173
return Features;
21492174
}
21502175
#elif defined(__linux__) && defined(__riscv)
2151-
// struct riscv_hwprobe
2152-
struct RISCVHwProbe {
2153-
int64_t Key;
2154-
uint64_t Value;
2155-
};
21562176
const StringMap<bool> sys::getHostCPUFeatures() {
21572177
RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
21582178
{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},

llvm/lib/TargetParser/RISCVTargetParser.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ bool hasFastVectorUnalignedAccess(StringRef CPU) {
5757
return Info && Info->FastVectorUnalignedAccess;
5858
}
5959

60-
bool hasValidCPUModel(StringRef CPU) {
61-
const CPUModel Model = getCPUModel(CPU);
62-
return Model.MVendorID != 0 && Model.MArchID != 0 && Model.MImpID != 0;
63-
}
60+
bool hasValidCPUModel(StringRef CPU) { return getCPUModel(CPU).isValid(); }
6461

6562
CPUModel getCPUModel(StringRef CPU) {
6663
const CPUInfo *Info = getCPUInfoByName(CPU);
@@ -69,6 +66,16 @@ CPUModel getCPUModel(StringRef CPU) {
6966
return Info->Model;
7067
}
7168

69+
StringRef getCPUNameFromCPUModel(const CPUModel &Model) {
70+
if (!Model.isValid())
71+
return "";
72+
73+
for (auto &C : RISCVCPUInfo)
74+
if (C.Model == Model)
75+
return C.Name;
76+
return "";
77+
}
78+
7279
bool parseCPU(StringRef CPU, bool IsRV64) {
7380
const CPUInfo *Info = getCPUInfoByName(CPU);
7481

0 commit comments

Comments
 (0)