compiler: Check SSA cache rewrite traversal
5a3af878d1693741707270610d59831961d508029e4d14233c6c6e9f728286d7
1 parent
86f24335
lib/std/lang/lower.rad
+23 -8
| 2089 | 2089 | /// Rewrite cached SSA values for a variable across all blocks, and also |
|
| 2090 | 2090 | /// rewrite any terminator arguments that reference the provisional register. |
|
| 2091 | 2091 | /// The latter is necessary because recursive SSA resolution may have already |
|
| 2092 | 2092 | /// patched terminator arguments with the provisional value before it was |
|
| 2093 | 2093 | /// found to be trivial. |
|
| 2094 | - | unsafe fn rewriteCachedVarValue 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, v: Var, from: il::Val, to: il::Val) where 'arena: 'phase, 'phase: 'function { |
|
| 2094 | + | fn rewriteCachedVarValue 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, v: Var, from: il::Val, to: il::Val) where 'arena: 'phase, 'phase: 'function { |
|
| 2095 | 2095 | for i in 0..self.blockData.len { |
|
| 2096 | 2096 | let blk = &mut self.blockData[i]; |
|
| 2097 | 2097 | if blk.vars[*v] == from { |
|
| 2098 | 2098 | set blk.vars[*v] = to; |
|
| 2099 | 2099 | } |
|
| 2100 | 2100 | if blk.instrs.len > 0 { |
|
| 2101 | 2101 | let ix = blk.instrs.len - 1; |
|
| 2102 | 2102 | match &mut blk.instrs[ix] { |
|
| 2103 | - | case il::Instr::Jmp { args, .. } => |
|
| 2104 | - | rewriteValInSlice(*args, from, to), |
|
| 2103 | + | case il::Instr::Jmp { args, .. } => { |
|
| 2104 | + | unsafe { |
|
| 2105 | + | rewriteValInSlice(*args, from, to); |
|
| 2106 | + | } |
|
| 2107 | + | }, |
|
| 2105 | 2108 | case il::Instr::Br { thenArgs, elseArgs, .. } => { |
|
| 2106 | - | rewriteValInSlice(*thenArgs, from, to); |
|
| 2107 | - | rewriteValInSlice(*elseArgs, from, to); |
|
| 2109 | + | unsafe { |
|
| 2110 | + | rewriteValInSlice(*thenArgs, from, to); |
|
| 2111 | + | rewriteValInSlice(*elseArgs, from, to); |
|
| 2112 | + | } |
|
| 2108 | 2113 | } |
|
| 2109 | 2114 | case il::Instr::Switch { defaultArgs, cases, .. } => { |
|
| 2110 | - | rewriteValInSlice(*defaultArgs, from, to); |
|
| 2111 | - | for j in 0..cases.len { |
|
| 2112 | - | rewriteValInSlice(cases[j].args, from, to); |
|
| 2115 | + | unsafe { |
|
| 2116 | + | rewriteValInSlice(*defaultArgs, from, to); |
|
| 2117 | + | rewriteSwitchArgs(*cases, from, to); |
|
| 2113 | 2118 | } |
|
| 2114 | 2119 | } |
|
| 2115 | 2120 | else => {} |
|
| 2116 | 2121 | } |
|
| 2117 | 2122 | } |
|
| 2118 | 2123 | } |
|
| 2119 | 2124 | } |
|
| 2120 | 2125 | ||
| 2126 | + | /// Replace a provisional value in each switch case's argument sequence. |
|
| 2127 | + | fn rewriteSwitchArgs(cases: &mut [il::SwitchCase], from: il::Val, to: il::Val) { |
|
| 2128 | + | for i in 0..cases.len { |
|
| 2129 | + | let branch = &mut cases[i]; |
|
| 2130 | + | unsafe { |
|
| 2131 | + | rewriteValInSlice(branch.args, from, to); |
|
| 2132 | + | } |
|
| 2133 | + | } |
|
| 2134 | + | } |
|
| 2135 | + | ||
| 2121 | 2136 | /// Replace all occurrences of `from` with `to` in an args slice. |
|
| 2122 | 2137 | fn rewriteValInSlice(args: &mut [il::Val], from: il::Val, to: il::Val) { |
|
| 2123 | 2138 | for i in 0..args.len { |
|
| 2124 | 2139 | if args[i] == from { |
|
| 2125 | 2140 | set args[i] = to; |