Generates an operand which defines a value.
(
&mut self,
block: Block,
value: Value,
is_ret: bool,
op_idx: usize,
defined_values: &mut Vec<Value>,
)
| 623 | |
| 624 | /// Generates an operand which defines a value. |
| 625 | fn gen_def( |
| 626 | &mut self, |
| 627 | block: Block, |
| 628 | value: Value, |
| 629 | is_ret: bool, |
| 630 | op_idx: usize, |
| 631 | defined_values: &mut Vec<Value>, |
| 632 | ) -> Result<Operand> { |
| 633 | let bank = self.func.values[value].bank; |
| 634 | |
| 635 | // Try to use a fixed register. |
| 636 | if self.u.arbitrary()? { |
| 637 | let reg = *self.u.choose(&self.reg_per_bank[bank])?; |
| 638 | let kind = if !is_ret && self.u.arbitrary()? { |
| 639 | OperandKind::Def(value) |
| 640 | } else { |
| 641 | OperandKind::EarlyDef(value) |
| 642 | }; |
| 643 | if self.check_fixed_conflict(reg, matches!(kind, OperandKind::EarlyDef(_)), true) { |
| 644 | defined_values.push(value); |
| 645 | return Ok(Operand::new(kind, OperandConstraint::Fixed(reg))); |
| 646 | } |
| 647 | } |
| 648 | |
| 649 | // Pick a register class to use. |
| 650 | let class = *self.u.choose(&self.class_per_bank[bank])?; |
| 651 | let group_size = self.reginfo.class_group_size(class); |
| 652 | let kind = if group_size > 1 { |
| 653 | let mut values = vec![value]; |
| 654 | for _ in 1..group_size { |
| 655 | // Try to find another definition from the definition list in |
| 656 | // the current block. |
| 657 | let value = if !self.defs_by_blocks[block].is_empty() && self.u.arbitrary()? { |
| 658 | let value_idx = self.u.choose_index(self.defs_by_blocks[block].len())?; |
| 659 | if self.func.values[self.defs_by_blocks[block][value_idx]].bank == bank { |
| 660 | self.defs_by_blocks[block].remove(value_idx) |
| 661 | } else { |
| 662 | self.new_value(bank)? |
| 663 | } |
| 664 | } else { |
| 665 | self.new_value(bank)? |
| 666 | }; |
| 667 | values.push(value); |
| 668 | } |
| 669 | if self.u.arbitrary()? { |
| 670 | // Later change this into a Reuse. |
| 671 | self.reuse_operands.push(op_idx); |
| 672 | } |
| 673 | defined_values.extend_from_slice(&values); |
| 674 | let value_group = self.func.value_groups.push(values); |
| 675 | if !is_ret && self.u.arbitrary()? { |
| 676 | OperandKind::DefGroup(value_group) |
| 677 | } else { |
| 678 | OperandKind::EarlyDefGroup(value_group) |
| 679 | } |
| 680 | } else { |
| 681 | if self.u.arbitrary()? { |
| 682 | // Later change this into a Reuse. |
no test coverage detected