| ... | ... | @@ -4736,9 +4736,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4736 | 4736 | // that we can use all the code emitting abstractions. This is why at the bottom we |
| 4737 | 4737 | // assert that parent_branch.free_registers equals the saved_then_branch.free_registers |
| 4738 | 4738 | // rather than assigning it. |
| 4739 | | const parent_branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 4740 | | try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, else_branch.inst_table.count()); |
| 4741 | | |
| 4742 | 4739 | log.debug("Upper branches:", .{}); |
| 4743 | 4740 | for (self.branch_stack.items) |bs| { |
| 4744 | 4741 | log.debug("{}", .{bs.fmtDebug()}); |
| ... | ... | @@ -4747,67 +4744,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4747 | 4744 | log.debug("Then branch: {}", .{then_branch.fmtDebug()}); |
| 4748 | 4745 | log.debug("Else branch: {}", .{else_branch.fmtDebug()}); |
| 4749 | 4746 | |
| 4750 | | const else_slice = else_branch.inst_table.entries.slice(); |
| 4751 | | const else_keys = else_slice.items(.key); |
| 4752 | | const else_values = else_slice.items(.value); |
| 4753 | | for (else_keys) |else_key, else_idx| { |
| 4754 | | const else_value = else_values[else_idx]; |
| 4755 | | const canon_mcv = if (then_branch.inst_table.fetchSwapRemove(else_key)) |then_entry| blk: { |
| 4756 | | // The instruction's MCValue is overridden in both branches. |
| 4757 | | parent_branch.inst_table.putAssumeCapacity(else_key, then_entry.value); |
| 4758 | | if (else_value == .dead) { |
| 4759 | | assert(then_entry.value == .dead); |
| 4760 | | continue; |
| 4761 | | } |
| 4762 | | break :blk then_entry.value; |
| 4763 | | } else blk: { |
| 4764 | | if (else_value == .dead) |
| 4765 | | continue; |
| 4766 | | // The instruction is only overridden in the else branch. |
| 4767 | | var i: usize = self.branch_stack.items.len - 1; |
| 4768 | | while (true) { |
| 4769 | | i -= 1; // If this overflows, the question is: why wasn't the instruction marked dead? |
| 4770 | | if (self.branch_stack.items[i].inst_table.get(else_key)) |mcv| { |
| 4771 | | assert(mcv != .dead); |
| 4772 | | break :blk mcv; |
| 4773 | | } |
| 4774 | | } |
| 4775 | | }; |
| 4776 | | log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv }); |
| 4777 | | // TODO make sure the destination stack offset / register does not already have something |
| 4778 | | // going on there. |
| 4779 | | try self.setRegOrMem(self.air.typeOfIndex(else_key), canon_mcv, else_value); |
| 4780 | | // TODO track the new register / stack allocation |
| 4781 | | } |
| 4782 | | try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, then_branch.inst_table.count()); |
| 4783 | | const then_slice = then_branch.inst_table.entries.slice(); |
| 4784 | | const then_keys = then_slice.items(.key); |
| 4785 | | const then_values = then_slice.items(.value); |
| 4786 | | for (then_keys) |then_key, then_idx| { |
| 4787 | | const then_value = then_values[then_idx]; |
| 4788 | | // We already deleted the items from this table that matched the else_branch. |
| 4789 | | // So these are all instructions that are only overridden in the then branch. |
| 4790 | | parent_branch.inst_table.putAssumeCapacity(then_key, then_value); |
| 4791 | | log.debug("then_value = {}", .{then_value}); |
| 4792 | | if (then_value == .dead) |
| 4793 | | continue; |
| 4794 | | const parent_mcv = blk: { |
| 4795 | | log.debug("{d}", .{self.branch_stack.items.len}); |
| 4796 | | var i: usize = self.branch_stack.items.len - 1; |
| 4797 | | while (true) { |
| 4798 | | i -= 1; |
| 4799 | | if (self.branch_stack.items[i].inst_table.get(then_key)) |mcv| { |
| 4800 | | assert(mcv != .dead); |
| 4801 | | break :blk mcv; |
| 4802 | | } |
| 4803 | | } |
| 4804 | | }; |
| 4805 | | log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value }); |
| 4806 | | // TODO make sure the destination stack offset / register does not already have something |
| 4807 | | // going on there. |
| 4808 | | try self.setRegOrMem(self.air.typeOfIndex(then_key), parent_mcv, then_value); |
| 4809 | | // TODO track the new register / stack allocation |
| 4810 | | } |
| 4747 | const parent_branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 4748 | try self.canonicaliseBranches(parent_branch, &then_branch, &else_branch); |
| 4811 | 4749 | |
| 4812 | 4750 | // We already took care of pl_op.operand earlier, so we're going |
| 4813 | 4751 | // to pass .none here |