Skip to content

Commit 17d2b22

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 effa5d1 commit 17d2b22

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

src/ion/moves.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,10 @@ impl<'a, F: Function> Env<'a, F> {
892892
}
893893

894894
let resolved = parallel_moves.resolve();
895-
let mut scratch_iter = RegTraversalIter::new(self.env, regclass, None, None, 0);
895+
let mut scratch_iter = RegTraversalIter::new(
896+
self.env, regclass, None, None, 0,
897+
None, // We assume there is no limit on the set of registers available for moves.
898+
);
896899
let mut dedicated_scratch = self.env.scratch_by_class[regclass as usize];
897900
let key = LiveRangeKey::from_range(&CodeRange {
898901
from: pos_prio.pos,

src/ion/process.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,9 +1072,15 @@ impl<'a, F: Function> Env<'a, F> {
10721072
+ bundle.index();
10731073

10741074
self.ctx.output.stats.process_bundle_reg_probe_start_any += 1;
1075-
for preg in
1076-
RegTraversalIter::new(self.env, class, fixed_preg, hint.as_valid(), scan_offset)
1077-
{
1075+
let limit = self.bundles[bundle].limit;
1076+
for preg in RegTraversalIter::new(
1077+
self.env,
1078+
class,
1079+
fixed_preg,
1080+
hint.as_valid(),
1081+
scan_offset,
1082+
limit,
1083+
) {
10781084
self.ctx.output.stats.process_bundle_reg_probes_any += 1;
10791085
let preg_idx = PRegIndex::new(preg.index());
10801086
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: Option<PReg>,
8384
offset: usize,
85+
limit: Option<usize>,
8486
) -> Self {
8587
debug_assert!(fixed != Some(PReg::invalid()));
8688
debug_assert!(hint != Some(PReg::invalid()));
@@ -96,6 +98,7 @@ impl<'a> RegTraversalIter<'a> {
9698
hint,
9799
preferred,
98100
non_preferred,
101+
limit,
99102
}
100103
}
101104
}
@@ -110,21 +113,23 @@ impl<'a> core::iter::Iterator for RegTraversalIter<'a> {
110113

111114
if self.use_hint {
112115
self.use_hint = false;
113-
return self.hint;
116+
if self.hint.unwrap().hw_enc() < self.limit.unwrap_or(usize::MAX) {
117+
return self.hint;
118+
}
114119
}
115120

116121
while !self.preferred.done() {
117122
let reg = self.preferred.advance();
118-
if Some(reg) == self.hint {
119-
continue; // Try again; we already tried the hint.
123+
if Some(reg) == self.hint || reg.hw_enc() >= self.limit.unwrap_or(usize::MAX) {
124+
continue; // Try again; we already tried the hint or we are outside of the register range limit.
120125
}
121126
return Some(reg);
122127
}
123128

124129
while !self.non_preferred.done() {
125130
let reg = self.non_preferred.advance();
126-
if Some(reg) == self.hint {
127-
continue; // Try again; we already tried the hint.
131+
if Some(reg) == self.hint || reg.hw_enc() >= self.limit.unwrap_or(usize::MAX) {
132+
continue; // Try again; we already tried the hint or we are outside of the register range limit.
128133
}
129134
return Some(reg);
130135
}

src/ion/spill.rs

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

4343
let mut success = false;
4444
self.ctx.output.stats.spill_bundle_reg_probes += 1;
45-
for preg in RegTraversalIter::new(self.env, class, None, hint, bundle.index()) {
45+
let limit = self.bundles[bundle].limit;
46+
for preg in RegTraversalIter::new(self.env, class, None, hint, bundle.index(), limit) {
4647
trace!("trying bundle {:?} to preg {:?}", bundle, preg);
4748
let preg_idx = PRegIndex::new(preg.index());
4849
if let AllocRegResult::Allocated(_) =
@@ -53,6 +54,7 @@ impl<'a, F: Function> Env<'a, F> {
5354
break;
5455
}
5556
}
57+
5658
if !success {
5759
trace!(
5860
"spilling bundle {:?}: marking spillset {:?} as required",

0 commit comments

Comments
 (0)