[llvm] r299458 - Implement host CPU detection for AArch64

Yi Kong via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 4 12:06:04 PDT 2017


Author: kongyi
Date: Tue Apr  4 14:06:04 2017
New Revision: 299458

URL: http://llvm.org/viewvc/llvm-project?rev=299458&view=rev
Log:
Implement host CPU detection for AArch64

This shares detection logic with ARM(32), since AArch64 capable CPUs may
also run in 32-bit system mode.

We observe weird /proc/cpuinfo output for MSM8992 and MSM8994, where
they report all CPU cores as one single model, depending on which CPU
core the kernel is running on. As a workaround, we hardcode the known
CPU part name for these SoCs.

For big.LITTLE systems, this patch would only return the part name of
the first core (usually the little core). Proper support will be added
in a follow-up change.

Differential Revision: D31675

Modified:
    llvm/trunk/lib/Support/Host.cpp
    llvm/trunk/unittests/Support/Host.cpp

Modified: llvm/trunk/lib/Support/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Host.cpp?rev=299458&r1=299457&r2=299458&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Host.cpp (original)
+++ llvm/trunk/lib/Support/Host.cpp Tue Apr  4 14:06:04 2017
@@ -149,18 +149,28 @@ StringRef sys::detail::getHostCPUNameFor
   // The cpuid register on arm is not accessible from user space. On Linux,
   // it is exposed through the /proc/cpuinfo file.
 
-  // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
+  // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line
   // in all cases.
   SmallVector<StringRef, 32> Lines;
   ProcCpuinfoContent.split(Lines, "\n");
 
   // Look for the CPU implementer line.
   StringRef Implementer;
-  for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+  StringRef Hardware;
+  for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
     if (Lines[I].startswith("CPU implementer"))
       Implementer = Lines[I].substr(15).ltrim("\t :");
+    if (Lines[I].startswith("Hardware"))
+      Hardware = Lines[I].substr(8).ltrim("\t :");
+  }
+
+  if (Implementer == "0x41") { // ARM Ltd.
+    // MSM8992/8994 may give cpu part for the core that the kernel is running on,
+    // which is undeterministic and wrong. Always return cortex-a53 for these SoC.
+    if (Hardware.endswith("MSM8994") || Hardware.endswith("MSM8996"))
+      return "cortex-a53";
+
 
-  if (Implementer == "0x41") // ARM Ltd.
     // Look for the CPU part line.
     for (unsigned I = 0, E = Lines.size(); I != E; ++I)
       if (Lines[I].startswith("CPU part"))
@@ -179,6 +189,22 @@ StringRef sys::detail::getHostCPUNameFor
             .Case("0xc20", "cortex-m0")
             .Case("0xc23", "cortex-m3")
             .Case("0xc24", "cortex-m4")
+            .Case("0xd03", "cortex-a53")
+            .Case("0xd07", "cortex-a57")
+            .Case("0xd08", "cortex-a72")
+            .Case("0xd09", "cortex-a73")
+            .Default("generic");
+  }
+
+  if (Implementer == "0x50") // Applied Micro Circuits Corporation (APM).
+    // Look for the CPU part line.
+    for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+      if (Lines[I].startswith("CPU part"))
+        // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
+        // values correspond to the "Part number" in the CP15/c0 register. The
+        // contents are specified in the various processor manuals.
+        return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
+            .Case("0x000", "xgene1")
             .Default("generic");
 
   if (Implementer == "0x51") // Qualcomm Technologies, Inc.
@@ -190,6 +216,8 @@ StringRef sys::detail::getHostCPUNameFor
         // contents are specified in the various processor manuals.
         return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
             .Case("0x06f", "krait") // APQ8064
+            .Case("0x201", "kryo")
+            .Case("0x205", "kryo")
             .Default("generic");
 
   return "generic";
@@ -1199,7 +1227,7 @@ StringRef sys::getHostCPUName() {
   const StringRef& Content = P ? P->getBuffer() : "";
   return detail::getHostCPUNameForPowerPC(Content);
 }
-#elif defined(__linux__) && defined(__arm__)
+#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
 StringRef sys::getHostCPUName() {
   std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
   const StringRef& Content = P ? P->getBuffer() : "";

Modified: llvm/trunk/unittests/Support/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Host.cpp?rev=299458&r1=299457&r2=299458&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/Host.cpp (original)
+++ llvm/trunk/unittests/Support/Host.cpp Tue Apr  4 14:06:04 2017
@@ -79,3 +79,38 @@ Serial          : 0000000000000000
                                               "CPU part        : 0x06f"),
             "krait");
 }
+
+TEST(getLinuxHostCPUName, AArch64) {
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
+                                              "CPU part        : 0xd03"),
+            "cortex-a53");
+  // Verify that both CPU implementer and CPU part are checked:
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
+                                              "CPU part        : 0xd03"),
+            "generic");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+                                              "CPU part        : 0x201"),
+            "kryo");
+
+  // MSM8992/4 weirdness
+  StringRef MSM8992ProcCpuInfo = R"(
+Processor       : AArch64 Processor rev 3 (aarch64)
+processor       : 0
+processor       : 1
+processor       : 2
+processor       : 3
+processor       : 4
+processor       : 5
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer : 0x41
+CPU architecture: 8
+CPU variant     : 0x0
+CPU part        : 0xd03
+CPU revision    : 3
+
+Hardware        : Qualcomm Technologies, Inc MSM8992
+)";
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo),
+            "cortex-a53");
+}




More information about the llvm-commits mailing list