Skip to content

Commit ddeb787

Browse files
committed
Constrain iteration of registers with a Limit
During allocation, we iterate over the available registers and pick one within all the constraints (i.e., fixed, hints, preferred/non-preferred lists). This adds a limit to all of those constraints: unless the register is fixed, we only pick a register with a HW encoding below the limit, if one is given.
1 parent f58fdef commit ddeb787

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

src/ion/moves.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,8 +892,14 @@ impl<'a, F: Function> Env<'a, F> {
892892
}
893893

894894
let resolved = parallel_moves.resolve();
895-
let mut scratch_iter =
896-
RegTraversalIter::new(self.env, regclass, None, PReg::invalid(), 0);
895+
let mut scratch_iter = RegTraversalIter::new(
896+
self.env,
897+
regclass,
898+
None,
899+
PReg::invalid(),
900+
0,
901+
None, // We assume there is no limit on registers available for moves.
902+
);
897903
let mut dedicated_scratch = self.env.scratch_by_class[regclass as usize];
898904
let key = LiveRangeKey::from_range(&CodeRange {
899905
from: pos_prio.pos,

src/ion/process.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,10 @@ impl<'a, F: Function> Env<'a, F> {
10781078
+ bundle.index();
10791079

10801080
self.ctx.output.stats.process_bundle_reg_probe_start_any += 1;
1081-
for preg in RegTraversalIter::new(self.env, class, fixed_preg, hint_reg, scan_offset) {
1081+
let limit = self.bundles[bundle].limit;
1082+
for preg in
1083+
RegTraversalIter::new(self.env, class, fixed_preg, hint_reg, scan_offset, limit)
1084+
{
10821085
self.ctx.output.stats.process_bundle_reg_probes_any += 1;
10831086
let preg_idx = PRegIndex::new(preg.index());
10841087
trace!("trying preg {:?}", preg_idx);

src/ion/reg_traversal.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub struct RegTraversalIter<'a> {
7272
hint: Option<PReg>,
7373
preferred: Cursor<'a>,
7474
non_preferred: Cursor<'a>,
75+
limit: Option<usize>,
7576
}
7677

7778
impl<'a> RegTraversalIter<'a> {
@@ -81,6 +82,7 @@ impl<'a> RegTraversalIter<'a> {
8182
fixed: Option<PReg>,
8283
hint: PReg,
8384
offset: usize,
85+
limit: Option<usize>,
8486
) -> Self {
8587
let hint = if hint != PReg::invalid() {
8688
Some(hint)
@@ -99,6 +101,7 @@ impl<'a> RegTraversalIter<'a> {
99101
hint,
100102
preferred,
101103
non_preferred,
104+
limit,
102105
}
103106
}
104107
}
@@ -113,21 +116,23 @@ impl<'a> core::iter::Iterator for RegTraversalIter<'a> {
113116

114117
if self.use_hint {
115118
self.use_hint = false;
116-
return self.hint;
119+
if self.hint.unwrap().hw_enc() < self.limit.unwrap_or(usize::MAX) {
120+
return self.hint;
121+
}
117122
}
118123

119124
while !self.preferred.done() {
120125
let reg = self.preferred.advance();
121-
if Some(reg) == self.hint {
122-
continue; // Try again; we already tried the hint.
126+
if Some(reg) == self.hint || reg.hw_enc() >= self.limit.unwrap_or(usize::MAX) {
127+
continue; // Try again; we already tried the hint or we are outside of the register range limit.
123128
}
124129
return Some(reg);
125130
}
126131

127132
while !self.non_preferred.done() {
128133
let reg = self.non_preferred.advance();
129-
if Some(reg) == self.hint {
130-
continue; // Try again; we already tried the hint.
134+
if Some(reg) == self.hint || reg.hw_enc() >= self.limit.unwrap_or(usize::MAX) {
135+
continue; // Try again; we already tried the hint or we are outside of the register range limit.
131136
}
132137
return Some(reg);
133138
}

src/ion/spill.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ impl<'a, F: Function> Env<'a, F> {
4040

4141
let mut success = false;
4242
self.ctx.output.stats.spill_bundle_reg_probes += 1;
43-
for preg in RegTraversalIter::new(self.env, class, None, hint, bundle.index()) {
43+
let limit = self.bundles[bundle].limit;
44+
for preg in RegTraversalIter::new(self.env, class, None, hint, bundle.index(), limit) {
4445
trace!("trying bundle {:?} to preg {:?}", bundle, preg);
4546
let preg_idx = PRegIndex::new(preg.index());
4647
if let AllocRegResult::Allocated(_) =
@@ -51,6 +52,7 @@ impl<'a, F: Function> Env<'a, F> {
5152
break;
5253
}
5354
}
55+
5456
if !success {
5557
trace!(
5658
"spilling bundle {:?}: marking spillset {:?} as required",

0 commit comments

Comments
 (0)