authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-05-12 11:26:37+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-12 14:03:59-04:00
log893a4286569c9250c29eec8d1cff386ddbf38b3c
tree7089652264d1cc2626455fb15c26197a1c1ae4a0
parent7b7724628974067f1a66069699fd1433d32da50d

stage2: Drop LLVM's host CPU detection method as fallback

The CPU detection code is nearly at feature parity, we do support detecting the native CPU on Sparc systems and macos, our ARM/AArch64 model list is quite comprehensive and so is our PPC one. The only missing pieces are: - ARM32 detection on Darwin hosts (I don't think anybody is planning on running the compiler on a old-ass iPhone) - s390x detection on Linux hosts, this can be easily added at a later stage.

2 files changed, 1 insertions(+), 90 deletions(-)

lib/std/zig/system.zig-9
......@@ -208,11 +208,6 @@ pub const NativeTargetInfo = struct {
208208
209209 dynamic_linker: DynamicLinker = DynamicLinker{},
210210
211 /// Only some architectures have CPU detection implemented. This field reveals whether
212 /// CPU detection actually occurred. When this is `true` it means that the reported
213 /// CPU is baseline only because of a missing implementation for that architecture.
214 cpu_detection_unimplemented: bool = false,
215
216211 pub const DynamicLinker = Target.DynamicLinker;
217212
218213 pub const DetectError = error{
......@@ -367,8 +362,6 @@ pub const NativeTargetInfo = struct {
367362 os.version_range.linux.glibc = glibc;
368363 }
369364
370 var cpu_detection_unimplemented = false;
371
372365 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
373366 // native CPU architecture as being different than the current target), we use this:
374367 const cpu_arch = cross_target.getCpuArch();
......@@ -382,7 +375,6 @@ pub const NativeTargetInfo = struct {
382375 Target.Cpu.baseline(cpu_arch),
383376 .explicit => |model| model.toCpu(cpu_arch),
384377 } orelse backup_cpu_detection: {
385 cpu_detection_unimplemented = true;
386378 break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);
387379 };
388380 var result = try detectAbiAndDynamicLinker(allocator, cpu, os, cross_target);
......@@ -419,7 +411,6 @@ pub const NativeTargetInfo = struct {
419411 else => {},
420412 }
421413 cross_target.updateCpuFeatures(&result.target.cpu.features);
422 result.cpu_detection_unimplemented = cpu_detection_unimplemented;
423414 return result;
424415 }
425416
src/main.zig+1-81
......@@ -3396,88 +3396,8 @@ test "fds" {
33963396 gimmeMoreOfThoseSweetSweetFileDescriptors();
33973397}
33983398
3399fn detectNativeCpuWithLLVM(
3400 arch: std.Target.Cpu.Arch,
3401 llvm_cpu_name_z: ?[*:0]const u8,
3402 llvm_cpu_features_opt: ?[*:0]const u8,
3403) !std.Target.Cpu {
3404 var result = std.Target.Cpu.baseline(arch);
3405
3406 if (llvm_cpu_name_z) |cpu_name_z| {
3407 const llvm_cpu_name = mem.spanZ(cpu_name_z);
3408
3409 for (arch.allCpuModels()) |model| {
3410 const this_llvm_name = model.llvm_name orelse continue;
3411 if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
3412 // Here we use the non-dependencies-populated set,
3413 // so that subtracting features later in this function
3414 // affect the prepopulated set.
3415 result = std.Target.Cpu{
3416 .arch = arch,
3417 .model = model,
3418 .features = model.features,
3419 };
3420 break;
3421 }
3422 }
3423 }
3424
3425 const all_features = arch.allFeaturesList();
3426
3427 if (llvm_cpu_features_opt) |llvm_cpu_features| {
3428 var it = mem.tokenize(mem.spanZ(llvm_cpu_features), ",");
3429 while (it.next()) |decorated_llvm_feat| {
3430 var op: enum {
3431 add,
3432 sub,
3433 } = undefined;
3434 var llvm_feat: []const u8 = undefined;
3435 if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
3436 op = .add;
3437 llvm_feat = decorated_llvm_feat[1..];
3438 } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
3439 op = .sub;
3440 llvm_feat = decorated_llvm_feat[1..];
3441 } else {
3442 return error.InvalidLlvmCpuFeaturesFormat;
3443 }
3444 for (all_features) |feature, index_usize| {
3445 const this_llvm_name = feature.llvm_name orelse continue;
3446 if (mem.eql(u8, llvm_feat, this_llvm_name)) {
3447 const index = @intCast(std.Target.Cpu.Feature.Set.Index, index_usize);
3448 switch (op) {
3449 .add => result.features.addFeature(index),
3450 .sub => result.features.removeFeature(index),
3451 }
3452 break;
3453 }
3454 }
3455 }
3456 }
3457
3458 result.features.populateDependencies(all_features);
3459 return result;
3460}
3461
34623399fn detectNativeTargetInfo(gpa: *Allocator, cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {
3463 var info = try std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
3464 if (info.cpu_detection_unimplemented) {
3465 const arch = std.Target.current.cpu.arch;
3466
3467 // We want to just use detected_info.target but implementing
3468 // CPU model & feature detection is todo so here we rely on LLVM.
3469 // https://github.com/ziglang/zig/issues/4591
3470 if (!build_options.have_llvm)
3471 fatal("CPU features detection is not yet available for {s} without LLVM extensions", .{@tagName(arch)});
3472
3473 const llvm = @import("codegen/llvm/bindings.zig");
3474 const llvm_cpu_name = llvm.GetHostCPUName();
3475 const llvm_cpu_features = llvm.GetNativeFeatures();
3476 info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features);
3477 cross_target.updateCpuFeatures(&info.target.cpu.features);
3478 info.target.cpu.arch = cross_target.getCpuArch();
3479 }
3480 return info;
3400 return std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
34813401}
34823402
34833403/// Indicate that we are now terminating with a successful exit code.