| ... | @@ -94,7 +94,7 @@ const Local = struct { | ... | @@ -94,7 +94,7 @@ const Local = struct { |
| 94 | | 94 | |
| 95 | const LocalIndex = u16; | 95 | const LocalIndex = u16; |
| 96 | const LocalType = struct { cty_idx: CType.Index, alignas: CType.AlignAs }; | 96 | const LocalType = struct { cty_idx: CType.Index, alignas: CType.AlignAs }; |
| 97 | const LocalsList = std.ArrayListUnmanaged(LocalIndex); | 97 | const LocalsList = std.AutoArrayHashMapUnmanaged(LocalIndex, void); |
| 98 | const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList); | 98 | const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList); |
| 99 | const LocalsStack = std.ArrayListUnmanaged(LocalsMap); | 99 | const LocalsStack = std.ArrayListUnmanaged(LocalsMap); |
| 100 | | 100 | |
| ... | @@ -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 | } |
| 371 | | 371 | |
| ... | @@ -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 | } |
| 2611 | | 2611 | |
| 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 { |
| 2622 | | 2622 | |
| 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 | } |
| 7470 | | 7469 | |
| 7471 | const BigTomb = struct { | 7470 | const 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 list | 7528 | // 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 list | 7545 | // 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 | } |