Commit 893a428656

LemonBoy <thatlemon@gmail.com>
2021-05-12 11:26:37
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.
1 parent 7b77246
Changed files (2)
lib
std
src
lib/std/zig/system.zig
@@ -208,11 +208,6 @@ pub const NativeTargetInfo = struct {
 
     dynamic_linker: DynamicLinker = DynamicLinker{},
 
-    /// Only some architectures have CPU detection implemented. This field reveals whether
-    /// CPU detection actually occurred. When this is `true` it means that the reported
-    /// CPU is baseline only because of a missing implementation for that architecture.
-    cpu_detection_unimplemented: bool = false,
-
     pub const DynamicLinker = Target.DynamicLinker;
 
     pub const DetectError = error{
@@ -367,8 +362,6 @@ pub const NativeTargetInfo = struct {
             os.version_range.linux.glibc = glibc;
         }
 
-        var cpu_detection_unimplemented = false;
-
         // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
         // native CPU architecture as being different than the current target), we use this:
         const cpu_arch = cross_target.getCpuArch();
@@ -382,7 +375,6 @@ pub const NativeTargetInfo = struct {
                 Target.Cpu.baseline(cpu_arch),
             .explicit => |model| model.toCpu(cpu_arch),
         } orelse backup_cpu_detection: {
-            cpu_detection_unimplemented = true;
             break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);
         };
         var result = try detectAbiAndDynamicLinker(allocator, cpu, os, cross_target);
@@ -419,7 +411,6 @@ pub const NativeTargetInfo = struct {
             else => {},
         }
         cross_target.updateCpuFeatures(&result.target.cpu.features);
-        result.cpu_detection_unimplemented = cpu_detection_unimplemented;
         return result;
     }
 
src/main.zig
@@ -3396,88 +3396,8 @@ test "fds" {
     gimmeMoreOfThoseSweetSweetFileDescriptors();
 }
 
-fn detectNativeCpuWithLLVM(
-    arch: std.Target.Cpu.Arch,
-    llvm_cpu_name_z: ?[*:0]const u8,
-    llvm_cpu_features_opt: ?[*:0]const u8,
-) !std.Target.Cpu {
-    var result = std.Target.Cpu.baseline(arch);
-
-    if (llvm_cpu_name_z) |cpu_name_z| {
-        const llvm_cpu_name = mem.spanZ(cpu_name_z);
-
-        for (arch.allCpuModels()) |model| {
-            const this_llvm_name = model.llvm_name orelse continue;
-            if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
-                // Here we use the non-dependencies-populated set,
-                // so that subtracting features later in this function
-                // affect the prepopulated set.
-                result = std.Target.Cpu{
-                    .arch = arch,
-                    .model = model,
-                    .features = model.features,
-                };
-                break;
-            }
-        }
-    }
-
-    const all_features = arch.allFeaturesList();
-
-    if (llvm_cpu_features_opt) |llvm_cpu_features| {
-        var it = mem.tokenize(mem.spanZ(llvm_cpu_features), ",");
-        while (it.next()) |decorated_llvm_feat| {
-            var op: enum {
-                add,
-                sub,
-            } = undefined;
-            var llvm_feat: []const u8 = undefined;
-            if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
-                op = .add;
-                llvm_feat = decorated_llvm_feat[1..];
-            } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
-                op = .sub;
-                llvm_feat = decorated_llvm_feat[1..];
-            } else {
-                return error.InvalidLlvmCpuFeaturesFormat;
-            }
-            for (all_features) |feature, index_usize| {
-                const this_llvm_name = feature.llvm_name orelse continue;
-                if (mem.eql(u8, llvm_feat, this_llvm_name)) {
-                    const index = @intCast(std.Target.Cpu.Feature.Set.Index, index_usize);
-                    switch (op) {
-                        .add => result.features.addFeature(index),
-                        .sub => result.features.removeFeature(index),
-                    }
-                    break;
-                }
-            }
-        }
-    }
-
-    result.features.populateDependencies(all_features);
-    return result;
-}
-
 fn detectNativeTargetInfo(gpa: *Allocator, cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {
-    var info = try std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
-    if (info.cpu_detection_unimplemented) {
-        const arch = std.Target.current.cpu.arch;
-
-        // We want to just use detected_info.target but implementing
-        // CPU model & feature detection is todo so here we rely on LLVM.
-        // https://github.com/ziglang/zig/issues/4591
-        if (!build_options.have_llvm)
-            fatal("CPU features detection is not yet available for {s} without LLVM extensions", .{@tagName(arch)});
-
-        const llvm = @import("codegen/llvm/bindings.zig");
-        const llvm_cpu_name = llvm.GetHostCPUName();
-        const llvm_cpu_features = llvm.GetNativeFeatures();
-        info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features);
-        cross_target.updateCpuFeatures(&info.target.cpu.features);
-        info.target.cpu.arch = cross_target.getCpuArch();
-    }
-    return info;
+    return std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
 }
 
 /// Indicate that we are now terminating with a successful exit code.