MCPcopy Create free account
hub / github.com/Amanieu/regalloc3 / isolate_group_uses

Method isolate_group_uses

src/internal/allocator/split.rs:1090–1224  ·  view source on GitHub ↗

Isolates all group uses in the given register group by splitting them off into minimal segments that only cover a single instruction (or part of one) and are therefore always allocatable. The remaining live range pieces are collected into a separate non-group virtual register for each original group member, which can then be split as normal.

(&mut self, group: VirtRegGroup)

Source from the content-addressed store, hash-verified

1088 /// virtual register for each original group member, which can then be split
1089 /// as normal.
1090 fn isolate_group_uses(&mut self, group: VirtRegGroup) {
1091 self.invalidate_operand_group_mapping(group);
1092
1093 // Find any group uses and split them into minimal segments
1094 let splitter = &mut self.allocator.splitter;
1095 splitter.minimal_segments.clear();
1096 splitter.new_vregs.clear();
1097 for group_index in 0..self.virt_regs.group_members(group).len() {
1098 splitter.segments.clear();
1099 let vreg = self.virt_regs.group_members(group)[group_index];
1100 let value_set = self.virt_regs[vreg].value_set;
1101 trace!("Isolating group uses in {vreg}");
1102 stat!(self.stats, isolated_group_vregs);
1103 for &segment in self.virt_regs.segments(vreg) {
1104 let mut segment = segment;
1105 'outer: loop {
1106 for &u in &self.uses[segment.use_list] {
1107 match u.kind {
1108 UseKind::GroupClassUse {
1109 slot: _,
1110 class: _,
1111 group_index: use_group_index,
1112 }
1113 | UseKind::GroupClassDef {
1114 slot: _,
1115 class: _,
1116 group_index: use_group_index,
1117 } => {
1118 debug_assert_eq!(use_group_index as usize, group_index);
1119 }
1120 UseKind::ClassUse { .. }
1121 | UseKind::ClassDef { .. }
1122 | UseKind::FixedDef { .. }
1123 | UseKind::FixedUse { .. }
1124 | UseKind::TiedUse { .. }
1125 | UseKind::ConstraintConflict { .. }
1126 | UseKind::BlockparamIn { .. }
1127 | UseKind::BlockparamOut { .. } => continue,
1128 };
1129
1130 trace!("Splitting around group use {}: {}", u.pos, u.kind);
1131
1132 // If there is a live range segment with no uses before
1133 // this use, collect that segment for the non-group
1134 // portion.
1135 if u.pos != segment.live_range.from.round_to_prev_inst().inst() {
1136 let (before, after) = segment.split_at(u.pos, self.uses, self.hints);
1137 splitter.segments.push(before);
1138 segment = after;
1139 }
1140
1141 if u.pos.next() == segment.live_range.to.round_to_next_inst().inst() {
1142 // If this use is on the last instruction of the segment
1143 // then split off the rest of the segment into a
1144 // minimal segment.
1145 trace!(
1146 "Generating minimal segment for {} at {}",
1147 segment.value, segment.live_range

Callers 1

split_or_spillMethod · 0.80

Calls 15

group_membersMethod · 0.80
segmentsMethod · 0.80
round_to_prev_instMethod · 0.80
split_atMethod · 0.80
pushMethod · 0.80
round_to_next_instMethod · 0.80
num_virt_regsMethod · 0.80
queue_new_vregsMethod · 0.80
clearMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected