| author | |
| committer | |
| log | 3a4a7d2ca378862dd6b31678a143315a9e306f8c |
| tree | bd9b7f891cfe67eb56bba8f1f3b34389e15e1017 |
| parent | 9a225456cb6e9079a6e435b264d25bd5f750e7bb |
| signature |
2 files changed, 28 insertions(+), 46 deletions(-)
src/Air.zig-44| ... | ... | @@ -1339,50 +1339,6 @@ pub const SwitchBr = struct { |
| 1339 | 1339 | ranges_len: u32, |
| 1340 | 1340 | body_len: u32, |
| 1341 | 1341 | }; |
| 1342 | ||
| 1343 | pub const BranchHints = struct { | |
| 1344 | bags: std.ArrayList(u32), | |
| 1345 | count: u32, | |
| 1346 | ||
| 1347 | const hints_per_bag = 10; | |
| 1348 | const hint_bits = @bitSizeOf(std.builtin.BranchHint); | |
| 1349 | ||
| 1350 | pub const empty: BranchHints = .{ | |
| 1351 | .bags = .empty, | |
| 1352 | .count = 0, | |
| 1353 | }; | |
| 1354 | ||
| 1355 | pub fn initCapacity(gpa: std.mem.Allocator, num: u32) std.mem.Allocator.Error!BranchHints { | |
| 1356 | const bags_required = std.math.divCeil(u32, num, hints_per_bag) catch unreachable; | |
| 1357 | const bags: std.ArrayList(u32) = try .initCapacity(gpa, bags_required); | |
| 1358 | return .{ .bags = bags, .count = 0 }; | |
| 1359 | } | |
| 1360 | ||
| 1361 | pub fn ensureUnusedCapacity(hints: *BranchHints, gpa: std.mem.Allocator, additional_count: u32) std.mem.Allocator.Error!void { | |
| 1362 | const unused_hints = hints.bags.capacity * hints_per_bag - hints.count; | |
| 1363 | if (unused_hints >= additional_count) return; | |
| 1364 | const bags_required = std.math.divCeil(u32, hints.count + additional_count, hints_per_bag) catch unreachable; | |
| 1365 | return hints.bags.ensureUnusedCapacity(gpa, bags_required); | |
| 1366 | } | |
| 1367 | ||
| 1368 | pub fn appendAssumeCapacity(hints: *BranchHints, hint: std.builtin.BranchHint) void { | |
| 1369 | const idx_in_bag = hints.count % hints_per_bag; | |
| 1370 | var bag: u32 = if (idx_in_bag > 0) hints.bags.pop().? else 0; | |
| 1371 | bag |= @as(u32, @intFromEnum(hint)) << @intCast(hint_bits * idx_in_bag); | |
| 1372 | hints.count += 1; | |
| 1373 | return hints.bags.appendAssumeCapacity(bag); | |
| 1374 | } | |
| 1375 | ||
| 1376 | pub fn append(hints: *BranchHints, gpa: std.mem.Allocator, hint: std.builtin.BranchHint) std.mem.Allocator.Error!void { | |
| 1377 | try hints.ensureUnusedCapacity(gpa, 1); | |
| 1378 | return hints.appendAssumeCapacity(hint); | |
| 1379 | } | |
| 1380 | ||
| 1381 | pub fn deinit(hints: *BranchHints, gpa: std.mem.Allocator) void { | |
| 1382 | hints.bags.deinit(gpa); | |
| 1383 | hints.* = undefined; | |
| 1384 | } | |
| 1385 | }; | |
| 1386 | 1342 | }; |
| 1387 | 1343 | |
| 1388 | 1344 | /// This data is stored inside extra. Trailing: |
src/Sema.zig+28-2| ... | ... | @@ -11108,11 +11108,37 @@ fn finishSwitchBr( |
| 11108 | 11108 | const estimated_cases_len: u32 = scalar_cases_len + multi_cases_len + |
| 11109 | 11109 | @intFromBool(has_else or has_under); |
| 11110 | 11110 | |
| 11111 | const BranchHints = struct { | |
| 11112 | bags: std.ArrayList(u32), | |
| 11113 | count: u32, | |
| 11114 | const hints_per_bag = 10; | |
| 11115 | fn ensureUnusedCapacity(hints: *@This(), gpa_inner: Allocator, additional_count: u32) Allocator.Error!void { | |
| 11116 | const unused_hints = hints.bags.capacity * hints_per_bag - hints.count; | |
| 11117 | if (unused_hints >= additional_count) return; | |
| 11118 | const bags_required = std.math.divCeil(u32, hints.count + additional_count, hints_per_bag) catch unreachable; | |
| 11119 | return hints.bags.ensureUnusedCapacity(gpa_inner, bags_required); | |
| 11120 | } | |
| 11121 | fn appendAssumeCapacity(hints: *@This(), hint: std.builtin.BranchHint) void { | |
| 11122 | const idx_in_bag = hints.count % hints_per_bag; | |
| 11123 | var bag: u32 = if (idx_in_bag > 0) hints.bags.pop().? else 0; | |
| 11124 | bag |= @as(u32, @intFromEnum(hint)) << @intCast(@bitSizeOf(std.builtin.BranchHint) * idx_in_bag); | |
| 11125 | hints.count += 1; | |
| 11126 | return hints.bags.appendAssumeCapacity(bag); | |
| 11127 | } | |
| 11128 | fn append(hints: *@This(), gpa_inner: Allocator, hint: std.builtin.BranchHint) Allocator.Error!void { | |
| 11129 | try hints.ensureUnusedCapacity(gpa_inner, 1); | |
| 11130 | return hints.appendAssumeCapacity(hint); | |
| 11131 | } | |
| 11132 | }; | |
| 11133 | var branch_hints: BranchHints = hints: { | |
| 11134 | const num_bags = std.math.divCeil(u32, estimated_cases_len, BranchHints.hints_per_bag) catch unreachable; | |
| 11135 | break :hints .{ .bags = try .initCapacity(gpa, num_bags), .count = 0 }; | |
| 11136 | }; | |
| 11137 | defer branch_hints.bags.deinit(gpa); | |
| 11138 | ||
| 11111 | 11139 | var cases_extra: std.ArrayList(u32) = try .initCapacity(gpa, estimated_cases_len * |
| 11112 | 11140 | @typeInfo(Air.SwitchBr.Case).@"struct".fields.len); |
| 11113 | 11141 | defer cases_extra.deinit(gpa); |
| 11114 | var branch_hints: Air.SwitchBr.BranchHints = try .initCapacity(gpa, estimated_cases_len); | |
| 11115 | defer branch_hints.deinit(gpa); | |
| 11116 | 11142 | |
| 11117 | 11143 | // We will reuse this block for each case. |
| 11118 | 11144 | var case_block = child_block.makeSubBlock(); |