authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-07 21:54:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-07 21:54:26-07:00
log73bf53069d4e719cb74be87bd41b0a2ac65b7dfe
treea93c11b8c028e27e8ab501987dc35ea897be545f
parent6ec24a6502833e5bce582294ef6691173095ead7

ZIR: implement iteration over switch instructions

for changelist detection

1 files changed, 119 insertions(+), 15 deletions(-)

src/Zir.zig+119-15
......@@ -4536,21 +4536,19 @@ fn findDeclsInner(
45364536 try zir.findDeclsBody(list, then_body);
45374537 try zir.findDeclsBody(list, else_body);
45384538 },
4539 .switch_block,
4540 .switch_block_else,
4541 .switch_block_under,
4542 .switch_block_ref,
4543 .switch_block_ref_else,
4544 .switch_block_ref_under,
4545 => @panic("TODO iterate switch block"),
4546
4547 .switch_block_multi,
4548 .switch_block_else_multi,
4549 .switch_block_under_multi,
4550 .switch_block_ref_multi,
4551 .switch_block_ref_else_multi,
4552 .switch_block_ref_under_multi,
4553 => @panic("TODO iterate switch block multi"),
4539 .switch_block => return findDeclsSwitch(zir, list, inst, .none),
4540 .switch_block_else => return findDeclsSwitch(zir, list, inst, .@"else"),
4541 .switch_block_under => return findDeclsSwitch(zir, list, inst, .under),
4542 .switch_block_ref => return findDeclsSwitch(zir, list, inst, .none),
4543 .switch_block_ref_else => return findDeclsSwitch(zir, list, inst, .@"else"),
4544 .switch_block_ref_under => return findDeclsSwitch(zir, list, inst, .under),
4545
4546 .switch_block_multi => return findDeclsSwitchMulti(zir, list, inst, .none),
4547 .switch_block_else_multi => return findDeclsSwitchMulti(zir, list, inst, .@"else"),
4548 .switch_block_under_multi => return findDeclsSwitchMulti(zir, list, inst, .under),
4549 .switch_block_ref_multi => return findDeclsSwitchMulti(zir, list, inst, .none),
4550 .switch_block_ref_else_multi => return findDeclsSwitchMulti(zir, list, inst, .@"else"),
4551 .switch_block_ref_under_multi => return findDeclsSwitchMulti(zir, list, inst, .under),
45544552
45554553 .suspend_block => @panic("TODO iterate suspend block"),
45564554
......@@ -4558,6 +4556,112 @@ fn findDeclsInner(
45584556 }
45594557}
45604558
4559fn findDeclsSwitch(
4560 zir: Zir,
4561 list: *std.ArrayList(Zir.Inst.Index),
4562 inst: Zir.Inst.Index,
4563 special_prong: SpecialProng,
4564) Allocator.Error!void {
4565 const inst_data = zir.instructions.items(.data)[inst].pl_node;
4566 const extra = zir.extraData(Inst.SwitchBlock, inst_data.payload_index);
4567 const special: struct {
4568 body: []const Inst.Index,
4569 end: usize,
4570 } = switch (special_prong) {
4571 .none => .{ .body = &.{}, .end = extra.end },
4572 .under, .@"else" => blk: {
4573 const body_len = zir.extra[extra.end];
4574 const extra_body_start = extra.end + 1;
4575 break :blk .{
4576 .body = zir.extra[extra_body_start..][0..body_len],
4577 .end = extra_body_start + body_len,
4578 };
4579 },
4580 };
4581
4582 try zir.findDeclsBody(list, special.body);
4583
4584 var extra_index: usize = special.end;
4585 var scalar_i: usize = 0;
4586 while (scalar_i < extra.data.cases_len) : (scalar_i += 1) {
4587 const item_ref = @intToEnum(Inst.Ref, zir.extra[extra_index]);
4588 extra_index += 1;
4589 const body_len = zir.extra[extra_index];
4590 extra_index += 1;
4591 const body = zir.extra[extra_index..][0..body_len];
4592 extra_index += body_len;
4593
4594 try zir.findDeclsBody(list, body);
4595 }
4596}
4597
4598fn findDeclsSwitchMulti(
4599 zir: Zir,
4600 list: *std.ArrayList(Zir.Inst.Index),
4601 inst: Zir.Inst.Index,
4602 special_prong: SpecialProng,
4603) Allocator.Error!void {
4604 const inst_data = zir.instructions.items(.data)[inst].pl_node;
4605 const extra = zir.extraData(Inst.SwitchBlockMulti, inst_data.payload_index);
4606 const special: struct {
4607 body: []const Inst.Index,
4608 end: usize,
4609 } = switch (special_prong) {
4610 .none => .{ .body = &.{}, .end = extra.end },
4611 .under, .@"else" => blk: {
4612 const body_len = zir.extra[extra.end];
4613 const extra_body_start = extra.end + 1;
4614 break :blk .{
4615 .body = zir.extra[extra_body_start..][0..body_len],
4616 .end = extra_body_start + body_len,
4617 };
4618 },
4619 };
4620
4621 try zir.findDeclsBody(list, special.body);
4622
4623 var extra_index: usize = special.end;
4624 {
4625 var scalar_i: usize = 0;
4626 while (scalar_i < extra.data.scalar_cases_len) : (scalar_i += 1) {
4627 const item_ref = @intToEnum(Inst.Ref, zir.extra[extra_index]);
4628 extra_index += 1;
4629 const body_len = zir.extra[extra_index];
4630 extra_index += 1;
4631 const body = zir.extra[extra_index..][0..body_len];
4632 extra_index += body_len;
4633
4634 try zir.findDeclsBody(list, body);
4635 }
4636 }
4637 {
4638 var multi_i: usize = 0;
4639 while (multi_i < extra.data.multi_cases_len) : (multi_i += 1) {
4640 const items_len = zir.extra[extra_index];
4641 extra_index += 1;
4642 const ranges_len = zir.extra[extra_index];
4643 extra_index += 1;
4644 const body_len = zir.extra[extra_index];
4645 extra_index += 1;
4646 const items = zir.refSlice(extra_index, items_len);
4647 extra_index += items_len;
4648
4649 var range_i: usize = 0;
4650 while (range_i < ranges_len) : (range_i += 1) {
4651 const item_first = @intToEnum(Inst.Ref, zir.extra[extra_index]);
4652 extra_index += 1;
4653 const item_last = @intToEnum(Inst.Ref, zir.extra[extra_index]);
4654 extra_index += 1;
4655 }
4656
4657 const body = zir.extra[extra_index..][0..body_len];
4658 extra_index += body_len;
4659
4660 try zir.findDeclsBody(list, body);
4661 }
4662 }
4663}
4664
45614665fn findDeclsBody(
45624666 zir: Zir,
45634667 list: *std.ArrayList(Zir.Inst.Index),