| ... | @@ -11108,11 +11108,37 @@ fn finishSwitchBr( | ... | @@ -11108,11 +11108,37 @@ fn finishSwitchBr( |
| 11108 | const estimated_cases_len: u32 = scalar_cases_len + multi_cases_len + | 11108 | const estimated_cases_len: u32 = scalar_cases_len + multi_cases_len + |
| 11109 | @intFromBool(has_else or has_under); | 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 | var cases_extra: std.ArrayList(u32) = try .initCapacity(gpa, estimated_cases_len * | 11139 | var cases_extra: std.ArrayList(u32) = try .initCapacity(gpa, estimated_cases_len * |
| 11112 | @typeInfo(Air.SwitchBr.Case).@"struct".fields.len); | 11140 | @typeInfo(Air.SwitchBr.Case).@"struct".fields.len); |
| 11113 | defer cases_extra.deinit(gpa); | 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 | // We will reuse this block for each case. | 11143 | // We will reuse this block for each case. |
| 11118 | var case_block = child_block.makeSubBlock(); | 11144 | var case_block = child_block.makeSubBlock(); |