authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-25 00:18:30-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-25 00:27:07-05:00
log477be90c0c18a473c5b0c84c0fbcc9ce41e47738
tree2204229b4986881c3ff774516745ed43bf212dbd
parent1453a595aac86b0ca5017c084b5d36108ac414ae

CBE: replace locals list with a hash map

Replace `ArrayList` with `ArrayHashMap` since we want to be able to remove by element.

1 files changed, 17 insertions(+), 22 deletions(-)

src/codegen/c.zig+17-22
......@@ -94,7 +94,7 @@ const Local = struct {
9494
9595const LocalIndex = u16;
9696const LocalType = struct { cty_idx: CType.Index, alignas: CType.AlignAs };
97const LocalsList = std.ArrayListUnmanaged(LocalIndex);
97const LocalsList = std.AutoArrayHashMapUnmanaged(LocalIndex, void);
9898const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList);
9999const LocalsStack = std.ArrayListUnmanaged(LocalsMap);
100100
......@@ -362,10 +362,10 @@ pub const Function = struct {
362362 .cty_idx = try f.typeToIndex(ty, .complete),
363363 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target)),
364364 })) |locals_list| {
365 if (locals_list.popOrNull()) |local_index| {
366 const local = &f.locals.items[local_index];
365 if (locals_list.popOrNull()) |local_entry| {
366 const local = &f.locals.items[local_entry.key];
367367 local.loop_depth = @intCast(LoopDepth, f.free_locals_stack.items.len - 1);
368 return .{ .new_local = local_index };
368 return .{ .new_local = local_entry.key };
369369 }
370370 }
371371
......@@ -2606,7 +2606,7 @@ pub fn genFunc(f: *Function) !void {
26062606 log.debug("inserting local {d} into free_locals", .{local_index});
26072607 const gop = try free_locals.getOrPut(gpa, local.getType());
26082608 if (!gop.found_existing) gop.value_ptr.* = .{};
2609 try gop.value_ptr.append(gpa, local_index);
2609 try gop.value_ptr.putNoClobber(gpa, local_index, {});
26102610 }
26112611
26122612 const SortContext = struct {
......@@ -2622,7 +2622,7 @@ pub fn genFunc(f: *Function) !void {
26222622
26232623 const w = o.code_header.writer();
26242624 for (free_locals.values()) |list| {
2625 for (list.items) |local_index| {
2625 for (list.keys()) |local_index| {
26262626 const local = f.locals.items[local_index];
26272627 try o.dg.renderCTypeAndName(w, local.cty_idx, .{ .local = local_index }, .{}, local.alignas);
26282628 try w.writeAll(";\n ");
......@@ -4494,11 +4494,11 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
44944494 while (it.next()) |entry| {
44954495 const gop = try old_free_locals.getOrPut(gpa, entry.key_ptr.*);
44964496 if (gop.found_existing) {
4497 try gop.value_ptr.appendSlice(gpa, entry.value_ptr.items);
4498 } else {
4499 gop.value_ptr.* = entry.value_ptr.*;
4500 entry.value_ptr.* = .{};
4501 }
4497 try gop.value_ptr.ensureUnusedCapacity(gpa, entry.value_ptr.count());
4498 for (entry.value_ptr.keys()) |local_index| {
4499 gop.value_ptr.putAssumeCapacityNoClobber(local_index, {});
4500 }
4501 } else gop.value_ptr.* = entry.value_ptr.move();
45024502 }
45034503 deinitFreeLocalsMap(gpa, new_free_locals);
45044504 new_free_locals.* = old_free_locals.move();
......@@ -7458,14 +7458,13 @@ fn freeLocal(f: *Function, inst: Air.Inst.Index, local_index: LocalIndex, ref_in
74587458 const gop = try f.free_locals_stack.items[local.loop_depth].getOrPut(gpa, local.getType());
74597459 if (!gop.found_existing) gop.value_ptr.* = .{};
74607460 if (std.debug.runtime_safety) {
7461 // If this trips, it means a local is being inserted into the
7462 // free_locals map while it already exists in the map, which is not
7463 // allowed.
7464 assert(mem.indexOfScalar(LocalIndex, gop.value_ptr.items, local_index) == null);
74657461 // If this trips, an unfreeable allocation was attempted to be freed.
74667462 assert(!f.allocs.contains(local_index));
74677463 }
7468 try gop.value_ptr.append(gpa, local_index);
7464 // If this trips, it means a local is being inserted into the
7465 // free_locals map while it already exists in the map, which is not
7466 // allowed.
7467 try gop.value_ptr.putNoClobber(gpa, local_index, {});
74697468}
74707469
74717470const BigTomb = struct {
......@@ -7528,7 +7527,7 @@ fn noticeBranchFrees(
75287527 if (std.debug.runtime_safety) {
75297528 // new allocs are no longer freeable, so make sure they aren't in the free list
75307529 if (free_locals.getPtr(local.getType())) |locals_list| {
7531 assert(mem.indexOfScalar(LocalIndex, locals_list.items, local_index) == null);
7530 assert(!locals_list.contains(local_index));
75327531 }
75337532 }
75347533 continue;
......@@ -7544,10 +7543,6 @@ fn noticeBranchFrees(
75447543 const local_index = @intCast(LocalIndex, local_i);
75457544 const local = &f.locals.items[local_index];
75467545 // new allocs are no longer freeable, so remove them from the free list
7547 if (free_locals.getPtr(local.getType())) |locals_list| {
7548 if (mem.indexOfScalar(LocalIndex, locals_list.items, local_index)) |i| {
7549 _ = locals_list.swapRemove(i);
7550 }
7551 }
7546 if (free_locals.getPtr(local.getType())) |locals_list| _ = locals_list.swapRemove(local_index);
75527547 }
75537548}