Handles the definition of a value. This consists of 4 parts: 1) Invalidating any previous mapping for the same value, since those are from the previous loop iteration and no longer valid. 2) Invalidating any previous value at the destination location. 3) Recording the location of the new value. 4) Updating spill-slot availability for redundant spill elimination.
(&mut self, value: Value, alloc: Allocation, block: Block, reginfo: &impl RegInfo)
| 479 | /// 3) Recording the location of the new value. |
| 480 | /// 4) Updating spill-slot availability for redundant spill elimination. |
| 481 | fn def_value(&mut self, value: Value, alloc: Allocation, block: Block, reginfo: &impl RegInfo) { |
| 482 | self.value_def_block[value] = block; |
| 483 | match alloc.kind() { |
| 484 | AllocationKind::PhysReg(reg) => { |
| 485 | for unit in reginfo.reg_units(reg) { |
| 486 | self.def_units.insert(unit); |
| 487 | self.clobber_unit(unit); |
| 488 | self.last_unit_write.insert(unit, (reg, value)); |
| 489 | } |
| 490 | let set = [reg].into_iter().collect(); |
| 491 | self.value_regs.insert(value, set); |
| 492 | if let Some(slot) = self.slot_for_value[value].expand() { |
| 493 | self.spillslot_values.remove(slot); |
| 494 | } |
| 495 | } |
| 496 | AllocationKind::SpillSlot(slot) => { |
| 497 | self.value_regs.remove(value); |
| 498 | let canonical_slot = self.slot_for_value[value].expand(); |
| 499 | if canonical_slot == Some(slot) { |
| 500 | self.spillslot_values.insert(slot, value); |
| 501 | self.last_spilled_in[value] = Some(block).into(); |
| 502 | } else { |
| 503 | if let Some(canonical_slot) = canonical_slot { |
| 504 | self.spillslot_values.remove(canonical_slot); |
| 505 | } |
| 506 | self.spillslot_values.remove(slot); |
| 507 | } |
| 508 | } |
| 509 | } |
| 510 | } |
| 511 | |
| 512 | /// Simpler version of `def_value` used for to set up the initial block |
| 513 | /// entry state. |