Skip to content

Commit dcdb442

Browse files
authored
Merge pull request #24124 from mlugg/better-backend-pipeline-2
compiler: threaded codegen (and more goodies)
2 parents 5e3c0b7 + 43d01ff commit dcdb442

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+8061
-7609
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,6 @@ set(ZIG_STAGE2_SOURCES
535535
src/Sema.zig
536536
src/Sema/bitcast.zig
537537
src/Sema/comptime_ptr_access.zig
538-
src/ThreadSafeQueue.zig
539538
src/Type.zig
540539
src/Value.zig
541540
src/Zcu.zig
@@ -624,6 +623,7 @@ set(ZIG_STAGE2_SOURCES
624623
src/link/Elf/synthetic_sections.zig
625624
src/link/Goff.zig
626625
src/link/LdScript.zig
626+
src/link/Lld.zig
627627
src/link/MachO.zig
628628
src/link/MachO/Archive.zig
629629
src/link/MachO/Atom.zig
@@ -652,6 +652,7 @@ set(ZIG_STAGE2_SOURCES
652652
src/link/MachO/uuid.zig
653653
src/link/Plan9.zig
654654
src/link/Plan9/aout.zig
655+
src/link/Queue.zig
655656
src/link/SpirV.zig
656657
src/link/SpirV/BinaryModule.zig
657658
src/link/SpirV/deduplicate.zig

lib/std/Build/Step/Compile.zig

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,47 +1834,16 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
18341834
lp.path = b.fmt("{}", .{output_dir});
18351835
}
18361836

1837-
// -femit-bin[=path] (default) Output machine code
1838-
if (compile.generated_bin) |bin| {
1839-
bin.path = output_dir.joinString(b.allocator, compile.out_filename) catch @panic("OOM");
1840-
}
1841-
1842-
const sep = std.fs.path.sep_str;
1843-
1844-
// output PDB if someone requested it
1845-
if (compile.generated_pdb) |pdb| {
1846-
pdb.path = b.fmt("{}" ++ sep ++ "{s}.pdb", .{ output_dir, compile.name });
1847-
}
1848-
1849-
// -femit-implib[=path] (default) Produce an import .lib when building a Windows DLL
1850-
if (compile.generated_implib) |implib| {
1851-
implib.path = b.fmt("{}" ++ sep ++ "{s}.lib", .{ output_dir, compile.name });
1852-
}
1853-
1854-
// -femit-h[=path] Generate a C header file (.h)
1855-
if (compile.generated_h) |lp| {
1856-
lp.path = b.fmt("{}" ++ sep ++ "{s}.h", .{ output_dir, compile.name });
1857-
}
1858-
1859-
// -femit-docs[=path] Create a docs/ dir with html documentation
1860-
if (compile.generated_docs) |generated_docs| {
1861-
generated_docs.path = output_dir.joinString(b.allocator, "docs") catch @panic("OOM");
1862-
}
1863-
1864-
// -femit-asm[=path] Output .s (assembly code)
1865-
if (compile.generated_asm) |lp| {
1866-
lp.path = b.fmt("{}" ++ sep ++ "{s}.s", .{ output_dir, compile.name });
1867-
}
1868-
1869-
// -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions)
1870-
if (compile.generated_llvm_ir) |lp| {
1871-
lp.path = b.fmt("{}" ++ sep ++ "{s}.ll", .{ output_dir, compile.name });
1872-
}
1873-
1874-
// -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions)
1875-
if (compile.generated_llvm_bc) |lp| {
1876-
lp.path = b.fmt("{}" ++ sep ++ "{s}.bc", .{ output_dir, compile.name });
1877-
}
1837+
// zig fmt: off
1838+
if (compile.generated_bin) |lp| lp.path = compile.outputPath(output_dir, .bin);
1839+
if (compile.generated_pdb) |lp| lp.path = compile.outputPath(output_dir, .pdb);
1840+
if (compile.generated_implib) |lp| lp.path = compile.outputPath(output_dir, .implib);
1841+
if (compile.generated_h) |lp| lp.path = compile.outputPath(output_dir, .h);
1842+
if (compile.generated_docs) |lp| lp.path = compile.outputPath(output_dir, .docs);
1843+
if (compile.generated_asm) |lp| lp.path = compile.outputPath(output_dir, .@"asm");
1844+
if (compile.generated_llvm_ir) |lp| lp.path = compile.outputPath(output_dir, .llvm_ir);
1845+
if (compile.generated_llvm_bc) |lp| lp.path = compile.outputPath(output_dir, .llvm_bc);
1846+
// zig fmt: on
18781847
}
18791848

18801849
if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic and
@@ -1888,6 +1857,21 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
18881857
);
18891858
}
18901859
}
1860+
fn outputPath(c: *Compile, out_dir: std.Build.Cache.Path, ea: std.zig.EmitArtifact) []const u8 {
1861+
const arena = c.step.owner.graph.arena;
1862+
const name = ea.cacheName(arena, .{
1863+
.root_name = c.name,
1864+
.target = c.root_module.resolved_target.?.result,
1865+
.output_mode = switch (c.kind) {
1866+
.lib => .Lib,
1867+
.obj, .test_obj => .Obj,
1868+
.exe, .@"test" => .Exe,
1869+
},
1870+
.link_mode = c.linkage,
1871+
.version = c.version,
1872+
}) catch @panic("OOM");
1873+
return out_dir.joinString(arena, name) catch @panic("OOM");
1874+
}
18911875

