Index: llvm/lib/Support/Unix/Threading.inc =================================================================== --- llvm/lib/Support/Unix/Threading.inc +++ llvm/lib/Support/Unix/Threading.inc @@ -371,6 +371,49 @@ } return CPU_COUNT(&Enabled); } +#elif defined(__linux__) && defined(__aarch64__) +static int computeHostNumPhysicalCores() { + cpu_set_t Affinity, Enabled; + if (sched_getaffinity(0, sizeof(Affinity), &Affinity) == 0 && + CPU_COUNT(&Affinity) != 0) + return CPU_COUNT(&Affinity); + + // Get affinity failed, check the core number. + // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be + // mmapped because it appears to have 0 size. + llvm::ErrorOr> Text = + llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo"); + if (std::error_code EC = Text.getError()) { + llvm::errs() << "Can't read " + << "/proc/cpuinfo: " << EC.message() << "\n"; + return -1; + } + SmallVector strs; + (*Text)->getBuffer().split(strs, "\n", -1, false); + int CurProcessor = -1; + int CurPhysicalId = -1; + int CurSiblings = -1; + int CurCoreId = -1; + for (StringRef Line : strs) { + std::pair Data = Line.split(':'); + auto Name = Data.first.trim(); + auto Val = Data.second.trim(); + // These fields are available if the kernel is configured with CONFIG_SMP. + if (Name == "processor") + Val.getAsInteger(10, CurProcessor); + else if (Name == "physical id") + Val.getAsInteger(10, CurPhysicalId); + else if (Name == "siblings") + Val.getAsInteger(10, CurSiblings); + else if (Name == "core id") { + Val.getAsInteger(10, CurCoreId); + // The processor id corresponds to an index into cpu_set_t. + if (CPU_ISSET(CurProcessor, &Affinity)) + CPU_SET(CurPhysicalId * CurSiblings + CurCoreId, &Enabled); + } + } + return CPU_COUNT(&Enabled); +} #elif defined(__linux__) && defined(__s390x__) static int computeHostNumPhysicalCores() { return sysconf(_SC_NPROCESSORS_ONLN); Index: llvm/unittests/Support/Threading.cpp =================================================================== --- llvm/unittests/Support/Threading.cpp +++ llvm/unittests/Support/Threading.cpp @@ -28,6 +28,7 @@ // some systems. return (Host.isOSWindows() && llvm_is_multithreaded()) || Host.isOSDarwin() || (Host.isX86() && Host.isOSLinux()) || + (Host.isAArch64() && Host.isOSLinux()) || (Host.isOSLinux() && !Host.isAndroid()) || (Host.isSystemZ() && Host.isOSzOS()); #else