authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-14 00:57:55-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-04-20 20:49:35+01:00
log641bfb939fd9e793f8fbaee886bc09844a4d506e
tree8fa9ce5e6e9f08e46090ce7ca43d5770f9fcfb2a
parent77941862101c9c0c1b11b7d99d01519172189edb
signaturelock-open Commit is signed but in an unrecognized format.

x86_64: use liveness block deaths


1 files changed, 11 insertions(+), 25 deletions(-)

src/arch/x86_64/CodeGen.zig+11-25
...@@ -280,12 +280,10 @@ const StackAllocation = struct {...@@ -280,12 +280,10 @@ const StackAllocation = struct {
280280
281const BlockData = struct {281const 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,
285284
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}
13821380
1383fn restoreState(self: *Self, state: State, deaths: []u32, comptime opts: struct {1381fn 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 }
13931391
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 instead1396 .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);
14041400
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 {
65216517
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);
65246521
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).?;
66506647
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)) {