| ... | @@ -4736,9 +4736,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4736,9 +4736,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4736 | // that we can use all the code emitting abstractions. This is why at the bottom we | 4736 | // that we can use all the code emitting abstractions. This is why at the bottom we |
| 4737 | // assert that parent_branch.free_registers equals the saved_then_branch.free_registers | 4737 | // assert that parent_branch.free_registers equals the saved_then_branch.free_registers |
| 4738 | // rather than assigning it. | 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 | log.debug("Upper branches:", .{}); | 4739 | log.debug("Upper branches:", .{}); |
| 4743 | for (self.branch_stack.items) |bs| { | 4740 | for (self.branch_stack.items) |bs| { |
| 4744 | log.debug("{}", .{bs.fmtDebug()}); | 4741 | log.debug("{}", .{bs.fmtDebug()}); |
| ... | @@ -4747,67 +4744,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4747,67 +4744,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4747 | log.debug("Then branch: {}", .{then_branch.fmtDebug()}); | 4744 | log.debug("Then branch: {}", .{then_branch.fmtDebug()}); |
| 4748 | log.debug("Else branch: {}", .{else_branch.fmtDebug()}); | 4745 | log.debug("Else branch: {}", .{else_branch.fmtDebug()}); |
| 4749 | | 4746 | |
| 4750 | const else_slice = else_branch.inst_table.entries.slice(); | 4747 | const parent_branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 4751 | const else_keys = else_slice.items(.key); | 4748 | try self.canonicaliseBranches(parent_branch, &then_branch, &else_branch); |
| 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 | } | | |
| 4811 | | 4749 | |
| 4812 | // We already took care of pl_op.operand earlier, so we're going | 4750 | // We already took care of pl_op.operand earlier, so we're going |
| 4813 | // to pass .none here | 4751 | // to pass .none here |