authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-01 21:14:57+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-10 12:21:57+02:00
log837e0f9c377d66f323926427551cc7db84a7151d
treeb855afbf64f9af7793c629b84131d1cca94b0dfb
parent2c241b263cf165cdde4b3b1df3ce551d915ee476

std.Target: Remove ObjectFormat.nvptx (and associated linker code).

Textual PTX is just assembly language like any other. And if we do ever add support for emitting PTX object files after reverse engineering the bytecode format, we'd be emitting ELF files like the CUDA toolchain. So there's really no need for a special ObjectFormat tag here, nor linker code that treats it as a distinct format.

9 files changed, 4 insertions(+), 147 deletions(-)

CMakeLists.txt-1
......@@ -640,7 +640,6 @@ set(ZIG_STAGE2_SOURCES
640640 src/link/MachO/synthetic.zig
641641 src/link/MachO/Thunk.zig
642642 src/link/MachO/uuid.zig
643 src/link/NvPtx.zig
644643 src/link/Plan9.zig
645644 src/link/Plan9/aout.zig
646645 src/link/SpirV.zig
lib/std/Target.zig-4
......@@ -1017,8 +1017,6 @@ pub const ObjectFormat = enum {
10171017 hex,
10181018 /// The Mach object format used by macOS and other Apple platforms.
10191019 macho,
1020 /// Nvidia's PTX (Parallel Thread Execution) assembly language.
1021 nvptx,
10221020 /// The a.out format used by Plan 9 from Bell Labs.
10231021 plan9,
10241022 /// Machine code with no metadata.
......@@ -1039,7 +1037,6 @@ pub const ObjectFormat = enum {
10391037 .coff => ".obj",
10401038 .elf, .goff, .macho, .wasm, .xcoff => ".o",
10411039 .hex => ".ihex",
1042 .nvptx => ".ptx",
10431040 .plan9 => arch.plan9Ext(),
10441041 .raw => ".bin",
10451042 .spirv => ".spv",
......@@ -1054,7 +1051,6 @@ pub const ObjectFormat = enum {
10541051 .uefi, .windows => .coff,
10551052 .zos => .goff,
10561053 else => switch (arch) {
1057 .nvptx, .nvptx64 => .nvptx,
10581054 .spirv, .spirv32, .spirv64 => .spirv,
10591055 .wasm32, .wasm64 => .wasm,
10601056 else => .elf,
lib/std/zig.zig-1
......@@ -232,7 +232,6 @@ pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMe
232232 t.libPrefix(), root_name,
233233 }),
234234 },
235 .nvptx => return std.fmt.allocPrint(allocator, "{s}.ptx", .{root_name}),
236235 }
237236}
238237
src/Compilation/Config.zig+1-1
......@@ -434,7 +434,7 @@ pub fn resolve(options: Options) ResolveError!Config {
434434 .windows, .uefi => .code_view,
435435 else => .{ .dwarf = .@"32" },
436436 },
437 .spirv, .nvptx, .hex, .raw, .plan9 => .strip,
437 .spirv, .hex, .raw, .plan9 => .strip,
438438 };
439439 };
440440
src/codegen.zig-2
......@@ -666,7 +666,6 @@ fn lowerUavRef(
666666 switch (lf.tag) {
667667 .c => unreachable,
668668 .spirv => unreachable,
669 .nvptx => unreachable,
670669 .wasm => {
671670 dev.check(link.File.Tag.wasm.devFeature());
672671 const wasm = lf.cast(.wasm).?;
......@@ -739,7 +738,6 @@ fn lowerNavRef(
739738 switch (lf.tag) {
740739 .c => unreachable,
741740 .spirv => unreachable,
742 .nvptx => unreachable,
743741 .wasm => {
744742 dev.check(link.File.Tag.wasm.devFeature());
745743 const wasm = lf.cast(.wasm).?;
src/dev.zig-2
......@@ -81,7 +81,6 @@ pub const Env = enum {
8181 .wasm_linker,
8282 .spirv_linker,
8383 .plan9_linker,
84 .nvptx_linker,
8584 .goff_linker,
8685 .xcoff_linker,
8786 => true,
......@@ -229,7 +228,6 @@ pub const Feature = enum {
229228 wasm_linker,
230229 spirv_linker,
231230 plan9_linker,
232 nvptx_linker,
233231 goff_linker,
234232 xcoff_linker,
235233};
src/link.zig+3-12
......@@ -597,7 +597,7 @@ pub const File = struct {
597597 .mode = determineMode(use_lld, output_mode, link_mode),
598598 });
599599 },
600 .c, .spirv, .nvptx => dev.checkAny(&.{ .c_linker, .spirv_linker, .nvptx_linker }),
600 .c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),
601601 }
602602 }
603603
......@@ -670,7 +670,7 @@ pub const File = struct {
670670 }
671671 }
672672 },
673 .c, .spirv, .nvptx => dev.checkAny(&.{ .c_linker, .spirv_linker, .nvptx_linker }),
673 .c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),
674674 }
675675 }
676676
......@@ -697,7 +697,6 @@ pub const File = struct {
697697 .plan9 => unreachable,
698698 .spirv => unreachable,
699699 .c => unreachable,
700 .nvptx => unreachable,
701700 inline else => |tag| {
702701 dev.check(tag.devFeature());
703702 return @as(*tag.Type(), @fieldParentPtr("base", base)).getGlobalSymbol(name, lib_name);
......@@ -766,7 +765,7 @@ pub const File = struct {
766765 }
767766
768767 switch (base.tag) {
769 .spirv, .nvptx => {},
768 .spirv => {},
770769 .goff, .xcoff => {},
771770 inline else => |tag| {
772771 dev.check(tag.devFeature());
......@@ -901,7 +900,6 @@ pub const File = struct {
901900 switch (base.tag) {
902901 .c => unreachable,
903902 .spirv => unreachable,
904 .nvptx => unreachable,
905903 .wasm => unreachable,
906904 .goff, .xcoff => unreachable,
907905 inline else => |tag| {
......@@ -921,7 +919,6 @@ pub const File = struct {
921919 switch (base.tag) {
922920 .c => unreachable,
923921 .spirv => unreachable,
924 .nvptx => unreachable,
925922 .wasm => unreachable,
926923 .goff, .xcoff => unreachable,
927924 inline else => |tag| {
......@@ -935,7 +932,6 @@ pub const File = struct {
935932 switch (base.tag) {
936933 .c => unreachable,
937934 .spirv => unreachable,
938 .nvptx => unreachable,
939935 .wasm => unreachable,
940936 .goff, .xcoff => unreachable,
941937 inline else => |tag| {
......@@ -953,7 +949,6 @@ pub const File = struct {
953949 switch (base.tag) {
954950 .plan9,
955951 .spirv,
956 .nvptx,
957952 .goff,
958953 .xcoff,
959954 => {},
......@@ -1251,7 +1246,6 @@ pub const File = struct {
12511246 wasm,
12521247 spirv,
12531248 plan9,
1254 nvptx,
12551249 goff,
12561250 xcoff,
12571251
......@@ -1264,7 +1258,6 @@ pub const File = struct {
12641258 .wasm => Wasm,
12651259 .spirv => SpirV,
12661260 .plan9 => Plan9,
1267 .nvptx => NvPtx,
12681261 .goff => Goff,
12691262 .xcoff => Xcoff,
12701263 };
......@@ -1279,7 +1272,6 @@ pub const File = struct {
12791272 .plan9 => .plan9,
12801273 .c => .c,
12811274 .spirv => .spirv,
1282 .nvptx => .nvptx,
12831275 .goff => .goff,
12841276 .xcoff => .xcoff,
12851277 .hex => @panic("TODO implement hex object format"),
......@@ -1386,7 +1378,6 @@ pub const File = struct {
13861378 pub const MachO = @import("link/MachO.zig");
13871379 pub const SpirV = @import("link/SpirV.zig");
13881380 pub const Wasm = @import("link/Wasm.zig");
1389 pub const NvPtx = @import("link/NvPtx.zig");
13901381 pub const Goff = @import("link/Goff.zig");
13911382 pub const Xcoff = @import("link/Xcoff.zig");
13921383 pub const Dwarf = @import("link/Dwarf.zig");
src/link/NvPtx.zig deleted-123
......@@ -1,123 +0,0 @@
1//! NVidia PTX (Parallel Thread Execution)
2//! https://docs.nvidia.com/cuda/parallel-thread-execution/index.html
3//! For this we rely on the nvptx backend of LLVM
4//! Kernel functions need to be marked both as "export" and "callconv(.kernel)"
5
6const NvPtx = @This();
7
8const std = @import("std");
9const builtin = @import("builtin");
10
11const Allocator = std.mem.Allocator;
12const assert = std.debug.assert;
13const log = std.log.scoped(.link);
14const Path = std.Build.Cache.Path;
15
16const Zcu = @import("../Zcu.zig");
17const InternPool = @import("../InternPool.zig");
18const Compilation = @import("../Compilation.zig");
19const link = @import("../link.zig");
20const trace = @import("../tracy.zig").trace;
21const build_options = @import("build_options");
22const Air = @import("../Air.zig");
23const Liveness = @import("../Liveness.zig");
24const LlvmObject = @import("../codegen/llvm.zig").Object;
25
26base: link.File,
27llvm_object: LlvmObject.Ptr,
28
29pub fn createEmpty(
30 arena: Allocator,
31 comp: *Compilation,
32 emit: Path,
33 options: link.File.OpenOptions,
34) !*NvPtx {
35 const target = comp.root_mod.resolved_target.result;
36 const use_lld = build_options.have_llvm and comp.config.use_lld;
37 const use_llvm = comp.config.use_llvm;
38
39 assert(use_llvm); // Caught by Compilation.Config.resolve.
40 assert(!use_lld); // Caught by Compilation.Config.resolve.
41 assert(target.cpu.arch.isNvptx()); // Caught by Compilation.Config.resolve.
42
43 switch (target.os.tag) {
44 // TODO: does it also work with nvcl ?
45 .cuda => {},
46 else => return error.PtxArchNotSupported,
47 }
48
49 const llvm_object = try LlvmObject.create(arena, comp);
50 const nvptx = try arena.create(NvPtx);
51 nvptx.* = .{
52 .base = .{
53 .tag = .nvptx,
54 .comp = comp,
55 .emit = emit,
56 .zcu_object_sub_path = emit.sub_path,
57 .gc_sections = options.gc_sections orelse false,
58 .print_gc_sections = options.print_gc_sections,
59 .stack_size = options.stack_size orelse 0,
60 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
61 .file = null,
62 .disable_lld_caching = options.disable_lld_caching,
63 .build_id = options.build_id,
64 },
65 .llvm_object = llvm_object,
66 };
67
68 return nvptx;
69}
70
71pub fn open(
72 arena: Allocator,
73 comp: *Compilation,
74 emit: Path,
75 options: link.File.OpenOptions,
76) !*NvPtx {
77 const target = comp.root_mod.resolved_target.result;
78 assert(target.ofmt == .nvptx);
79 return createEmpty(arena, comp, emit, options);
80}
81
82pub fn deinit(self: *NvPtx) void {
83 self.llvm_object.deinit();
84}
85
86pub fn updateFunc(
87 self: *NvPtx,
88 pt: Zcu.PerThread,
89 func_index: InternPool.Index,
90 air: Air,
91 liveness: Liveness,
92) link.File.UpdateNavError!void {
93 try self.llvm_object.updateFunc(pt, func_index, air, liveness);
94}
95
96pub fn updateNav(self: *NvPtx, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
97 return self.llvm_object.updateNav(pt, nav);
98}
99
100pub fn updateExports(
101 self: *NvPtx,
102 pt: Zcu.PerThread,
103 exported: Zcu.Exported,
104 export_indices: []const Zcu.Export.Index,
105) !void {
106 if (build_options.skip_non_native and builtin.object_format != .nvptx)
107 @panic("Attempted to compile for object format that was disabled by build configuration");
108
109 return self.llvm_object.updateExports(pt, exported, export_indices);
110}
111
112pub fn flush(self: *NvPtx, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
113 return self.flushModule(arena, tid, prog_node);
114}
115
116pub fn flushModule(self: *NvPtx, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
117 if (build_options.skip_non_native)
118 @panic("Attempted to compile for architecture that was disabled by build configuration");
119
120 _ = tid;
121
122 try self.base.emitLlvmObject(arena, self.llvm_object, prog_node);
123}
src/target.zig-1
......@@ -140,7 +140,6 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
140140 .goff,
141141 .hex,
142142 .macho,
143 .nvptx,
144143 .spirv,
145144 .raw,
146145 .wasm,