C backend: remove unneeded ordering mechanism

This logic to lower snippets of C code in a dependency order is no
longer needed. Simplify the logic by deleting the mechanism.
This commit is contained in:
Andrew Kelley 2023-09-29 16:02:00 -07:00
parent 101df768a0
commit 0d841e827a

View File

@ -322,29 +322,19 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
self.lazy_code_buf.clearRetainingCapacity();
try self.flushErrDecls(&f.lazy_ctypes);
// Unlike other backends, the .c code we are emitting has order-dependent decls.
// `CType`s, forward decls, and non-functions first.
// Unlike other backends, the .c code we are emitting is order-dependent. Therefore
// we must traverse the set of Decls that we are emitting according to their dependencies.
// Our strategy is to populate a set of remaining decls, pop Decls one by one,
// recursively chasing their dependencies.
try f.remaining_decls.ensureUnusedCapacity(gpa, self.decl_table.count());
const decl_keys = self.decl_table.keys();
const decl_values = self.decl_table.values();
for (decl_keys) |decl_index| {
assert(module.declPtr(decl_index).has_tv);
f.remaining_decls.putAssumeCapacityNoClobber(decl_index, {});
}
{
var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
defer export_names.deinit(gpa);
try export_names.ensureTotalCapacity(gpa, @as(u32, @intCast(module.decl_exports.entries.len)));
try export_names.ensureTotalCapacity(gpa, @intCast(module.decl_exports.entries.len));
for (module.decl_exports.values()) |exports| for (exports.items) |@"export"|
try export_names.put(gpa, @"export".opts.name, {});
while (f.remaining_decls.popOrNull()) |kv| {
const decl_index = kv.key;
const decl_keys = self.decl_table.keys();
for (decl_keys) |decl_index| {
assert(module.declPtr(decl_index).has_tv);
try self.flushDecl(&f, decl_index, export_names);
}
}
@ -374,6 +364,7 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
f.file_size += lazy_fwd_decl_len;
// Now the code.
const decl_values = self.decl_table.values();
try f.all_buffers.ensureUnusedCapacity(gpa, 1 + decl_values.len);
f.appendBufAssumeCapacity(self.lazy_code_buf.items);
for (decl_values) |decl| f.appendBufAssumeCapacity(self.getString(decl.code));
@ -384,8 +375,6 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
}
const Flush = struct {
remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},
ctypes: codegen.CType.Store = .{},
ctypes_map: std.ArrayListUnmanaged(codegen.CType.Index) = .{},
ctypes_buf: std.ArrayListUnmanaged(u8) = .{},
@ -416,7 +405,6 @@ const Flush = struct {
f.ctypes_buf.deinit(gpa);
f.ctypes_map.deinit(gpa);
f.ctypes.deinit(gpa);
f.remaining_decls.deinit(gpa);
}
};
@ -591,7 +579,6 @@ fn flushLazyFns(self: *C, f: *Flush, lazy_fns: codegen.LazyFnMap) FlushDeclError
}
}
/// Assumes `decl` was in the `remaining_decls` set, and has already been removed.
fn flushDecl(
self: *C,
f: *Flush,
@ -601,14 +588,6 @@ fn flushDecl(
const gpa = self.base.allocator;
const mod = self.base.options.module.?;
const decl = mod.declPtr(decl_index);
// Before flushing any particular Decl we must ensure its
// dependencies are already flushed, so that the order in the .c
// file comes out correctly.
for (decl.dependencies.keys()) |dep| {
if (f.remaining_decls.swapRemove(dep)) {
try flushDecl(self, f, dep, export_names);
}
}
const decl_block = self.decl_table.getPtr(decl_index).?;