| author | |
| committer | |
| log | a97e5e119afb80e0d6d047682b8301bab9423078 |
| tree | 9faa8d41b8669302772471e622bb247024289b94 |
| parent | 495e60d6415d6de63c9ef0f604a959d969118116 |
3 files changed, 40 insertions(+), 26 deletions(-)
src/Liveness.zig+5-5| ... | ... | @@ -442,9 +442,9 @@ fn analyzeInst( |
| 442 | 442 | return trackOperands(a, new_set, inst, main_tomb, .{ condition, .none, .none }); |
| 443 | 443 | }, |
| 444 | 444 | .switch_br => { |
| 445 | const inst_data = inst_datas[inst].pl_op; | |
| 446 | const condition = inst_data.operand; | |
| 447 | const switch_br = a.air.extraData(Air.SwitchBr, inst_data.payload); | |
| 445 | const pl_op = inst_datas[inst].pl_op; | |
| 446 | const condition = pl_op.operand; | |
| 447 | const switch_br = a.air.extraData(Air.SwitchBr, pl_op.payload); | |
| 448 | 448 | |
| 449 | 449 | const Table = std.AutoHashMapUnmanaged(Air.Inst.Index, void); |
| 450 | 450 | const case_tables = try gpa.alloc(Table, switch_br.data.cases_len + 1); // +1 for else |
| ... | ... | @@ -456,8 +456,8 @@ fn analyzeInst( |
| 456 | 456 | var air_extra_index: usize = switch_br.end; |
| 457 | 457 | for (case_tables[0..switch_br.data.cases_len]) |*case_table| { |
| 458 | 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]; | |
| 460 | air_extra_index = case.end + case_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.data.items_len + case_body.len; | |
| 461 | 461 | try analyzeWithContext(a, case_table, case_body); |
| 462 | 462 | |
| 463 | 463 | // Reset the table back to its state from before the case. |
src/Sema.zig+6-3| ... | ... | @@ -4213,6 +4213,7 @@ fn analyzeSwitch( |
| 4213 | 4213 | var prev_then_body: []const Air.Inst.Index = &.{}; |
| 4214 | 4214 | defer gpa.free(prev_then_body); |
| 4215 | 4215 | |
| 4216 | var cases_len = scalar_cases_len; | |
| 4216 | 4217 | var multi_i: usize = 0; |
| 4217 | 4218 | while (multi_i < multi_cases_len) : (multi_i += 1) { |
| 4218 | 4219 | const items_len = sema.code.extra[extra_index]; |
| ... | ... | @@ -4232,6 +4233,8 @@ fn analyzeSwitch( |
| 4232 | 4233 | // else prong. Otherwise, we can take advantage of multiple items |
| 4233 | 4234 | // mapping to the same body. |
| 4234 | 4235 | if (ranges_len == 0) { |
| 4236 | cases_len += 1; | |
| 4237 | ||
| 4235 | 4238 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 4236 | 4239 | extra_index += body_len; |
| 4237 | 4240 | _ = try sema.analyzeBody(&case_block, body); |
| ... | ... | @@ -4239,7 +4242,7 @@ fn analyzeSwitch( |
| 4239 | 4242 | try cases_extra.ensureUnusedCapacity(gpa, 2 + items.len + |
| 4240 | 4243 | case_block.instructions.items.len); |
| 4241 | 4244 | |
| 4242 | cases_extra.appendAssumeCapacity(1); // items_len | |
| 4245 | cases_extra.appendAssumeCapacity(@intCast(u32, items.len)); | |
| 4243 | 4246 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 4244 | 4247 | |
| 4245 | 4248 | for (items) |item_ref| { |
| ... | ... | @@ -4352,12 +4355,12 @@ fn analyzeSwitch( |
| 4352 | 4355 | } |
| 4353 | 4356 | |
| 4354 | 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); | |
| 4356 | 4359 | |
| 4357 | 4360 | _ = try child_block.addInst(.{ .tag = .switch_br, .data = .{ .pl_op = .{ |
| 4358 | 4361 | .operand = operand, |
| 4359 | 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 | 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 | 300 | |
| 301 | 301 | fn writeSwitchBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 302 | 302 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; |
| 303 | const extra = w.air.extraData(Air.SwitchBr, pl_op.payload); | |
| 304 | const cases = w.air.extra[extra.end..][0..extra.data.cases_len]; | |
| 305 | const else_body = w.air.extra[extra.end + cases.len ..][0..extra.data.else_body_len]; | |
| 303 | const switch_br = w.air.extraData(Air.SwitchBr, pl_op.payload); | |
| 304 | var extra_index: usize = switch_br.end; | |
| 305 | var case_i: u32 = 0; | |
| 306 | 306 | |
| 307 | 307 | try w.writeInstRef(s, pl_op.operand); |
| 308 | try s.writeAll(", {\n"); | |
| 309 | ||
| 310 | 308 | const old_indent = w.indent; |
| 311 | if (else_body.len != 0) { | |
| 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 | } | |
| 309 | w.indent += 2; | |
| 318 | 310 | |
| 319 | for (cases) |case_index| { | |
| 320 | const case = w.air.extraData(Air.SwitchBr.Case, case_index); | |
| 321 | const case_body = w.air.extra[case.end..][0..case.data.body_len]; | |
| 311 | while (case_i < switch_br.data.cases_len) : (case_i += 1) { | |
| 312 | const case = w.air.extraData(Air.SwitchBr.Case, extra_index); | |
| 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; | |
| 322 | 316 | |
| 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 | 323 | w.indent += 2; |
| 324 | 324 | try w.writeBody(s, case_body); |
| 325 | try s.writeByteNTimes(' ', old_indent); | |
| 326 | try s.writeAll("}, {\n"); | |
| 327 | w.indent = old_indent; | |
| 325 | w.indent -= 2; | |
| 326 | try s.writeByteNTimes(' ', w.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 | } |
| 329 | 339 | |
| 340 | try s.writeAll("\n"); | |
| 330 | 341 | try s.writeByteNTimes(' ', old_indent); |
| 331 | 342 | try s.writeAll("}"); |
| 332 | 343 | } |