compiler: Own SSA cache storage during initialization
e0736f02d493de9e2dd9b0ab1280e582f6ab23e372fb067d73b70c74e6235432
1 parent
c3a1a901
lib/std/lang/lower.rad
+4 -2
| 2171 | 2171 | /// be switched to via [`switchToBlock`] before instructions can be emitted. |
|
| 2172 | 2172 | unsafe fn createBlock 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, labelBase: *[u8]) -> BlockId throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 2173 | 2173 | let label = try nextLabel(self, labelBase); |
|
| 2174 | 2174 | let id = BlockId(self.blockData.len); |
|
| 2175 | 2175 | let varCount = self.localCount; |
|
| 2176 | - | let vars = try! alloc::allocRawSlice(self.arena, @sizeOf(?il::Val), @alignOf(?il::Val), varCount) as *unsafe mut [?il::Val]; |
|
| 2176 | + | let vars = try! alloc::allocSlice( |
|
| 2177 | + | self.arena, @sizeOf(?il::Val), @alignOf(?il::Val), varCount |
|
| 2178 | + | ) as *mut [?il::Val]; |
|
| 2177 | 2179 | ||
| 2178 | 2180 | for i in 0..varCount { |
|
| 2179 | 2181 | set vars[i] = nil; |
|
| 2180 | 2182 | } |
|
| 2181 | 2183 | self.blockData.append(BlockData { |
| 2183 | 2185 | params: &mut [], |
|
| 2184 | 2186 | paramVars: &mut [], |
|
| 2185 | 2187 | instrs: &mut [], |
|
| 2186 | 2188 | locs: &mut [], |
|
| 2187 | 2189 | preds: &mut [], |
|
| 2188 | - | vars, |
|
| 2190 | + | vars: (&mut vars[..]) as *unsafe mut [?il::Val], |
|
| 2189 | 2191 | sealState: Sealed::No, |
|
| 2190 | 2192 | loopDepth: self.loopDepth, |
|
| 2191 | 2193 | }, alloc::arenaAllocator(self.arena)); |
|
| 2192 | 2194 | ||
| 2193 | 2195 | return id; |
test/tests/ssa.block.locals.rad
added
+52 -0
| 1 | + | //! returns: 0 |
|
| 2 | + | ||
| 3 | + | /// Select different local bindings while retaining outer and loop values. |
|
| 4 | + | fn run(limit: u32, selected: bool) -> u32 { |
|
| 5 | + | let outer: u32 = 11; |
|
| 6 | + | let mut result: u32 = 0; |
|
| 7 | + | for index in 0..limit { |
|
| 8 | + | let current = outer + index; |
|
| 9 | + | if selected { |
|
| 10 | + | let outer = current * 2; |
|
| 11 | + | let extra = outer + 3; |
|
| 12 | + | set result += extra; |
|
| 13 | + | } else { |
|
| 14 | + | let outer = current * 3; |
|
| 15 | + | let extra = outer + 5; |
|
| 16 | + | set result += extra; |
|
| 17 | + | } |
|
| 18 | + | assert outer == 11; |
|
| 19 | + | assert current == 11 + index; |
|
| 20 | + | match index % 3 { |
|
| 21 | + | case 0 => { |
|
| 22 | + | let local = current + 1; |
|
| 23 | + | set result += local; |
|
| 24 | + | } |
|
| 25 | + | case 1 => { |
|
| 26 | + | let local = current + 2; |
|
| 27 | + | set result += local; |
|
| 28 | + | } |
|
| 29 | + | else => { |
|
| 30 | + | let local = current + 3; |
|
| 31 | + | set result += local; |
|
| 32 | + | } |
|
| 33 | + | } |
|
| 34 | + | } |
|
| 35 | + | return result; |
|
| 36 | + | } |
|
| 37 | + | ||
| 38 | + | /// Compare both branches with a direct arithmetic accumulation. |
|
| 39 | + | @default fn main() -> u32 { |
|
| 40 | + | for limit in 0..12 { |
|
| 41 | + | let mut first: u32 = 0; |
|
| 42 | + | let mut second: u32 = 0; |
|
| 43 | + | for index in 0..limit { |
|
| 44 | + | set first += (11 + index) * 3 + 4 + index % 3; |
|
| 45 | + | set second += (11 + index) * 4 + 6 + index % 3; |
|
| 46 | + | } |
|
| 47 | + | assert run(limit, true) == first; |
|
| 48 | + | assert run(limit, false) == second; |
|
| 49 | + | assert run(limit, true) == first; |
|
| 50 | + | } |
|
| 51 | + | return 0; |
|
| 52 | + | } |