Computes the allocation order for the given virtual register.
(
&mut self,
vreg: V,
virt_regs: &VirtRegs,
hints: &Hints,
last_allocated_reg: &SecondaryMap<ValueSet, PackedOption<PhysReg>>,
reginfo: &impl RegInfo,
| 64 | |
| 65 | /// Computes the allocation order for the given virtual register. |
| 66 | pub fn compute( |
| 67 | &mut self, |
| 68 | vreg: V, |
| 69 | virt_regs: &VirtRegs, |
| 70 | hints: &Hints, |
| 71 | last_allocated_reg: &SecondaryMap<ValueSet, PackedOption<PhysReg>>, |
| 72 | reginfo: &impl RegInfo, |
| 73 | ) { |
| 74 | // If this virtual register has fixed-register constraints, collect them |
| 75 | // and assign them weights based on their use frequency. |
| 76 | self.hinted_regs.clear(); |
| 77 | for (group_index, vreg) in vreg.vregs(virt_regs).enumerate() { |
| 78 | if virt_regs[vreg].has_fixed_hint { |
| 79 | let class = virt_regs[vreg].class; |
| 80 | self.collect_fixed_preferences(vreg, group_index, class, virt_regs, hints, reginfo); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | // If there are hinted registers, they need to be sorted in order |
| 85 | // of decreasing weight. |
| 86 | if self.hinted_regs.len() > 1 { |
| 87 | self.hinted_regs.as_mut_vec().sort_unstable_by( |
| 88 | |&(_reg1, preference_weight1), &(_reg2, preference_weight2)| { |
| 89 | // Note: the variables are reversed here to sort in order of decreasing weight. |
| 90 | if preference_weight2 < preference_weight1 { |
| 91 | Ordering::Less |
| 92 | } else if preference_weight2 > preference_weight1 { |
| 93 | Ordering::Greater |
| 94 | } else { |
| 95 | Ordering::Equal |
| 96 | } |
| 97 | }, |
| 98 | ); |
| 99 | self.hinted_regs.rebuild_mapping(); |
| 100 | } |
| 101 | |
| 102 | // If another virtual register in the same value set was assigned, try |
| 103 | // to reuse the same physical register. This can help with move |
| 104 | // elimination in the later stages. |
| 105 | // |
| 106 | // We don't assign it a preference though since it's not worth evicting |
| 107 | // other registers over. |
| 108 | for (group_index, vreg) in vreg.vregs(virt_regs).enumerate() { |
| 109 | let set = virt_regs[vreg].value_set; |
| 110 | if let Some(hint) = last_allocated_reg[set].expand() { |
| 111 | let class = virt_regs[vreg.first_vreg(virt_regs)].class; |
| 112 | if let Some(reg) = V::group_for_reg(hint, group_index, class, reginfo) { |
| 113 | self.hinted_regs.entry(reg).or_insert(0.0); |
| 114 | } |
| 115 | } |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | /// Returns an iterator over all the registers in the allocation order. |
| 120 | pub fn order<'a>( |
no test coverage detected