compiler: Grow initialized scalar match destinations
9a2a5d6dd9ab089ac98ff1da9b51d501b5bfb5f898274fbf988dfc5920246f12
1 parent
84ff2d4f
lib/std/lang/lower.rad
+3 -3
| 3719 | 3719 | return try finalizeBlocks(self); |
|
| 3720 | 3720 | } |
|
| 3721 | 3721 | ||
| 3722 | 3722 | /// Lower a scalar match as a switch instruction. |
|
| 3723 | 3723 | unsafe fn lowerMatchSwitch 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, prongs: *[*ast::Node], subject: &MatchSubject, mergeBlock: &mut ?BlockId) throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 3724 | - | let mut blocks: [BlockId; 32] = undefined; |
|
| 3724 | + | let mut blocks: *mut [BlockId] = &mut []; |
|
| 3725 | 3725 | let mut cases: *unsafe mut [il::SwitchCase] = &mut []; |
|
| 3726 | 3726 | let mut defaultIdx: u32 = 0; |
|
| 3727 | 3727 | let entry = currentBlock(self); |
|
| 3728 | 3728 | ||
| 3729 | 3729 | for p, i in prongs { |
|
| 3730 | 3730 | let case ast::NodeValue::MatchProng(prong) = p.value |
|
| 3731 | 3731 | else throw LowerError::UnexpectedNodeValue(p); |
|
| 3732 | 3732 | ||
| 3733 | 3733 | match prong.arm { |
|
| 3734 | 3734 | case ast::ProngArm::Binding(_), ast::ProngArm::Else => { |
|
| 3735 | - | set blocks[i] = try createBlock(self, "default"); |
|
| 3735 | + | blocks.append(try createBlock(self, "default"), alloc::arenaAllocator(self.arena)); |
|
| 3736 | 3736 | set defaultIdx = i; |
|
| 3737 | 3737 | } |
|
| 3738 | 3738 | case ast::ProngArm::Case(pats) => { |
|
| 3739 | - | set blocks[i] = try createBlock(self, "case"); |
|
| 3739 | + | blocks.append(try createBlock(self, "case"), alloc::arenaAllocator(self.arena)); |
|
| 3740 | 3740 | for pat in pats { |
|
| 3741 | 3741 | let cv = resolver::constValueEntry(self.low.resolver, pat) |
|
| 3742 | 3742 | else throw LowerError::MissingConst(pat); |
|
| 3743 | 3743 | ||
| 3744 | 3744 | cases.append(il::SwitchCase { |
test/tests/match.switch.capacity.rad
added
+161 -0
| 1 | + | //! returns: 0 |
|
| 2 | + | //! Scalar match destinations cover table boundaries and large matches. |
|
| 3 | + | ||
| 4 | + | /// Select among 31 scalar cases and a fallback. |
|
| 5 | + | fn select31(value: u32) -> u32 { |
|
| 6 | + | match value { |
|
| 7 | + | case 0 => return 100, |
|
| 8 | + | case 1 => return 101, |
|
| 9 | + | case 2 => return 102, |
|
| 10 | + | case 3 => return 103, |
|
| 11 | + | case 4 => return 104, |
|
| 12 | + | case 5 => return 105, |
|
| 13 | + | case 6 => return 106, |
|
| 14 | + | case 7 => return 107, |
|
| 15 | + | case 8 => return 108, |
|
| 16 | + | case 9 => return 109, |
|
| 17 | + | case 10 => return 110, |
|
| 18 | + | case 11 => return 111, |
|
| 19 | + | case 12 => return 112, |
|
| 20 | + | case 13 => return 113, |
|
| 21 | + | case 14 => return 114, |
|
| 22 | + | case 15 => return 115, |
|
| 23 | + | case 16 => return 116, |
|
| 24 | + | case 17 => return 117, |
|
| 25 | + | case 18 => return 118, |
|
| 26 | + | case 19 => return 119, |
|
| 27 | + | case 20 => return 120, |
|
| 28 | + | case 21 => return 121, |
|
| 29 | + | case 22 => return 122, |
|
| 30 | + | case 23 => return 123, |
|
| 31 | + | case 24 => return 124, |
|
| 32 | + | case 25 => return 125, |
|
| 33 | + | case 26 => return 126, |
|
| 34 | + | case 27 => return 127, |
|
| 35 | + | case 28 => return 128, |
|
| 36 | + | case 29 => return 129, |
|
| 37 | + | case 30 => return 130, |
|
| 38 | + | else => return 999, |
|
| 39 | + | } |
|
| 40 | + | } |
|
| 41 | + | ||
| 42 | + | /// Select among 32 scalar cases and a fallback. |
|
| 43 | + | fn select32(value: u32) -> u32 { |
|
| 44 | + | match value { |
|
| 45 | + | case 0 => return 100, |
|
| 46 | + | case 1 => return 101, |
|
| 47 | + | case 2 => return 102, |
|
| 48 | + | case 3 => return 103, |
|
| 49 | + | case 4 => return 104, |
|
| 50 | + | case 5 => return 105, |
|
| 51 | + | case 6 => return 106, |
|
| 52 | + | case 7 => return 107, |
|
| 53 | + | case 8 => return 108, |
|
| 54 | + | case 9 => return 109, |
|
| 55 | + | case 10 => return 110, |
|
| 56 | + | case 11 => return 111, |
|
| 57 | + | case 12 => return 112, |
|
| 58 | + | case 13 => return 113, |
|
| 59 | + | case 14 => return 114, |
|
| 60 | + | case 15 => return 115, |
|
| 61 | + | case 16 => return 116, |
|
| 62 | + | case 17 => return 117, |
|
| 63 | + | case 18 => return 118, |
|
| 64 | + | case 19 => return 119, |
|
| 65 | + | case 20 => return 120, |
|
| 66 | + | case 21 => return 121, |
|
| 67 | + | case 22 => return 122, |
|
| 68 | + | case 23 => return 123, |
|
| 69 | + | case 24 => return 124, |
|
| 70 | + | case 25 => return 125, |
|
| 71 | + | case 26 => return 126, |
|
| 72 | + | case 27 => return 127, |
|
| 73 | + | case 28 => return 128, |
|
| 74 | + | case 29 => return 129, |
|
| 75 | + | case 30 => return 130, |
|
| 76 | + | case 31 => return 131, |
|
| 77 | + | else => return 999, |
|
| 78 | + | } |
|
| 79 | + | } |
|
| 80 | + | ||
| 81 | + | /// Select among 64 scalar cases and a fallback. |
|
| 82 | + | fn select64(value: u32) -> u32 { |
|
| 83 | + | match value { |
|
| 84 | + | case 0 => return 100, |
|
| 85 | + | case 1 => return 101, |
|
| 86 | + | case 2 => return 102, |
|
| 87 | + | case 3 => return 103, |
|
| 88 | + | case 4 => return 104, |
|
| 89 | + | case 5 => return 105, |
|
| 90 | + | case 6 => return 106, |
|
| 91 | + | case 7 => return 107, |
|
| 92 | + | case 8 => return 108, |
|
| 93 | + | case 9 => return 109, |
|
| 94 | + | case 10 => return 110, |
|
| 95 | + | case 11 => return 111, |
|
| 96 | + | case 12 => return 112, |
|
| 97 | + | case 13 => return 113, |
|
| 98 | + | case 14 => return 114, |
|
| 99 | + | case 15 => return 115, |
|
| 100 | + | case 16 => return 116, |
|
| 101 | + | case 17 => return 117, |
|
| 102 | + | case 18 => return 118, |
|
| 103 | + | case 19 => return 119, |
|
| 104 | + | case 20 => return 120, |
|
| 105 | + | case 21 => return 121, |
|
| 106 | + | case 22 => return 122, |
|
| 107 | + | case 23 => return 123, |
|
| 108 | + | case 24 => return 124, |
|
| 109 | + | case 25 => return 125, |
|
| 110 | + | case 26 => return 126, |
|
| 111 | + | case 27 => return 127, |
|
| 112 | + | case 28 => return 128, |
|
| 113 | + | case 29 => return 129, |
|
| 114 | + | case 30 => return 130, |
|
| 115 | + | case 31 => return 131, |
|
| 116 | + | case 32 => return 132, |
|
| 117 | + | case 33 => return 133, |
|
| 118 | + | case 34 => return 134, |
|
| 119 | + | case 35 => return 135, |
|
| 120 | + | case 36 => return 136, |
|
| 121 | + | case 37 => return 137, |
|
| 122 | + | case 38 => return 138, |
|
| 123 | + | case 39 => return 139, |
|
| 124 | + | case 40 => return 140, |
|
| 125 | + | case 41 => return 141, |
|
| 126 | + | case 42 => return 142, |
|
| 127 | + | case 43 => return 143, |
|
| 128 | + | case 44 => return 144, |
|
| 129 | + | case 45 => return 145, |
|
| 130 | + | case 46 => return 146, |
|
| 131 | + | case 47 => return 147, |
|
| 132 | + | case 48 => return 148, |
|
| 133 | + | case 49 => return 149, |
|
| 134 | + | case 50 => return 150, |
|
| 135 | + | case 51 => return 151, |
|
| 136 | + | case 52 => return 152, |
|
| 137 | + | case 53 => return 153, |
|
| 138 | + | case 54 => return 154, |
|
| 139 | + | case 55 => return 155, |
|
| 140 | + | case 56 => return 156, |
|
| 141 | + | case 57 => return 157, |
|
| 142 | + | case 58 => return 158, |
|
| 143 | + | case 59 => return 159, |
|
| 144 | + | case 60 => return 160, |
|
| 145 | + | case 61 => return 161, |
|
| 146 | + | case 62 => return 162, |
|
| 147 | + | case 63 => return 163, |
|
| 148 | + | else => return 999, |
|
| 149 | + | } |
|
| 150 | + | } |
|
| 151 | + | ||
| 152 | + | /// Exercise every case and each fallback. |
|
| 153 | + | @default fn main() -> u32 { |
|
| 154 | + | for value in 0..31 { assert select31(value) == value + 100; } |
|
| 155 | + | assert select31(31) == 999; |
|
| 156 | + | for value in 0..32 { assert select32(value) == value + 100; } |
|
| 157 | + | assert select32(32) == 999; |
|
| 158 | + | for value in 0..64 { assert select64(value) == value + 100; } |
|
| 159 | + | assert select64(64) == 999; |
|
| 160 | + | return 0; |
|
| 161 | + | } |