Assigns final stack offsets to all active spill slots.
(
&mut self,
move_resolver: &MoveResolver,
allocations: &Allocations,
stats: &mut Stats,
)
| 276 | |
| 277 | /// Assigns final stack offsets to all active spill slots. |
| 278 | pub fn finalize_stack_layout( |
| 279 | &mut self, |
| 280 | move_resolver: &MoveResolver, |
| 281 | allocations: &Allocations, |
| 282 | stats: &mut Stats, |
| 283 | ) -> Result<(), RegAllocError> { |
| 284 | self.stack_layout.spillslot_area_size = 0; |
| 285 | |
| 286 | // Collect the set of spillslots that are used in the function. Some |
| 287 | // spillslots may end up unused due to move optimization. |
| 288 | self.collect_used_spillslots(move_resolver, allocations); |
| 289 | |
| 290 | // Process spill slots from largest to smallest. |
| 291 | self.final_slots.clear(); |
| 292 | self.final_slots.extend( |
| 293 | self.stack_layout |
| 294 | .slots |
| 295 | .iter_mut() |
| 296 | .filter_map(|(slot, layout)| { |
| 297 | // Remove any unused spillslots from the layout. |
| 298 | if self.used_spillslots.contains(slot) { |
| 299 | Some((slot, layout.unwrap().1)) |
| 300 | } else { |
| 301 | *layout = None; |
| 302 | None |
| 303 | } |
| 304 | }), |
| 305 | ); |
| 306 | self.final_slots |
| 307 | .sort_unstable_by_key(|&(_slot, size)| Reverse(size)); |
| 308 | |
| 309 | for &(slot, size) in &self.final_slots { |
| 310 | // This is guaranteed to be properly aligned because we start |
| 311 | // allocating from larger sizes first, and all sizes are |
| 312 | // powers of 2. |
| 313 | debug_assert_eq!(self.stack_layout.spillslot_area_size % size.bytes(), 0); |
| 314 | |
| 315 | let offset = self.stack_layout.spillslot_area_size; |
| 316 | self.stack_layout.spillslot_area_size = self |
| 317 | .stack_layout |
| 318 | .spillslot_area_size |
| 319 | .checked_add(size.bytes()) |
| 320 | .ok_or(RegAllocError::FunctionTooBig)?; |
| 321 | self.stack_layout.slots[slot] = Some((offset, size)); |
| 322 | } |
| 323 | |
| 324 | stat!(stats, final_spillslots, self.final_slots.len()); |
| 325 | stat!( |
| 326 | stats, |
| 327 | spill_area_size, |
| 328 | self.stack_layout.spillslot_area_size as usize |
| 329 | ); |
| 330 | |
| 331 | Ok(()) |
| 332 | } |
| 333 | } |
no test coverage detected