18921876
pub fn rebuildInFuzzMode(c: *Compile, progress_node: std.Progress.Node) !Path {
18931877
const gpa = c.step.owner.allocator;

lib/std/Progress.zig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,28 @@ pub const Node = struct {
234234
_ = @atomicRmw(u32, &storage.completed_count, .Add, 1, .monotonic);
235235
}
236236

237+
/// Thread-safe. Bytes after '0' in `new_name` are ignored.
238+
pub fn setName(n: Node, new_name: []const u8) void {
239+
const index = n.index.unwrap() orelse return;
240+
const storage = storageByIndex(index);
241+
242+
const name_len = @min(max_name_len, std.mem.indexOfScalar(u8, new_name, 0) orelse new_name.len);
243+
244+
copyAtomicStore(storage.name[0..name_len], new_name[0..name_len]);
245+
if (name_len < storage.name.len)
246+
@atomicStore(u8, &storage.name[name_len], 0, .monotonic);
247+
}
248+
249+
/// Gets the name of this `Node`.
250+
/// A pointer to this array can later be passed to `setName` to restore the name.
251+
pub fn getName(n: Node) [max_name_len]u8 {
252+
var dest: [max_name_len]u8 align(@alignOf(usize)) = undefined;
253+
if (n.index.unwrap()) |index| {
254+
copyAtomicLoad(&dest, &storageByIndex(index).name);
255+
}
256+
return dest;
257+
}
258+
237259
/// Thread-safe.
238260
pub fn setCompletedItems(n: Node, completed_items: usize) void {
239261
const index = n.index.unwrap() orelse return;

lib/std/heap/debug_allocator.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ pub fn DebugAllocator(comptime config: Config) type {
212212
DummyMutex{};
213213

214214
const DummyMutex = struct {
215-
inline fn lock(_: *DummyMutex) void {}
216-
inline fn unlock(_: *DummyMutex) void {}
215+
inline fn lock(_: DummyMutex) void {}
216+
inline fn unlock(_: DummyMutex) void {}
217217
};
218218

219219
const stack_n = config.stack_trace_frames;

lib/std/multi_array_list.zig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,22 @@ pub fn MultiArrayList(comptime T: type) type {
135135
self.* = undefined;
136136
}
137137

138+
/// Returns a `Slice` representing a range of elements in `s`, analagous to `arr[off..len]`.
139+
/// It is illegal to call `deinit` or `toMultiArrayList` on the returned `Slice`.
140+
/// Asserts that `off + len <= s.len`.
141+
pub fn subslice(s: Slice, off: usize, len: usize) Slice {
142+
assert(off + len <= s.len);
143+
var ptrs: [fields.len][*]u8 = undefined;
144+
inline for (s.ptrs, &ptrs, fields) |in, *out, field| {
145+
out.* = in + (off * @sizeOf(field.type));
146+
}
147+
return .{
148+
.ptrs = ptrs,
149+
.len = len,
150+
.capacity = len,
151+
};
152+
}
153+
138154
/// This function is used in the debugger pretty formatters in tools/ to fetch the
139155
/// child field order and entry type to facilitate fancy debug printing for this type.
140156
fn dbHelper(self: *Slice, child: *Elem, field: *Field, entry: *Entry) void {

lib/std/zig.zig

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,35 @@ pub const SimpleComptimeReason = enum(u32) {
884884
}
885885
};
886886

887+
/// Every kind of artifact which the compiler can emit.
888+
pub const EmitArtifact = enum {
889+
bin,
890+
@"asm",
891+
implib,
892+
llvm_ir,
893+
llvm_bc,
894+
docs,
895+
pdb,
896+
h,
897+
898+
/// If using `Server` to communicate with the compiler, it will place requested artifacts in
899+
/// paths under the output directory, where those paths are named according to this function.
900+
/// Returned string is allocated with `gpa` and owned by the caller.
901+
pub fn cacheName(ea: EmitArtifact, gpa: Allocator, opts: BinNameOptions) Allocator.Error![]const u8 {
902+
const suffix: []const u8 = switch (ea) {
903+
.bin => return binNameAlloc(gpa, opts),
904+
.@"asm" => ".s",
905+
.implib => ".lib",
906+
.llvm_ir => ".ll",
907+
.llvm_bc => ".bc",
908+
.docs => "-docs",
909+
.pdb => ".pdb",
910+
.h => ".h",
911+
};
912+
return std.fmt.allocPrint(gpa, "{s}{s}", .{ opts.root_name, suffix });
913+
}
914+
};
915+
887916
test {
888917
_ = Ast;
889918
_ = AstRlAnnotate;

lib/std/zig/Zir.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4861,6 +4861,15 @@ pub fn getParamBody(zir: Zir, fn_inst: Inst.Index) []const Zir.Inst.Index {
48614861
}
48624862
}
48634863

4864+
pub fn getParamName(zir: Zir, param_inst: Inst.Index) ?NullTerminatedString {
4865+
const inst = zir.instructions.get(@intFromEnum(param_inst));
4866+
return switch (inst.tag) {
4867+
.param, .param_comptime => zir.extraData(Inst.Param, inst.data.pl_tok.payload_index).data.name,
4868+
.param_anytype, .param_anytype_comptime => inst.data.str_tok.start,
4869+
else => null,
4870+
};
4871+
}
4872+
48644873
pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
48654874
const tags = zir.instructions.items(.tag);
48664875
const datas = zir.instructions.items(.data);

src/Air.zig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,9 +1153,7 @@ pub const Inst = struct {
11531153
ty: Type,
11541154
arg: struct {
11551155
ty: Ref,
1156-
/// Index into `extra` of a null-terminated string representing the parameter name.
1157-
/// This is `.none` if debug info is stripped.
1158-
name: NullTerminatedString,
1156+
zir_param_index: u32,
11591157
},
11601158
ty_op: struct {
11611159
ty: Ref,

src/Air/print.zig

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,7 @@ const Writer = struct {
363363
fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
364364
const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
365365
try w.writeType(s, arg.ty.toType());
366-
switch (arg.name) {
367-
.none => {},
368-
_ => try s.print(", \"{}\"", .{std.zig.fmtEscapes(arg.name.toSlice(w.air))}),
369-
}
366+
try s.print(", {d}", .{arg.zir_param_index});
370367
}
371368

372369
fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {

0 commit comments

Comments
 (0)