compiler: Read block descriptors through checked slices
06628001e2e58e8e5ec178187d8fe2b48da38885c774992acefb2c7627632bfe
1 parent
cb284e73
lib/std/lang/lower.rad
+7 -7
| 2214 | 2214 | unsafe fn switchToAndSeal 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId) throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 2215 | 2215 | try sealBlock(self, block); |
|
| 2216 | 2216 | switchToBlock(self, block); |
|
| 2217 | 2217 | } |
|
| 2218 | 2218 | ||
| 2219 | - | /// Get block data by block id. |
|
| 2220 | - | unsafe fn getBlock 'arena 'phase 'function (self: &FnLowerer 'arena 'phase 'function, block: BlockId) -> *unsafe BlockData where 'arena: 'phase, 'phase: 'function { |
|
| 2221 | - | return &self.blockData[*block]; |
|
| 2219 | + | /// Get a snapshot of a block's descriptors by block id. |
|
| 2220 | + | fn getBlock(blocks: &[BlockData], block: BlockId) -> BlockData { |
|
| 2221 | + | return blocks[*block]; |
|
| 2222 | 2222 | } |
|
| 2223 | 2223 | ||
| 2224 | 2224 | /// Get mutable block data by block id. |
|
| 2225 | 2225 | unsafe fn getBlockMut 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId) -> *unsafe mut BlockData where 'arena: 'phase, 'phase: 'function { |
|
| 2226 | 2226 | return &mut self.blockData[*block]; |
| 2673 | 2673 | try sealBlock(self, target); |
|
| 2674 | 2674 | } |
|
| 2675 | 2675 | ||
| 2676 | 2676 | /// Check if the current block already has a terminator instruction. |
|
| 2677 | 2677 | unsafe fn blockHasTerminator 'arena 'phase 'function (self: &FnLowerer 'arena 'phase 'function) -> bool where 'arena: 'phase, 'phase: 'function { |
|
| 2678 | - | let blk = getBlock(self, currentBlock(self)); |
|
| 2678 | + | let blk = getBlock(&self.blockData[..], currentBlock(self)); |
|
| 2679 | 2679 | if blk.instrs.len == 0 { |
|
| 2680 | 2680 | return false; |
|
| 2681 | 2681 | } |
|
| 2682 | 2682 | match blk.instrs[blk.instrs.len - 1] { |
|
| 2683 | 2683 | case il::Instr::Ret { .. }, |
| 3074 | 3074 | /// |
|
| 3075 | 3075 | /// This representation avoids the need for phi nodes to reference their |
|
| 3076 | 3076 | /// predecessor blocks explicitly, since the control flow edges already encode |
|
| 3077 | 3077 | /// that information. |
|
| 3078 | 3078 | unsafe fn resolveBlockArgs 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId, v: Var, paramIdx: u32) throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 3079 | - | let blk = getBlock(self, block); |
|
| 3079 | + | let blk = getBlock(&self.blockData[..], block); |
|
| 3080 | 3080 | ||
| 3081 | 3081 | // For each predecessor, recursively look up the variable's reaching definition |
|
| 3082 | 3082 | // in that block, then patch the predecessor's terminator to pass that value |
|
| 3083 | 3083 | // as an argument to this block's parameter. |
|
| 3084 | 3084 | for predId in blk.preds { |
| 3092 | 3092 | } |
|
| 3093 | 3093 | ||
| 3094 | 3094 | /// Check if a block parameter is trivial, i.e. all predecessors provide |
|
| 3095 | 3095 | /// the same value. Returns the trivial value if so. |
|
| 3096 | 3096 | unsafe fn getTrivialPhiVal 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId, v: Var) -> ?il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 3097 | - | let blk = getBlock(self, block); |
|
| 3097 | + | let blk = getBlock(&self.blockData[..], block); |
|
| 3098 | 3098 | // Get the block parameter register. |
|
| 3099 | 3099 | let paramReg = blk.vars[*v]; |
|
| 3100 | 3100 | // Check if all predecessors provide the same value. |
|
| 3101 | 3101 | let mut sameVal: ?il::Val = nil; |
|
| 3102 | 3102 |
| 5721 | 5721 | exitLoop(self); |
|
| 5722 | 5722 | ||
| 5723 | 5723 | // Only seal end block if it's actually reachable (ie. has predecessors). |
|
| 5724 | 5724 | // If the loop has no breaks and only exits via return, the end block |
|
| 5725 | 5725 | // remains unreachable and isn't added to the CFG. |
|
| 5726 | - | if getBlock(self, endBlock).preds.len > 0 { |
|
| 5726 | + | if getBlock(&self.blockData[..], endBlock).preds.len > 0 { |
|
| 5727 | 5727 | try switchToAndSeal(self, endBlock); |
|
| 5728 | 5728 | } |
|
| 5729 | 5729 | } |
|
| 5730 | 5730 | ||
| 5731 | 5731 | /// Lower a while loop: `while <cond> { <body> }`. |