authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-10 03:29:32-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-04-20 20:49:35+01:00
log07d57623b30991ac00160a0ac0e3c44d85c73931
tree7ab17d800e48fc6554e756240bebde8699f804cd
parentf18ee1e2a2d4fb7ece2741efbfe4bda8b056068e
signaturelock-open Commit is signed but in an unrecognized format.

x86_64: instruction tracking cleanup


1 files changed, 109 insertions(+), 84 deletions(-)

src/arch/x86_64/CodeGen.zig+109-84
...@@ -337,6 +337,8 @@ pub fn generate(...@@ -337,6 +337,8 @@ pub fn generate(
337 };337 };
338 defer {338 defer {
339 function.stack.deinit(gpa);339 function.stack.deinit(gpa);
340 var block_it = function.blocks.valueIterator();
341 while (block_it.next()) |block| block.deinit(gpa);
340 function.blocks.deinit(gpa);342 function.blocks.deinit(gpa);
341 function.inst_tracking.deinit(gpa);343 function.inst_tracking.deinit(gpa);
342 function.const_tracking.deinit(gpa);344 function.const_tracking.deinit(gpa);
...@@ -1184,7 +1186,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1184,7 +1186,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1184 var it = self.register_manager.free_registers.iterator(.{ .kind = .unset });1186 var it = self.register_manager.free_registers.iterator(.{ .kind = .unset });
1185 while (it.next()) |index| {1187 while (it.next()) |index| {
1186 const tracked_inst = self.register_manager.registers[index];1188 const tracked_inst = self.register_manager.registers[index];
1187 const tracking = self.getResolvedInstValue(tracked_inst).?;1189 const tracking = self.getResolvedInstValue(tracked_inst);
1188 assert(RegisterManager.indexOfRegIntoTracked(switch (tracking.short) {1190 assert(RegisterManager.indexOfRegIntoTracked(switch (tracking.short) {
1189 .register => |reg| reg,1191 .register => |reg| reg,
1190 .register_overflow => |ro| ro.reg,1192 .register_overflow => |ro| ro.reg,
...@@ -1232,7 +1234,7 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {...@@ -1232,7 +1234,7 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {
1232 const air_tags = self.air.instructions.items(.tag);1234 const air_tags = self.air.instructions.items(.tag);
1233 if (air_tags[inst] == .constant) return;1235 if (air_tags[inst] == .constant) return;
1234 log.debug("%{d} => {}", .{ inst, MCValue.dead });1236 log.debug("%{d} => {}", .{ inst, MCValue.dead });
1235 if (self.getResolvedInstValue(inst)) |tracking| tracking.die(self);1237 self.inst_tracking.getPtr(inst).?.die(self);
1236}1238}
12371239
1238/// Called when there are no operands, and the instruction is always unreferenced.1240/// Called when there are no operands, and the instruction is always unreferenced.
...@@ -1378,7 +1380,7 @@ fn saveState(self: *Self) !State {...@@ -1378,7 +1380,7 @@ fn saveState(self: *Self) !State {
1378 return state;1380 return state;
1379}1381}
13801382
1381fn restoreState(self: *Self, state: State, comptime opts: struct {1383fn restoreState(self: *Self, state: State, deaths: []u32, comptime opts: struct {
1382 emit_instructions: bool,1384 emit_instructions: bool,
1383 update_tracking: bool,1385 update_tracking: bool,
1384 resurrect: bool,1386 resurrect: bool,
...@@ -1389,8 +1391,16 @@ fn restoreState(self: *Self, state: State, comptime opts: struct {...@@ -1389,8 +1391,16 @@ fn restoreState(self: *Self, state: State, comptime opts: struct {
1389 self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len);1391 self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len);
1390 }1392 }
13911393
1392 if (opts.resurrect) for (self.inst_tracking.values()) |*tracking|1394 if (opts.resurrect) {
1393 tracking.resurrect(state.scope_generation);1395 var death_i: usize = 0;
1396 for (self.inst_tracking.values()[0..state.inst_tracking_len], 0..) |*tracking, tracking_i| {
1397 if (death_i < deaths.len and deaths[death_i] == tracking_i) {
1398 // oops, it was actually a death instead
1399 death_i += 1;
1400 tracking.die(self);
1401 } else tracking.resurrect(state.scope_generation);
1402 }
1403 } else assert(deaths.len == 0);
13941404
1395 for (0..state.registers.len) |index| {1405 for (0..state.registers.len) |index| {
1396 const current_maybe_inst = if (self.register_manager.free_registers.isSet(index))1406 const current_maybe_inst = if (self.register_manager.free_registers.isSet(index))
...@@ -3616,7 +3626,7 @@ fn reuseOperand(...@@ -3616,7 +3626,7 @@ fn reuseOperand(
36163626
3617 // Prevent the operand deaths processing code from deallocating it.3627 // Prevent the operand deaths processing code from deallocating it.
3618 self.liveness.clearOperandDeath(inst, op_index);3628 self.liveness.clearOperandDeath(inst, op_index);
3619 if (self.getResolvedInstValue(Air.refToIndex(operand).?)) |tracking| tracking.reuse(self);3629 self.getResolvedInstValue(Air.refToIndex(operand).?).reuse(self);
36203630
3621 return true;3631 return true;
3622}3632}
...@@ -6009,9 +6019,8 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {...@@ -6009,9 +6019,8 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6009 const extra = self.air.extraData(Air.Try, pl_op.payload);6019 const extra = self.air.extraData(Air.Try, pl_op.payload);
6010 const body = self.air.extra[extra.end..][0..extra.data.body_len];6020 const body = self.air.extra[extra.end..][0..extra.data.body_len];
6011 const err_union_ty = self.air.typeOf(pl_op.operand);6021 const err_union_ty = self.air.typeOf(pl_op.operand);
6012 const err_union = try self.resolveInst(pl_op.operand);6022 const result = try self.genTry(inst, pl_op.operand, body, err_union_ty, false);
6013 const result = try self.genTry(inst, err_union, body, err_union_ty, false);6023 return self.finishAir(inst, result, .{ .none, .none, .none });
6014 return self.finishAir(inst, result, .{ pl_op.operand, .none, .none });
6015}6024}
60166025
6017fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {6026fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
...@@ -6019,15 +6028,14 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6019,15 +6028,14 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
6019 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);6028 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
6020 const body = self.air.extra[extra.end..][0..extra.data.body_len];6029 const body = self.air.extra[extra.end..][0..extra.data.body_len];
6021 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();6030 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
6022 const err_union_ptr = try self.resolveInst(extra.data.ptr);6031 const result = try self.genTry(inst, extra.data.ptr, body, err_union_ty, true);
6023 const result = try self.genTry(inst, err_union_ptr, body, err_union_ty, true);6032 return self.finishAir(inst, result, .{ .none, .none, .none });
6024 return self.finishAir(inst, result, .{ extra.data.ptr, .none, .none });
6025}6033}
60266034
6027fn genTry(6035fn genTry(
6028 self: *Self,6036 self: *Self,
6029 inst: Air.Inst.Index,6037 inst: Air.Inst.Index,
6030 err_union: MCValue,6038 err_union: Air.Inst.Ref,
6031 body: []const Air.Inst.Index,6039 body: []const Air.Inst.Index,
6032 err_union_ty: Type,6040 err_union_ty: Type,
6033 operand_is_ptr: bool,6041 operand_is_ptr: bool,
...@@ -6035,14 +6043,37 @@ fn genTry(...@@ -6035,14 +6043,37 @@ fn genTry(
6035 if (operand_is_ptr) {6043 if (operand_is_ptr) {
6036 return self.fail("TODO genTry for pointers", .{});6044 return self.fail("TODO genTry for pointers", .{});
6037 }6045 }
6038 const is_err_mcv = try self.isErr(null, err_union_ty, err_union);6046 const liveness_cond_br = self.liveness.getCondBr(inst);
6047
6048 const err_union_mcv = try self.resolveInst(err_union);
6049 const is_err_mcv = try self.isErr(null, err_union_ty, err_union_mcv);
6050
6039 const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv);6051 const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv);
6052
6053 if (self.liveness.operandDies(inst, 0)) {
6054 if (Air.refToIndex(err_union)) |err_union_inst| self.processDeath(err_union_inst);
6055 }
6056
6057 self.scope_generation += 1;
6058 const state = try self.saveState();
6059
6060 for (liveness_cond_br.else_deaths) |operand| self.processDeath(operand);
6040 try self.genBody(body);6061 try self.genBody(body);
6062 try self.restoreState(state, &.{}, .{
6063 .emit_instructions = false,
6064 .update_tracking = true,
6065 .resurrect = true,
6066 .close_scope = true,
6067 });
6068
6041 try self.performReloc(reloc);6069 try self.performReloc(reloc);
6070
6071 for (liveness_cond_br.then_deaths) |operand| self.processDeath(operand);
6072
6042 const result = if (self.liveness.isUnused(inst))6073 const result = if (self.liveness.isUnused(inst))
6043 .unreach6074 .unreach
6044 else6075 else
6045 try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, err_union);6076 try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, err_union_mcv);
6046 return result;6077 return result;
6047}6078}
60486079
...@@ -6123,7 +6154,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6123,7 +6154,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
6123 const extra = self.air.extraData(Air.CondBr, pl_op.payload);6154 const extra = self.air.extraData(Air.CondBr, pl_op.payload);
6124 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];6155 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
6125 const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];6156 const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
6126 const liveness_condbr = self.liveness.getCondBr(inst);6157 const liveness_cond_br = self.liveness.getCondBr(inst);
61276158
6128 const reloc = try self.genCondBrMir(cond_ty, cond);6159 const reloc = try self.genCondBrMir(cond_ty, cond);
61296160
...@@ -6139,9 +6170,9 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6139,9 +6170,9 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
6139 self.scope_generation += 1;6170 self.scope_generation += 1;
6140 const inner_state = try self.saveState();6171 const inner_state = try self.saveState();
61416172
6142 for (liveness_condbr.then_deaths) |operand| self.processDeath(operand);6173 for (liveness_cond_br.then_deaths) |operand| self.processDeath(operand);
6143 try self.genBody(then_body);6174 try self.genBody(then_body);
6144 try self.restoreState(inner_state, .{6175 try self.restoreState(inner_state, &.{}, .{
6145 .emit_instructions = false,6176 .emit_instructions = false,
6146 .update_tracking = true,6177 .update_tracking = true,
6147 .resurrect = true,6178 .resurrect = true,
...@@ -6150,16 +6181,16 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6150,16 +6181,16 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
61506181
6151 try self.performReloc(reloc);6182 try self.performReloc(reloc);
61526183
6153 for (liveness_condbr.else_deaths) |operand| self.processDeath(operand);6184 for (liveness_cond_br.else_deaths) |operand| self.processDeath(operand);
6154 try self.genBody(else_body);6185 try self.genBody(else_body);
6155 try self.restoreState(inner_state, .{6186 try self.restoreState(inner_state, &.{}, .{
6156 .emit_instructions = false,6187 .emit_instructions = false,
6157 .update_tracking = true,6188 .update_tracking = true,
6158 .resurrect = true,6189 .resurrect = true,
6159 .close_scope = true,6190 .close_scope = true,
6160 });6191 });
6161 }6192 }
6162 try self.restoreState(outer_state, .{6193 try self.restoreState(outer_state, &.{}, .{
6163 .emit_instructions = false,6194 .emit_instructions = false,
6164 .update_tracking = false,6195 .update_tracking = false,
6165 .resurrect = false,6196 .resurrect = false,
...@@ -6473,7 +6504,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {...@@ -6473,7 +6504,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
6473 const state = try self.saveState();6504 const state = try self.saveState();
64746505
6475 try self.genBody(body);6506 try self.genBody(body);
6476 try self.restoreState(state, .{6507 try self.restoreState(state, &.{}, .{
6477 .emit_instructions = true,6508 .emit_instructions = true,
6478 .update_tracking = false,6509 .update_tracking = false,
6479 .resurrect = false,6510 .resurrect = false,
...@@ -6486,40 +6517,29 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {...@@ -6486,40 +6517,29 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
64866517
6487fn airBlock(self: *Self, inst: Air.Inst.Index) !void {6518fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
6488 // A block is a setup to be able to jump to the end.6519 // A block is a setup to be able to jump to the end.
6489 const ty = self.air.typeOfIndex(inst);6520 self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(.unreach));
6490
6491 // Here we use .{ .long = .unreach } to represent a null value so that the
6492 // first break instruction will choose a MCValue for the block result and
6493 // overwrite this field. Following break instructions will use that MCValue
6494 // to put their block results.
6495 self.inst_tracking.putAssumeCapacityNoClobber(inst, .{
6496 .long = .unreach,
6497 .short = if (ty.isNoReturn()) .unreach else .none,
6498 });
64996521
6500 self.scope_generation += 1;6522 self.scope_generation += 1;
6501 try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() });6523 try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() });
6502 defer {
6503 var block_data = self.blocks.fetchRemove(inst).?.value;
6504 block_data.deinit(self.gpa);
6505 }
65066524
6507 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6525 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6508 const extra = self.air.extraData(Air.Block, ty_pl.payload);6526 const extra = self.air.extraData(Air.Block, ty_pl.payload);
6509 const body = self.air.extra[extra.end..][0..extra.data.body_len];6527 const body = self.air.extra[extra.end..][0..extra.data.body_len];
6510 try self.genBody(body);6528 try self.genBody(body);
65116529
6512 const tracking = self.inst_tracking.getPtr(inst).?;6530 var block_data = self.blocks.fetchRemove(inst).?;
6513 const block_data = self.blocks.getPtr(inst).?;6531 defer block_data.value.deinit(self.gpa);
6514 for (block_data.deaths.items) |tracking_index| self.inst_tracking.values()[tracking_index].die(self);6532 if (block_data.value.relocs.items.len > 0) {
6515 if (tracking.short != .unreach) try self.restoreState(block_data.state, .{6533 try self.restoreState(block_data.value.state, block_data.value.deaths.items, .{
6516 .emit_instructions = false,6534 .emit_instructions = false,
6517 .update_tracking = true,6535 .update_tracking = true,
6518 .resurrect = false,6536 .resurrect = true,
6519 .close_scope = true,6537 .close_scope = true,
6520 });6538 });
6521 for (block_data.relocs.items) |reloc| try self.performReloc(reloc);6539 for (block_data.value.relocs.items) |reloc| try self.performReloc(reloc);
6540 }
65226541
6542 const tracking = self.inst_tracking.getPtr(inst).?;
6523 if (self.liveness.isUnused(inst)) tracking.die(self);6543 if (self.liveness.isUnused(inst)) tracking.die(self);
6524 self.getValue(tracking.short, inst);6544 self.getValue(tracking.short, inst);
6525 self.finishAirBookkeeping();6545 self.finishAirBookkeeping();
...@@ -6569,7 +6589,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6569,7 +6589,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
6569 for (liveness.deaths[case_i]) |operand| self.processDeath(operand);6589 for (liveness.deaths[case_i]) |operand| self.processDeath(operand);
65706590
6571 try self.genBody(case_body);6591 try self.genBody(case_body);
6572 try self.restoreState(inner_state, .{6592 try self.restoreState(inner_state, &.{}, .{
6573 .emit_instructions = false,6593 .emit_instructions = false,
6574 .update_tracking = true,6594 .update_tracking = true,
6575 .resurrect = true,6595 .resurrect = true,
...@@ -6586,7 +6606,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6586,7 +6606,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
6586 for (liveness.deaths[else_deaths]) |operand| self.processDeath(operand);6606 for (liveness.deaths[else_deaths]) |operand| self.processDeath(operand);
65876607
6588 try self.genBody(else_body);6608 try self.genBody(else_body);
6589 try self.restoreState(inner_state, .{6609 try self.restoreState(inner_state, &.{}, .{
6590 .emit_instructions = false,6610 .emit_instructions = false,
6591 .update_tracking = true,6611 .update_tracking = true,
6592 .resurrect = true,6612 .resurrect = true,
...@@ -6594,7 +6614,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -6594,7 +6614,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
6594 });6614 });
6595 }6615 }
6596 }6616 }
6597 try self.restoreState(outer_state, .{6617 try self.restoreState(outer_state, &.{}, .{
6598 .emit_instructions = false,6618 .emit_instructions = false,
6599 .update_tracking = false,6619 .update_tracking = false,
6600 .resurrect = false,6620 .resurrect = false,
...@@ -6620,58 +6640,64 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {...@@ -6620,58 +6640,64 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {
66206640
6621fn airBr(self: *Self, inst: Air.Inst.Index) !void {6641fn airBr(self: *Self, inst: Air.Inst.Index) !void {
6622 const br = self.air.instructions.items(.data)[inst].br;6642 const br = self.air.instructions.items(.data)[inst].br;
6643 const src_mcv = try self.resolveInst(br.operand);
6644
6623 const block_ty = self.air.typeOfIndex(br.block_inst);6645 const block_ty = self.air.typeOfIndex(br.block_inst);
6624 const block_unused =6646 const block_unused =
6625 !block_ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(br.block_inst);6647 !block_ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(br.block_inst);
6626
6627 // Process operand death early so that it is properly accounted for in the State below.
6628 const src_mcv = try self.resolveInst(br.operand);
6629 if (self.liveness.operandDies(inst, 0)) {
6630 if (Air.refToIndex(br.operand)) |op_inst| self.processDeath(op_inst);
6631 }
6632
6633 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;6648 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
6634 const block_data = self.blocks.getPtr(br.block_inst).?;6649 const block_data = self.blocks.getPtr(br.block_inst).?;
6635 if (block_tracking.long == .unreach) {
6636 // .unreach is used to mean that we are the first branch
66376650
6651 if (block_data.relocs.items.len == 0) {
6638 // We need to compute a list of deaths for later. This list needs to include6652 // We need to compute a list of deaths for later. This list needs to include
6639 // instructions that was born before, and has died since, the target block.6653 // instructions that was born before, and has died since, the target block.
6640 for (self.inst_tracking.values()[0..block_data.state.inst_tracking_len], 0..) |6654 for (
6641 *tracking,6655 self.inst_tracking.values()[0..block_data.state.inst_tracking_len],
6642 tracked_index,6656 0..,
6643 | switch (tracking.short) {6657 ) |*tracking, tracked_index| switch (tracking.short) {
6644 .dead => |die_generation| if (die_generation >= block_data.state.scope_generation)6658 .dead => |die_generation| if (die_generation >= block_data.state.scope_generation)
6645 try block_data.deaths.append(self.gpa, @intCast(u32, tracked_index)),6659 try block_data.deaths.append(self.gpa, @intCast(u32, tracked_index)),
6646 else => {},6660 else => {},
6647 };6661 };
66486662
6649 const result = result: {6663 block_tracking.* = InstTracking.init(result: {
6650 if (block_unused) break :result .none;6664 if (block_unused) break :result .none;
6651 if (self.reuseOperand(inst, br.operand, 0, src_mcv)) break :result src_mcv;6665 if (self.reuseOperand(inst, br.operand, 0, src_mcv)) {
6666 // Fix instruction tracking
6667 switch (src_mcv) {
6668 .register => |reg| if (RegisterManager.indexOfRegIntoTracked(reg)) |index| {
6669 self.register_manager.registers[index] = br.block_inst;
6670 },
6671 else => {},
6672 }
6673 break :result src_mcv;
6674 }
66526675
6653 const new_mcv = try self.allocRegOrMem(br.block_inst, true);6676 const new_mcv = try self.allocRegOrMem(br.block_inst, true);
6654 try self.setRegOrMem(block_ty, new_mcv, src_mcv);6677 try self.setRegOrMem(block_ty, new_mcv, src_mcv);
6655 break :result new_mcv;6678 break :result new_mcv;
6656 };
6657 block_tracking.* = InstTracking.init(result);
6658 try self.saveRetroactiveState(&block_data.state);
6659 self.freeValue(result);
6660 } else {
6661 if (!block_unused) try self.setRegOrMem(block_ty, block_tracking.short, src_mcv);
6662 try self.restoreState(block_data.state, .{
6663 .emit_instructions = true,
6664 .update_tracking = false,
6665 .resurrect = false,
6666 .close_scope = false,
6667 });6679 });
6680 } else if (!block_unused) try self.setRegOrMem(block_ty, block_tracking.short, src_mcv);
6681
6682 // Process operand death so that it is properly accounted for in the State below.
6683 if (self.liveness.operandDies(inst, 0)) {
6684 if (Air.refToIndex(br.operand)) |op_inst| self.processDeath(op_inst);
6668 }6685 }
66696686
6687 if (block_data.relocs.items.len == 0) {
6688 try self.saveRetroactiveState(&block_data.state);
6689 block_tracking.die(self);
6690 } else try self.restoreState(block_data.state, &.{}, .{
6691 .emit_instructions = true,
6692 .update_tracking = false,
6693 .resurrect = false,
6694 .close_scope = false,
6695 });
6696
6670 // Emit a jump with a relocation. It will be patched up after the block ends.6697 // Emit a jump with a relocation. It will be patched up after the block ends.
6671 try block_data.relocs.ensureUnusedCapacity(self.gpa, 1);
6672 // Leave the jump offset undefined6698 // Leave the jump offset undefined
6673 const jmp_reloc = try self.asmJmpReloc(undefined);6699 const jmp_reloc = try self.asmJmpReloc(undefined);
6674 block_data.relocs.appendAssumeCapacity(jmp_reloc);6700 try block_data.relocs.append(self.gpa, jmp_reloc);
66756701
6676 self.finishAirBookkeeping();6702 self.finishAirBookkeeping();
6677}6703}
...@@ -8636,7 +8662,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -8636,7 +8662,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
8636 else => self.inst_tracking.getPtr(inst).?,8662 else => self.inst_tracking.getPtr(inst).?,
8637 }.short;8663 }.short;
8638 switch (mcv) {8664 switch (mcv) {
8639 .none, .unreach => unreachable,8665 .none, .unreach, .dead => unreachable,
8640 else => return mcv,8666 else => return mcv,
8641 }8667 }
8642 }8668 }
...@@ -8644,15 +8670,14 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -8644,15 +8670,14 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
8644 return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref).? });8670 return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref).? });
8645}8671}
86468672
8647fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) ?*InstTracking {8673fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {
8648 const tracking = switch (self.air.instructions.items(.tag)[inst]) {8674 const tracking = switch (self.air.instructions.items(.tag)[inst]) {
8649 .constant => self.const_tracking.getPtr(inst) orelse return null,8675 .constant => &self.const_tracking,
8650 .const_ty => unreachable,8676 .const_ty => unreachable,
8651 else => self.inst_tracking.getPtr(inst).?,8677 else => &self.inst_tracking,
8652 };8678 }.getPtr(inst).?;
8653 return switch (tracking.short) {8679 return switch (tracking.short) {
8654 .unreach => unreachable,8680 .none, .unreach, .dead => unreachable,
8655 .dead => null,
8656 else => tracking,8681 else => tracking,
8657 };8682 };
8658}8683}