Check a register class.
(&mut self, class: RegClass)
| 155 | |
| 156 | /// Check a register class. |
| 157 | fn check_class(&mut self, class: RegClass) -> Result<()> { |
| 158 | let bank = self.reginfo.bank_for_class(class); |
| 159 | self.check_entity(Entity::RegBank(bank))?; |
| 160 | |
| 161 | let group_size = self.reginfo.class_group_size(class); |
| 162 | ensure!( |
| 163 | group_size <= MAX_GROUP_SIZE, |
| 164 | "{class}: Group size {group_size} too large (max: {MAX_GROUP_SIZE})" |
| 165 | ); |
| 166 | ensure!(group_size != 0, "{class}: Invalid group size of 0"); |
| 167 | if group_size != 1 { |
| 168 | ensure!( |
| 169 | !self.reginfo.class_includes_spillslots(class), |
| 170 | "{class}: Group class cannot include spillslots" |
| 171 | ); |
| 172 | } |
| 173 | |
| 174 | if group_size != 1 { |
| 175 | let mut regs_per_index = [PhysRegSet::new(); MAX_GROUP_SIZE]; |
| 176 | for group in self.reginfo.class_group_members(class) { |
| 177 | // Check that class members have the same group size as the class. |
| 178 | let members = self.reginfo.reg_group_members(group); |
| 179 | ensure!( |
| 180 | members.len() == group_size, |
| 181 | "{group} group size ({}) doesn't match {class} group size ({group_size})", |
| 182 | members.len() |
| 183 | ); |
| 184 | |
| 185 | for (group_index, ®) in members.iter().enumerate() { |
| 186 | // Check that class members are in the same bank as the class. |
| 187 | ensure!( |
| 188 | self.reginfo.bank_for_reg(reg) == Some(bank), |
| 189 | "{class} contains {reg} which is outside {bank}" |
| 190 | ); |
| 191 | |
| 192 | // Check that, at each index, each register is unique within the class. |
| 193 | ensure!( |
| 194 | !regs_per_index[group_index].contains(reg), |
| 195 | "{class} has duplicate register {reg} at group index {group_index}" |
| 196 | ); |
| 197 | regs_per_index[group_index].insert(reg); |
| 198 | |
| 199 | // Check the reverse mapping in group_for_reg. |
| 200 | ensure!( |
| 201 | self.reginfo.group_for_reg(reg, group_index, class) == Some(group), |
| 202 | "Inconsistent group_for_reg({reg}, {group_index}, {class}): got {:?} \ |
| 203 | expected {:?}", |
| 204 | self.reginfo.group_for_reg(reg, group_index, class), |
| 205 | Some(group) |
| 206 | ); |
| 207 | } |
| 208 | } |
| 209 | } else { |
| 210 | for reg in self.reginfo.class_members(class) { |
| 211 | // Check that class members are in the same bank as the class. |
| 212 | ensure!( |
| 213 | self.reginfo.bank_for_reg(reg) == Some(bank), |
| 214 | "{class} contains {reg} which is outside {bank}" |
no test coverage detected