Liveness: control flow analysis

This is a partial rewrite of Liveness, so has some other notable changes:
- A proper multi-pass system to prevent code duplication
- Better logging
- Minor bugfixes
This commit is contained in:
mlugg 2023-04-09 01:32:53 +01:00
parent fac120bc3a
commit 8258530c39
No known key found for this signature in database
GPG Key ID: 58978E823BDE3EF9
8 changed files with 987 additions and 939 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5000,17 +5000,11 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end..][0..loop.data.body_len];
const liveness_loop = self.liveness.getLoop(inst);
const start_index = @intCast(u32, self.mir_instructions.len);
try self.genBody(body);
try self.jump(start_index);
try self.ensureProcessDeathCapacity(liveness_loop.deaths.len);
for (liveness_loop.deaths) |operand| {
self.processDeath(operand);
}
return self.finishAirBookkeeping();
}

View File

@ -4923,17 +4923,11 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end..][0..loop.data.body_len];
const liveness_loop = self.liveness.getLoop(inst);
const start_index = @intCast(Mir.Inst.Index, self.mir_instructions.len);
try self.genBody(body);
try self.jump(start_index);
try self.ensureProcessDeathCapacity(liveness_loop.deaths.len);
for (liveness_loop.deaths) |operand| {
self.processDeath(operand);
}
return self.finishAirBookkeeping();
}

View File

@ -1750,17 +1750,11 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end .. loop.end + loop.data.body_len];
const liveness_loop = self.liveness.getLoop(inst);
const start = @intCast(u32, self.mir_instructions.len);
try self.genBody(body);
try self.jump(start);
try self.ensureProcessDeathCapacity(liveness_loop.deaths.len);
for (liveness_loop.deaths) |operand| {
self.processDeath(operand);
}
return self.finishAirBookkeeping();
}

View File

@ -3183,7 +3183,6 @@ fn airLoop(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const loop = func.air.extraData(Air.Block, ty_pl.payload);
const body = func.air.extra[loop.end..][0..loop.data.body_len];
const liveness_loop = func.liveness.getLoop(inst);
// result type of loop is always 'noreturn', meaning we can always
// emit the wasm type 'block_empty'.
@ -3194,11 +3193,6 @@ fn airLoop(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
try func.addLabel(.br, 0);
try func.endBlock();
try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_loop.deaths.len));
for (liveness_loop.deaths) |death| {
func.processDeath(Air.indexToRef(death));
}
func.finishAir(inst, .none, &.{});
}

View File

@ -6439,7 +6439,6 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end..][0..loop.data.body_len];
const jmp_target = @intCast(u32, self.mir_instructions.len);
const liveness_loop = self.liveness.getLoop(inst);
{
try self.branch_stack.append(.{});
@ -6464,11 +6463,6 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
_ = try self.asmJmpReloc(jmp_target);
try self.ensureProcessDeathCapacity(liveness_loop.deaths.len);
for (liveness_loop.deaths) |operand| {
self.processDeath(operand);
}
return self.finishAirBookkeeping();
}

View File

@ -4637,17 +4637,12 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const loop = f.air.extraData(Air.Block, ty_pl.payload);
const body = f.air.extra[loop.end..][0..loop.data.body_len];
const liveness_loop = f.liveness.getLoop(inst);
const writer = f.object.writer();
try writer.writeAll("for (;;) ");
try genBody(f, body);
try writer.writeByte('\n');
for (liveness_loop.deaths) |operand| {
try die(f, inst, Air.indexToRef(operand));
}
return .none;
}

View File

@ -405,7 +405,6 @@ const Writer = struct {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const extra = w.air.extraData(Air.Block, ty_pl.payload);
const body = w.air.extra[extra.end..][0..extra.data.body_len];
const liveness_loop = w.liveness.getLoop(inst);
try w.writeType(s, w.air.getRefType(ty_pl.ty));
if (w.skip_body) return s.writeAll(", ...");
@ -413,14 +412,6 @@ const Writer = struct {
const old_indent = w.indent;
w.indent += 2;
try w.writeBody(s, body);
if (liveness_loop.deaths.len != 0) {
try s.writeByteNTimes(' ', w.indent);
for (liveness_loop.deaths, 0..) |operand, i| {
if (i != 0) try s.writeAll(" ");
try s.print("%{d}!", .{operand});
}
try s.writeAll("\n");
}
w.indent = old_indent;
try s.writeByteNTimes(' ', w.indent);
try s.writeAll("}");