| ... | @@ -280,12 +280,10 @@ const StackAllocation = struct { | ... | @@ -280,12 +280,10 @@ const StackAllocation = struct { |
| 280 | | 280 | |
| 281 | const BlockData = struct { | 281 | const BlockData = struct { |
| 282 | relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .{}, | 282 | relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .{}, |
| 283 | deaths: std.ArrayListUnmanaged(u32) = .{}, // inst_tracking indices | | |
| 284 | state: State, | 283 | state: State, |
| 285 | | 284 | |
| 286 | fn deinit(self: *BlockData, gpa: Allocator) void { | 285 | fn deinit(self: *BlockData, gpa: Allocator) void { |
| 287 | self.relocs.deinit(gpa); | 286 | self.relocs.deinit(gpa); |
| 288 | self.deaths.deinit(gpa); | | |
| 289 | self.* = undefined; | 287 | self.* = undefined; |
| 290 | } | 288 | } |
| 291 | }; | 289 | }; |
| ... | @@ -1380,7 +1378,7 @@ fn saveState(self: *Self) !State { | ... | @@ -1380,7 +1378,7 @@ fn saveState(self: *Self) !State { |
| 1380 | return state; | 1378 | return state; |
| 1381 | } | 1379 | } |
| 1382 | | 1380 | |
| 1383 | fn restoreState(self: *Self, state: State, deaths: []u32, comptime opts: struct { | 1381 | fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, comptime opts: struct { |
| 1384 | emit_instructions: bool, | 1382 | emit_instructions: bool, |
| 1385 | update_tracking: bool, | 1383 | update_tracking: bool, |
| 1386 | resurrect: bool, | 1384 | resurrect: bool, |
| ... | @@ -1391,16 +1389,14 @@ fn restoreState(self: *Self, state: State, deaths: []u32, comptime opts: struct | ... | @@ -1391,16 +1389,14 @@ fn restoreState(self: *Self, state: State, deaths: []u32, comptime opts: struct |
| 1391 | self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len); | 1389 | self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len); |
| 1392 | } | 1390 | } |
| 1393 | | 1391 | |
| 1394 | if (opts.resurrect) { | 1392 | if (opts.resurrect) for (self.inst_tracking.values()[0..state.inst_tracking_len]) |*tracking| |
| 1395 | var death_i: usize = 0; | 1393 | tracking.resurrect(state.scope_generation); |
| 1396 | for (self.inst_tracking.values()[0..state.inst_tracking_len], 0..) |*tracking, tracking_i| { | 1394 | const air_tags = self.air.instructions.items(.tag); |
| 1397 | if (death_i < deaths.len and deaths[death_i] == tracking_i) { | 1395 | for (deaths) |death| switch (air_tags[death]) { |
| 1398 | // oops, it was actually a death instead | 1396 | .constant => {}, |
| 1399 | death_i += 1; | 1397 | .const_ty => unreachable, |
| 1400 | tracking.die(self); | 1398 | else => self.inst_tracking.getPtr(death).?.die(self), |
| 1401 | } else tracking.resurrect(state.scope_generation); | 1399 | }; |
| 1402 | } | | |
| 1403 | } else assert(deaths.len == 0); | | |
| 1404 | | 1400 | |
| 1405 | for (0..state.registers.len) |index| { | 1401 | for (0..state.registers.len) |index| { |
| 1406 | const current_maybe_inst = if (self.register_manager.free_registers.isSet(index)) | 1402 | const current_maybe_inst = if (self.register_manager.free_registers.isSet(index)) |
| ... | @@ -6521,6 +6517,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6521,6 +6517,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 6521 | | 6517 | |
| 6522 | self.scope_generation += 1; | 6518 | self.scope_generation += 1; |
| 6523 | try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() }); | 6519 | try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() }); |
| | 6520 | const liveness = self.liveness.getBlock(inst); |
| 6524 | | 6521 | |
| 6525 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 6522 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 6526 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 6523 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| ... | @@ -6530,7 +6527,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6530,7 +6527,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 6530 | var block_data = self.blocks.fetchRemove(inst).?; | 6527 | var block_data = self.blocks.fetchRemove(inst).?; |
| 6531 | defer block_data.value.deinit(self.gpa); | 6528 | defer block_data.value.deinit(self.gpa); |
| 6532 | if (block_data.value.relocs.items.len > 0) { | 6529 | if (block_data.value.relocs.items.len > 0) { |
| 6533 | try self.restoreState(block_data.value.state, block_data.value.deaths.items, .{ | 6530 | try self.restoreState(block_data.value.state, liveness.deaths, .{ |
| 6534 | .emit_instructions = false, | 6531 | .emit_instructions = false, |
| 6535 | .update_tracking = true, | 6532 | .update_tracking = true, |
| 6536 | .resurrect = true, | 6533 | .resurrect = true, |
| ... | @@ -6649,17 +6646,6 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6649,17 +6646,6 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 6649 | const block_data = self.blocks.getPtr(br.block_inst).?; | 6646 | const block_data = self.blocks.getPtr(br.block_inst).?; |
| 6650 | | 6647 | |
| 6651 | if (block_data.relocs.items.len == 0) { | 6648 | if (block_data.relocs.items.len == 0) { |
| 6652 | // We need to compute a list of deaths for later. This list needs to include | | |
| 6653 | // instructions that was born before, and has died since, the target block. | | |
| 6654 | for ( | | |
| 6655 | self.inst_tracking.values()[0..block_data.state.inst_tracking_len], | | |
| 6656 | 0.., | | |
| 6657 | ) |*tracking, tracked_index| switch (tracking.short) { | | |
| 6658 | .dead => |die_generation| if (die_generation >= block_data.state.scope_generation) | | |
| 6659 | try block_data.deaths.append(self.gpa, @intCast(u32, tracked_index)), | | |
| 6660 | else => {}, | | |
| 6661 | }; | | |
| 6662 | | | |
| 6663 | block_tracking.* = InstTracking.init(result: { | 6649 | block_tracking.* = InstTracking.init(result: { |
| 6664 | if (block_unused) break :result .none; | 6650 | if (block_unused) break :result .none; |
| 6665 | if (self.reuseOperand(inst, br.operand, 0, src_mcv)) { | 6651 | if (self.reuseOperand(inst, br.operand, 0, src_mcv)) { |