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 {...@@ -94,7 +94,7 @@ const Local = struct {
9494
95const LocalIndex = u16;95const LocalIndex = u16;
96const LocalType = struct { cty_idx: CType.Index, alignas: CType.AlignAs };96const LocalType = struct { cty_idx: CType.Index, alignas: CType.AlignAs };
97const LocalsList = std.ArrayListUnmanaged(LocalIndex);97const LocalsList = std.AutoArrayHashMapUnmanaged(LocalIndex, void);
98const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList);98const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList);
99const LocalsStack = std.ArrayListUnmanaged(LocalsMap);99const LocalsStack = std.ArrayListUnmanaged(LocalsMap);
100100
...@@ -362,10 +362,10 @@ pub const Function = struct {...@@ -362,10 +362,10 @@ pub const Function = struct {
362 .cty_idx = try f.typeToIndex(ty, .complete),362 .cty_idx = try f.typeToIndex(ty, .complete),
363 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target)),363 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target)),
364 })) |locals_list| {364 })) |locals_list| {
365 if (locals_list.popOrNull()) |local_index| {365 if (locals_list.popOrNull()) |local_entry| {
366 const local = &f.locals.items[local_index];366 const local = &f.locals.items[local_entry.key];
367 local.loop_depth = @intCast(LoopDepth, f.free_locals_stack.items.len - 1);367 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 };
369 }369 }
370 }370 }
371371
...@@ -2606,7 +2606,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2606,7 +2606,7 @@ pub fn genFunc(f: *Function) !void {
2606 log.debug("inserting local {d} into free_locals", .{local_index});2606 log.debug("inserting local {d} into free_locals", .{local_index});
2607 const gop = try free_locals.getOrPut(gpa, local.getType());2607 const gop = try free_locals.getOrPut(gpa, local.getType());
2608 if (!gop.found_existing) gop.value_ptr.* = .{};2608 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, {});
2610 }2610 }
26112611
2612 const SortContext = struct {2612 const SortContext = struct {
...@@ -2622,7 +2622,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2622,7 +2622,7 @@ pub fn genFunc(f: *Function) !void {
26222622
2623 const w = o.code_header.writer();2623 const w = o.code_header.writer();
2624 for (free_locals.values()) |list| {2624 for (free_locals.values()) |list| {
2625 for (list.items) |local_index| {2625 for (list.keys()) |local_index| {
2626 const local = f.locals.items[local_index];2626 const local = f.locals.items[local_index];
2627 try o.dg.renderCTypeAndName(w, local.cty_idx, .{ .local = local_index }, .{}, local.alignas);2627 try o.dg.renderCTypeAndName(w, local.cty_idx, .{ .local = local_index }, .{}, local.alignas);
2628 try w.writeAll(";\n ");2628 try w.writeAll(";\n ");
...@@ -4494,11 +4494,11 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4494,11 +4494,11 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
4494 while (it.next()) |entry| {4494 while (it.next()) |entry| {
4495 const gop = try old_free_locals.getOrPut(gpa, entry.key_ptr.*);4495 const gop = try old_free_locals.getOrPut(gpa, entry.key_ptr.*);
4496 if (gop.found_existing) {4496 if (gop.found_existing) {
4497 try gop.value_ptr.appendSlice(gpa, entry.value_ptr.items);4497 try gop.value_ptr.ensureUnusedCapacity(gpa, entry.value_ptr.count());
4498 } else {4498 for (entry.value_ptr.keys()) |local_index| {
4499 gop.value_ptr.* = entry.value_ptr.*;4499 gop.value_ptr.putAssumeCapacityNoClobber(local_index, {});
4500 entry.value_ptr.* = .{};4500 }
4501 }4501 } else gop.value_ptr.* = entry.value_ptr.move();
4502 }4502 }
4503 deinitFreeLocalsMap(gpa, new_free_locals);4503 deinitFreeLocalsMap(gpa, new_free_locals);
4504 new_free_locals.* = old_free_locals.move();4504 new_free_locals.* = old_free_locals.move();
...@@ -7458,14 +7458,13 @@ fn freeLocal(f: *Function, inst: Air.Inst.Index, local_index: LocalIndex, ref_in...@@ -7458,14 +7458,13 @@ fn freeLocal(f: *Function, inst: Air.Inst.Index, local_index: LocalIndex, ref_in
7458 const gop = try f.free_locals_stack.items[local.loop_depth].getOrPut(gpa, local.getType());7458 const gop = try f.free_locals_stack.items[local.loop_depth].getOrPut(gpa, local.getType());
7459 if (!gop.found_existing) gop.value_ptr.* = .{};7459 if (!gop.found_existing) gop.value_ptr.* = .{};
7460 if (std.debug.runtime_safety) {7460 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);
7465 // If this trips, an unfreeable allocation was attempted to be freed.7461 // If this trips, an unfreeable allocation was attempted to be freed.
7466 assert(!f.allocs.contains(local_index));7462 assert(!f.allocs.contains(local_index));
7467 }7463 }
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, {});
7469}7468}
74707469
7471const BigTomb = struct {7470const BigTomb = struct {
...@@ -7528,7 +7527,7 @@ fn noticeBranchFrees(...@@ -7528,7 +7527,7 @@ fn noticeBranchFrees(
7528 if (std.debug.runtime_safety) {7527 if (std.debug.runtime_safety) {
7529 // new allocs are no longer freeable, so make sure they aren't in the free list7528 // new allocs are no longer freeable, so make sure they aren't in the free list
7530 if (free_locals.getPtr(local.getType())) |locals_list| {7529 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));
7532 }7531 }
7533 }7532 }
7534 continue;7533 continue;
...@@ -7544,10 +7543,6 @@ fn noticeBranchFrees(...@@ -7544,10 +7543,6 @@ fn noticeBranchFrees(
7544 const local_index = @intCast(LocalIndex, local_i);7543 const local_index = @intCast(LocalIndex, local_i);
7545 const local = &f.locals.items[local_index];7544 const local = &f.locals.items[local_index];
7546 // new allocs are no longer freeable, so remove them from the free list7545 // new allocs are no longer freeable, so remove them from the free list
7547 if (free_locals.getPtr(local.getType())) |locals_list| {7546 if (free_locals.getPtr(local.getType())) |locals_list| _ = locals_list.swapRemove(local_index);
7548 if (mem.indexOfScalar(LocalIndex, locals_list.items, local_index)) |i| {
7549 _ = locals_list.swapRemove(i);
7550 }
7551 }
7552 }7547 }
7553}7548}