authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-19 18:58:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-20 12:19:17-07:00
loga97e5e119afb80e0d6d047682b8301bab9423078
tree9faa8d41b8669302772471e622bb247024289b94
parent495e60d6415d6de63c9ef0f604a959d969118116

stage2: switch: fix Sema bugs and implement AIR printing


3 files changed, 40 insertions(+), 26 deletions(-)

src/Liveness.zig+5-5
...@@ -442,9 +442,9 @@ fn analyzeInst(...@@ -442,9 +442,9 @@ fn analyzeInst(
442 return trackOperands(a, new_set, inst, main_tomb, .{ condition, .none, .none });442 return trackOperands(a, new_set, inst, main_tomb, .{ condition, .none, .none });
443 },443 },
444 .switch_br => {444 .switch_br => {
445 const inst_data = inst_datas[inst].pl_op;445 const pl_op = inst_datas[inst].pl_op;
446 const condition = inst_data.operand;446 const condition = pl_op.operand;
447 const switch_br = a.air.extraData(Air.SwitchBr, inst_data.payload);447 const switch_br = a.air.extraData(Air.SwitchBr, pl_op.payload);
448448
449 const Table = std.AutoHashMapUnmanaged(Air.Inst.Index, void);449 const Table = std.AutoHashMapUnmanaged(Air.Inst.Index, void);
450 const case_tables = try gpa.alloc(Table, switch_br.data.cases_len + 1); // +1 for else450 const case_tables = try gpa.alloc(Table, switch_br.data.cases_len + 1); // +1 for else
...@@ -456,8 +456,8 @@ fn analyzeInst(...@@ -456,8 +456,8 @@ fn analyzeInst(
456 var air_extra_index: usize = switch_br.end;456 var air_extra_index: usize = switch_br.end;
457 for (case_tables[0..switch_br.data.cases_len]) |*case_table| {457 for (case_tables[0..switch_br.data.cases_len]) |*case_table| {
458 const case = a.air.extraData(Air.SwitchBr.Case, air_extra_index);458 const case = a.air.extraData(Air.SwitchBr.Case, air_extra_index);
459 const case_body = a.air.extra[case.end..][0..case.data.body_len];459 const case_body = a.air.extra[case.end + case.data.items_len ..][0..case.data.body_len];
460 air_extra_index = case.end + case_body.len;460 air_extra_index = case.end + case.data.items_len + case_body.len;
461 try analyzeWithContext(a, case_table, case_body);461 try analyzeWithContext(a, case_table, case_body);
462462
463 // Reset the table back to its state from before the case.463 // Reset the table back to its state from before the case.
src/Sema.zig+6-3
...@@ -4213,6 +4213,7 @@ fn analyzeSwitch(...@@ -4213,6 +4213,7 @@ fn analyzeSwitch(
4213 var prev_then_body: []const Air.Inst.Index = &.{};4213 var prev_then_body: []const Air.Inst.Index = &.{};
4214 defer gpa.free(prev_then_body);4214 defer gpa.free(prev_then_body);
42154215
4216 var cases_len = scalar_cases_len;
4216 var multi_i: usize = 0;4217 var multi_i: usize = 0;
4217 while (multi_i < multi_cases_len) : (multi_i += 1) {4218 while (multi_i < multi_cases_len) : (multi_i += 1) {
4218 const items_len = sema.code.extra[extra_index];4219 const items_len = sema.code.extra[extra_index];
...@@ -4232,6 +4233,8 @@ fn analyzeSwitch(...@@ -4232,6 +4233,8 @@ fn analyzeSwitch(
4232 // else prong. Otherwise, we can take advantage of multiple items4233 // else prong. Otherwise, we can take advantage of multiple items
4233 // mapping to the same body.4234 // mapping to the same body.
4234 if (ranges_len == 0) {4235 if (ranges_len == 0) {
4236 cases_len += 1;
4237
4235 const body = sema.code.extra[extra_index..][0..body_len];4238 const body = sema.code.extra[extra_index..][0..body_len];
4236 extra_index += body_len;4239 extra_index += body_len;
4237 _ = try sema.analyzeBody(&case_block, body);4240 _ = try sema.analyzeBody(&case_block, body);
...@@ -4239,7 +4242,7 @@ fn analyzeSwitch(...@@ -4239,7 +4242,7 @@ fn analyzeSwitch(
4239 try cases_extra.ensureUnusedCapacity(gpa, 2 + items.len +4242 try cases_extra.ensureUnusedCapacity(gpa, 2 + items.len +
4240 case_block.instructions.items.len);4243 case_block.instructions.items.len);
42414244
4242 cases_extra.appendAssumeCapacity(1); // items_len4245 cases_extra.appendAssumeCapacity(@intCast(u32, items.len));
4243 cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len));4246 cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len));
42444247
4245 for (items) |item_ref| {4248 for (items) |item_ref| {
...@@ -4352,12 +4355,12 @@ fn analyzeSwitch(...@@ -4352,12 +4355,12 @@ fn analyzeSwitch(
4352 }4355 }
43534356
4354 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr).Struct.fields.len +4357 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr).Struct.fields.len +
4355 cases_extra.items.len);4358 cases_extra.items.len + final_else_body.len);
43564359
4357 _ = try child_block.addInst(.{ .tag = .switch_br, .data = .{ .pl_op = .{4360 _ = try child_block.addInst(.{ .tag = .switch_br, .data = .{ .pl_op = .{
4358 .operand = operand,4361 .operand = operand,
4359 .payload = sema.addExtraAssumeCapacity(Air.SwitchBr{4362 .payload = sema.addExtraAssumeCapacity(Air.SwitchBr{
4360 .cases_len = @intCast(u32, scalar_cases_len + multi_cases_len),4363 .cases_len = @intCast(u32, cases_len),
4361 .else_body_len = @intCast(u32, final_else_body.len),4364 .else_body_len = @intCast(u32, final_else_body.len),
4362 }),4365 }),
4363 } } });4366 } } });
src/print_air.zig+29-18
...@@ -300,33 +300,44 @@ const Writer = struct {...@@ -300,33 +300,44 @@ const Writer = struct {
300300
301 fn writeSwitchBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {301 fn writeSwitchBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
302 const pl_op = w.air.instructions.items(.data)[inst].pl_op;302 const pl_op = w.air.instructions.items(.data)[inst].pl_op;
303 const extra = w.air.extraData(Air.SwitchBr, pl_op.payload);303 const switch_br = w.air.extraData(Air.SwitchBr, pl_op.payload);
304 const cases = w.air.extra[extra.end..][0..extra.data.cases_len];304 var extra_index: usize = switch_br.end;
305 const else_body = w.air.extra[extra.end + cases.len ..][0..extra.data.else_body_len];305 var case_i: u32 = 0;
306306
307 try w.writeInstRef(s, pl_op.operand);307 try w.writeInstRef(s, pl_op.operand);
308 try s.writeAll(", {\n");
309
310 const old_indent = w.indent;308 const old_indent = w.indent;
311 if (else_body.len != 0) {309 w.indent += 2;
312 w.indent += 2;
313 try w.writeBody(s, else_body);
314 try s.writeByteNTimes(' ', old_indent);
315 try s.writeAll("}, {\n");
316 w.indent = old_indent;
317 }
318310
319 for (cases) |case_index| {311 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
320 const case = w.air.extraData(Air.SwitchBr.Case, case_index);312 const case = w.air.extraData(Air.SwitchBr.Case, extra_index);
321 const case_body = w.air.extra[case.end..][0..case.data.body_len];313 const items = @bitCast([]const Air.Inst.Ref, w.air.extra[case.end..][0..case.data.items_len]);
314 const case_body = w.air.extra[case.end + items.len ..][0..case.data.body_len];
315 extra_index = case.end + case.data.items_len + case_body.len;
322316
317 try s.writeAll(", [");
318 for (items) |item, item_i| {
319 if (item_i != 0) try s.writeAll(", ");
320 try w.writeInstRef(s, item);
321 }
322 try s.writeAll("] => {\n");
323 w.indent += 2;323 w.indent += 2;
324 try w.writeBody(s, case_body);324 try w.writeBody(s, case_body);
325 try s.writeByteNTimes(' ', old_indent);325 w.indent -= 2;
326 try s.writeAll("}, {\n");326 try s.writeByteNTimes(' ', w.indent);
327 w.indent = old_indent;327 try s.writeAll("}");
328 }
329
330 const else_body = w.air.extra[extra_index..][0..switch_br.data.else_body_len];
331 if (else_body.len != 0) {
332 try s.writeAll(", else => {\n");
333 w.indent += 2;
334 try w.writeBody(s, else_body);
335 w.indent -= 2;
336 try s.writeByteNTimes(' ', w.indent);
337 try s.writeAll("}");
328 }338 }
329339
340 try s.writeAll("\n");
330 try s.writeByteNTimes(' ', old_indent);341 try s.writeByteNTimes(' ', old_indent);
331 try s.writeAll("}");342 try s.writeAll("}");
332 }343 }