Skip to content

Commit

Permalink
unstick macOS 10.9 buildbot (JuliaLang#24493)
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Nov 7, 2017
1 parent 695fedb commit c8d52d2
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 163 deletions.
163 changes: 83 additions & 80 deletions src/processor_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,96 +901,99 @@ static void shrink_big_little(std::vector<std::pair<uint32_t,CPUID>> &list,
}
}

static inline const std::pair<uint32_t,FeatureList<feature_sz>> &get_host_cpu()
static NOINLINE std::pair<uint32_t,FeatureList<feature_sz>> _get_host_cpu()
{
static const auto host_cpu = [] {
FeatureList<feature_sz> features = {};
// Here we assume that only the lower 32bit are used on aarch64
// Change the cast here when that's not the case anymore (and when there's features in the
// high bits that we want to detect).
features[0] = (uint32_t)jl_getauxval(AT_HWCAP);
features[1] = (uint32_t)jl_getauxval(AT_HWCAP2);
auto cpuinfo = get_cpuinfo();
auto arch = get_elf_arch();
FeatureList<feature_sz> features = {};
// Here we assume that only the lower 32bit are used on aarch64
// Change the cast here when that's not the case anymore (and when there's features in the
// high bits that we want to detect).
features[0] = (uint32_t)jl_getauxval(AT_HWCAP);
features[1] = (uint32_t)jl_getauxval(AT_HWCAP2);
auto cpuinfo = get_cpuinfo();
auto arch = get_elf_arch();
#ifdef _CPU_ARM_
if (arch.first >= 7) {
if (arch.second == 'M') {
set_bit(features, Feature::mclass, true);
}
else if (arch.second == 'R') {
set_bit(features, Feature::rclass, true);
}
else if (arch.second == 'A') {
set_bit(features, Feature::aclass, true);
}
if (arch.first >= 7) {
if (arch.second == 'M') {
set_bit(features, Feature::mclass, true);
}
switch (arch.first) {
case 8:
set_bit(features, Feature::v8, true);
JL_FALLTHROUGH;
case 7:
set_bit(features, Feature::v7, true);
break;
default:
break;
else if (arch.second == 'R') {
set_bit(features, Feature::rclass, true);
}
else if (arch.second == 'A') {
set_bit(features, Feature::aclass, true);
}
}
switch (arch.first) {
case 8:
set_bit(features, Feature::v8, true);
JL_FALLTHROUGH;
case 7:
set_bit(features, Feature::v7, true);
break;
default:
break;
}
#endif

std::set<uint32_t> cpus;
std::vector<std::pair<uint32_t,CPUID>> list;
for (auto info: cpuinfo) {
auto name = (uint32_t)get_cpu_name(info);
if (name == 0)
continue;
if (!check_cpu_arch_ver(name, arch))
continue;
if (cpus.insert(name).second) {
features = features | find_cpu(name)->features;
list.emplace_back(name, info);
}
std::set<uint32_t> cpus;
std::vector<std::pair<uint32_t,CPUID>> list;
for (auto info: cpuinfo) {
auto name = (uint32_t)get_cpu_name(info);
if (name == 0)
continue;
if (!check_cpu_arch_ver(name, arch))
continue;
if (cpus.insert(name).second) {
features = features | find_cpu(name)->features;
list.emplace_back(name, info);
}
// Not all elements/pairs are valid
static constexpr CPU v8order[] = {
CPU::arm_cortex_a32,
CPU::arm_cortex_a35,
CPU::arm_cortex_a53,
CPU::arm_cortex_a55,
CPU::arm_cortex_a57,
CPU::arm_cortex_a72,
CPU::arm_cortex_a73,
CPU::arm_cortex_a75,
CPU::nvidia_denver2,
CPU::samsung_exynos_m1
};
shrink_big_little(list, v8order, sizeof(v8order) / sizeof(CPU));
}
// Not all elements/pairs are valid
static constexpr CPU v8order[] = {
CPU::arm_cortex_a32,
CPU::arm_cortex_a35,
CPU::arm_cortex_a53,
CPU::arm_cortex_a55,
CPU::arm_cortex_a57,
CPU::arm_cortex_a72,
CPU::arm_cortex_a73,
CPU::arm_cortex_a75,
CPU::nvidia_denver2,
CPU::samsung_exynos_m1
};
shrink_big_little(list, v8order, sizeof(v8order) / sizeof(CPU));
#ifdef _CPU_ARM_
// Not all elements/pairs are valid
static constexpr CPU v7order[] = {
CPU::arm_cortex_a5,
CPU::arm_cortex_a7,
CPU::arm_cortex_a8,
CPU::arm_cortex_a9,
CPU::arm_cortex_a12,
CPU::arm_cortex_a15,
CPU::arm_cortex_a17
};
shrink_big_little(list, v7order, sizeof(v7order) / sizeof(CPU));
// Not all elements/pairs are valid
static constexpr CPU v7order[] = {
CPU::arm_cortex_a5,
CPU::arm_cortex_a7,
CPU::arm_cortex_a8,
CPU::arm_cortex_a9,
CPU::arm_cortex_a12,
CPU::arm_cortex_a15,
CPU::arm_cortex_a17
};
shrink_big_little(list, v7order, sizeof(v7order) / sizeof(CPU));
#endif
uint32_t cpu = 0;
if (list.empty()) {
cpu = (uint32_t)generic_for_arch(arch);
}
else {
// This also covers `list.size() > 1` case which means there's a unknown combination
// consists of CPU's we know. Unclear what else we could try so just randomly return
// one...
cpu = list[0].first;
}
// Ignore feature bits that we are not interested in.
mask_features(feature_masks, &features[0]);
uint32_t cpu = 0;
if (list.empty()) {
cpu = (uint32_t)generic_for_arch(arch);
}
else {
// This also covers `list.size() > 1` case which means there's a unknown combination
// consists of CPU's we know. Unclear what else we could try so just randomly return
// one...
cpu = list[0].first;
}
// Ignore feature bits that we are not interested in.
mask_features(feature_masks, &features[0]);

return std::make_pair(cpu, features);
}();
return std::make_pair(cpu, features);
}

static inline const std::pair<uint32_t,FeatureList<feature_sz>> &get_host_cpu()
{
static auto host_cpu = _get_host_cpu();
return host_cpu;
}

Expand Down
169 changes: 86 additions & 83 deletions src/processor_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,92 +479,95 @@ static inline void features_disable_avx(T &features)
xsaveopt, xsavec, xsaves);
}

static inline const std::pair<uint32_t,FeatureList<feature_sz>> &get_host_cpu()
{
static const auto host_cpu = [] () NOINLINE {
FeatureList<feature_sz> features = {};

int32_t info0[4];
jl_cpuid(info0, 0);
uint32_t maxleaf = info0[0];
if (maxleaf < 1)
return std::make_pair(uint32_t(CPU::generic), features);
int32_t info1[4];
jl_cpuid(info1, 1);

auto vendor = info0[1];
auto brand_id = info1[1] & 0xff;

auto family = (info1[0] >> 8) & 0xf; // Bits 8 - 11
auto model = (info1[0] >> 4) & 0xf; // Bits 4 - 7
if (family == 6 || family == 0xf) {
if (family == 0xf)
// Examine extended family ID if family ID is F.
family += (info1[0] >> 20) & 0xff; // Bits 20 - 27
// Examine extended model ID if family ID is 6 or F.
model += ((info1[0] >> 16) & 0xf) << 4; // Bits 16 - 19
}
static NOINLINE std::pair<uint32_t,FeatureList<feature_sz>> _get_host_cpu(void)
{
FeatureList<feature_sz> features = {};

int32_t info0[4];
jl_cpuid(info0, 0);
uint32_t maxleaf = info0[0];
if (maxleaf < 1)
return std::make_pair(uint32_t(CPU::generic), features);
int32_t info1[4];
jl_cpuid(info1, 1);

auto vendor = info0[1];
auto brand_id = info1[1] & 0xff;

auto family = (info1[0] >> 8) & 0xf; // Bits 8 - 11
auto model = (info1[0] >> 4) & 0xf; // Bits 4 - 7
if (family == 6 || family == 0xf) {
if (family == 0xf)
// Examine extended family ID if family ID is F.
family += (info1[0] >> 20) & 0xff; // Bits 20 - 27
// Examine extended model ID if family ID is 6 or F.
model += ((info1[0] >> 16) & 0xf) << 4; // Bits 16 - 19
}

// Fill in the features
features[0] = info1[2];
features[1] = info1[3];
if (maxleaf >= 7) {
int32_t info7[4];
jl_cpuidex(info7, 7, 0);
features[2] = info7[1];
features[3] = info7[2];
features[4] = info7[3];
}
int32_t infoex0[4];
jl_cpuid(infoex0, 0x80000000);
uint32_t maxexleaf = infoex0[0];
if (maxexleaf >= 0x80000001) {
int32_t infoex1[4];
jl_cpuid(infoex1, 0x80000001);
features[5] = infoex1[2];
features[6] = infoex1[3];
}
if (maxleaf >= 0xd) {
int32_t infod[4];
jl_cpuidex(infod, 0xd, 0x1);
features[7] = infod[0];
}
if (maxexleaf >= 0x80000008) {
int32_t infoex8[4];
jl_cpuidex(infoex8, 0x80000008, 0);
features[8] = infoex8[1];
}
// Fill in the features
features[0] = info1[2];
features[1] = info1[3];
if (maxleaf >= 7) {
int32_t info7[4];
jl_cpuidex(info7, 7, 0);
features[2] = info7[1];
features[3] = info7[2];
features[4] = info7[3];
}
int32_t infoex0[4];
jl_cpuid(infoex0, 0x80000000);
uint32_t maxexleaf = infoex0[0];
if (maxexleaf >= 0x80000001) {
int32_t infoex1[4];
jl_cpuid(infoex1, 0x80000001);
features[5] = infoex1[2];
features[6] = infoex1[3];
}
if (maxleaf >= 0xd) {
int32_t infod[4];
jl_cpuidex(infod, 0xd, 0x1);
features[7] = infod[0];
}
if (maxexleaf >= 0x80000008) {
int32_t infoex8[4];
jl_cpuidex(infoex8, 0x80000008, 0);
features[8] = infoex8[1];
}

// Fix up AVX bits to account for OS support and match LLVM model
uint64_t xcr0 = 0;
const uint32_t avx_mask = (1 << 27) | (1 << 28);
bool hasavx = test_all_bits(features[0], avx_mask);
if (hasavx) {
xcr0 = get_xcr0();
hasavx = test_all_bits(xcr0, 0x6);
}
unset_bits(features, 32 + 27);
if (!hasavx)
features_disable_avx(features);
bool hasavx512save = hasavx && test_all_bits(xcr0, 0xe0);
if (!hasavx512save)
features_disable_avx512(features);
// Ignore feature bits that we are not interested in.
mask_features(feature_masks, &features[0]);

uint32_t cpu;
if (vendor == SIG_INTEL) {
cpu = uint32_t(get_intel_processor_name(family, model, brand_id, &features[0]));
}
else if (vendor == SIG_AMD) {
cpu = uint32_t(get_amd_processor_name(family, model, &features[0]));
}
else {
cpu = uint32_t(CPU::generic);
}
// Fix up AVX bits to account for OS support and match LLVM model
uint64_t xcr0 = 0;
const uint32_t avx_mask = (1 << 27) | (1 << 28);
bool hasavx = test_all_bits(features[0], avx_mask);
if (hasavx) {
xcr0 = get_xcr0();
hasavx = test_all_bits(xcr0, 0x6);
}
unset_bits(features, 32 + 27);
if (!hasavx)
features_disable_avx(features);
bool hasavx512save = hasavx && test_all_bits(xcr0, 0xe0);
if (!hasavx512save)
features_disable_avx512(features);
// Ignore feature bits that we are not interested in.
mask_features(feature_masks, &features[0]);

uint32_t cpu;
if (vendor == SIG_INTEL) {
cpu = uint32_t(get_intel_processor_name(family, model, brand_id, &features[0]));
}
else if (vendor == SIG_AMD) {
cpu = uint32_t(get_amd_processor_name(family, model, &features[0]));
}
else {
cpu = uint32_t(CPU::generic);
}

return std::make_pair(cpu, features);
}

return std::make_pair(cpu, features);
}();
static inline const std::pair<uint32_t,FeatureList<feature_sz>> &get_host_cpu()
{
static auto host_cpu = _get_host_cpu();
return host_cpu;
}

Expand Down

0 comments on commit c8d52d2

Please sign in to comment.