Adds an indirect rematerialization recipe for a value defined at the current program point.
(
&mut self,
value: Value,
block: Block,
is_first_inst: bool,
)
| 569 | /// Adds an indirect rematerialization recipe for a value defined at |
| 570 | /// the current program point. |
| 571 | fn add_indirect_remat( |
| 572 | &mut self, |
| 573 | value: Value, |
| 574 | block: Block, |
| 575 | is_first_inst: bool, |
| 576 | ) -> Result<()> { |
| 577 | let saved_early_fixed = self.early_fixed; |
| 578 | let saved_late_fixed = self.late_fixed; |
| 579 | self.early_fixed.clear(); |
| 580 | self.late_fixed.clear(); |
| 581 | |
| 582 | let allow_destination_overlap: bool = self.u.arbitrary()?; |
| 583 | let bank = self.func.values[value].bank; |
| 584 | let mut constraint = OperandConstraint::Class(self.reginfo.top_level_class(bank)); |
| 585 | if self.u.arbitrary()? { |
| 586 | let reg = *self.u.choose(&self.reg_per_bank[bank])?; |
| 587 | if self.check_fixed_conflict(reg, !allow_destination_overlap, true) { |
| 588 | constraint = OperandConstraint::Fixed(reg); |
| 589 | } |
| 590 | } |
| 591 | |
| 592 | let input_count = self.u.int_in_range(self.config.uses_per_inst.clone())?; |
| 593 | if input_count != 0 { |
| 594 | let mut inputs = vec![]; |
| 595 | for _ in 0..input_count { |
| 596 | let input_idx = inputs.len(); |
| 597 | let input = self.gen_use(block, is_first_inst, input_idx != 0, |this| { |
| 598 | let OperandConstraint::Class(class) = constraint else { |
| 599 | return Ok(None); |
| 600 | }; |
| 601 | if this.u.arbitrary()? { |
| 602 | constraint = OperandConstraint::Reuse(input_idx); |
| 603 | Ok(Some(class)) |
| 604 | } else { |
| 605 | Ok(None) |
| 606 | } |
| 607 | })?; |
| 608 | inputs.push(input); |
| 609 | } |
| 610 | |
| 611 | self.func.values[value].indirect_remat = Some(IndirectRematData { |
| 612 | constraint, |
| 613 | inputs, |
| 614 | allow_destination_overlap, |
| 615 | }); |
| 616 | } |
| 617 | |
| 618 | self.early_fixed = saved_early_fixed; |
| 619 | self.late_fixed = saved_late_fixed; |
| 620 | |
| 621 | Ok(()) |
| 622 | } |
| 623 | |
| 624 | /// Generates an operand which defines a value. |
| 625 | fn gen_def( |
no test coverage detected