| ... | @@ -11509,7 +11509,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11509,7 +11509,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11509 | while (try it.next()) |cur| { | 11509 | while (try it.next()) |cur| { |
| 11510 | cases_len += 1; | 11510 | cases_len += 1; |
| 11511 | | 11511 | |
| 11512 | const item_ref = try sema.addConstant(operand_ty, cur); | 11512 | const item_ref = try sema.addConstant(operand_ty, cur.toValue()); |
| 11513 | case_block.inline_case_capture = item_ref; | 11513 | case_block.inline_case_capture = item_ref; |
| 11514 | | 11514 | |
| 11515 | case_block.instructions.shrinkRetainingCapacity(0); | 11515 | case_block.instructions.shrinkRetainingCapacity(0); |
| ... | @@ -11647,47 +11647,70 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11647,47 +11647,70 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11647 | } | 11647 | } |
| 11648 | | 11648 | |
| 11649 | const RangeSetUnhandledIterator = struct { | 11649 | const RangeSetUnhandledIterator = struct { |
| 11650 | sema: *Sema, | 11650 | mod: *Module, |
| 11651 | ty: Type, | 11651 | cur: ?InternPool.Index, |
| 11652 | cur: Value, | 11652 | max: InternPool.Index, |
| 11653 | max: Value, | 11653 | range_i: usize, |
| 11654 | ranges: []const RangeSet.Range, | 11654 | ranges: []const RangeSet.Range, |
| 11655 | range_i: usize = 0, | 11655 | limbs: []math.big.Limb, |
| 11656 | first: bool = true, | 11656 | |
| | 11657 | const preallocated_limbs = math.big.int.calcTwosCompLimbCount(128); |
| 11657 | | 11658 | |
| 11658 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { | 11659 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { |
| 11659 | const mod = sema.mod; | 11660 | const mod = sema.mod; |
| 11660 | const min = try ty.minInt(mod, ty); | 11661 | const int_type = mod.intern_pool.indexToKey(ty.toIntern()).int_type; |
| 11661 | const max = try ty.maxInt(mod, ty); | 11662 | const needed_limbs = math.big.int.calcTwosCompLimbCount(int_type.bits); |
| 11662 | | 11663 | return .{ |
| 11663 | return RangeSetUnhandledIterator{ | 11664 | .mod = mod, |
| 11664 | .sema = sema, | 11665 | .cur = (try ty.minInt(mod, ty)).toIntern(), |
| 11665 | .ty = ty, | 11666 | .max = (try ty.maxInt(mod, ty)).toIntern(), |
| 11666 | .cur = min, | 11667 | .range_i = 0, |
| 11667 | .max = max, | | |
| 11668 | .ranges = range_set.ranges.items, | 11668 | .ranges = range_set.ranges.items, |
| | 11669 | .limbs = if (needed_limbs > preallocated_limbs) |
| | 11670 | try sema.arena.alloc(math.big.Limb, needed_limbs) |
| | 11671 | else |
| | 11672 | &.{}, |
| 11669 | }; | 11673 | }; |
| 11670 | } | 11674 | } |
| 11671 | | 11675 | |
| 11672 | fn next(it: *RangeSetUnhandledIterator) !?Value { | 11676 | fn addOne(it: *const RangeSetUnhandledIterator, val: InternPool.Index) !?InternPool.Index { |
| 11673 | while (it.range_i < it.ranges.len) : (it.range_i += 1) { | 11677 | if (val == it.max) return null; |
| 11674 | if (!it.first) { | 11678 | const int = it.mod.intern_pool.indexToKey(val).int; |
| 11675 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); | 11679 | |
| 11676 | } | 11680 | switch (int.storage) { |
| 11677 | it.first = false; | 11681 | inline .u64, .i64 => |val_int| { |
| 11678 | if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first.toValue(), it.ty, it.sema.mod)) { | 11682 | const next_int = @addWithOverflow(val_int, 1); |
| 11679 | return it.cur; | 11683 | if (next_int[1] == 0) |
| 11680 | } | 11684 | return (try it.mod.intValue(int.ty.toType(), next_int[0])).toIntern(); |
| 11681 | it.cur = it.ranges[it.range_i].last.toValue(); | 11685 | }, |
| 11682 | } | 11686 | .big_int => {}, |
| 11683 | if (!it.first) { | 11687 | .lazy_align, .lazy_size => unreachable, |
| 11684 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); | | |
| 11685 | } | 11688 | } |
| 11686 | it.first = false; | 11689 | |
| 11687 | if (it.cur.compareScalar(.lte, it.max, it.ty, it.sema.mod)) { | 11690 | var val_space: InternPool.Key.Int.Storage.BigIntSpace = undefined; |
| 11688 | return it.cur; | 11691 | const val_bigint = int.storage.toBigInt(&val_space); |
| | 11692 | |
| | 11693 | var result_limbs: [preallocated_limbs]math.big.Limb = undefined; |
| | 11694 | var result_bigint = math.big.int.Mutable.init( |
| | 11695 | if (it.limbs.len > 0) it.limbs else &result_limbs, |
| | 11696 | 0, |
| | 11697 | ); |
| | 11698 | |
| | 11699 | result_bigint.addScalar(val_bigint, 1); |
| | 11700 | return (try it.mod.intValue_big(int.ty.toType(), result_bigint.toConst())).toIntern(); |
| | 11701 | } |
| | 11702 | |
| | 11703 | fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index { |
| | 11704 | var cur = it.cur orelse return null; |
| | 11705 | while (it.range_i < it.ranges.len and cur == it.ranges[it.range_i].first) { |
| | 11706 | defer it.range_i += 1; |
| | 11707 | cur = (try it.addOne(it.ranges[it.range_i].last)) orelse { |
| | 11708 | it.cur = null; |
| | 11709 | return null; |
| | 11710 | }; |
| 11689 | } | 11711 | } |
| 11690 | return null; | 11712 | it.cur = try it.addOne(cur); |
| | 11713 | return cur; |
| 11691 | } | 11714 | } |
| 11692 | }; | 11715 | }; |
| 11693 | | 11716 | |