Skip to content

Commit 6d502ba

Browse files
committed
move assigned to the interval rather than using a parallel array
1 parent 690f779 commit 6d502ba

1 file changed

Lines changed: 30 additions & 21 deletions

File tree

zjit/src/backend/lir.rs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,7 @@ pub struct Interval {
13861386
pub ranges: Vec<LiveRange>,
13871387
pub id: VRegId,
13881388
pub state: State,
1389+
pub assigned: Option<Allocation>,
13891390
}
13901391

13911392
impl Interval {
@@ -1395,6 +1396,7 @@ impl Interval {
13951396
ranges: vec![],
13961397
id: i,
13971398
state: State::Unhandled,
1399+
assigned: None,
13981400
}
13991401
}
14001402

@@ -2149,25 +2151,25 @@ impl Assembler
21492151

21502152
let mut free_registers: BTreeSet<usize> = (0..num_registers).collect();
21512153
let mut active: Vec<Interval> = Vec::new(); // sorted by increasing end point
2152-
let mut assignment: Vec<Option<Allocation>> = vec![None; intervals.len()];
21532154
let mut num_stack_slots: usize = 0;
21542155

2155-
// Collect vreg indices that have valid ranges, sorted by start point
2156-
let mut sorted_intervals: Vec<Interval> = intervals.iter()
2156+
let mut handled: Vec<Interval> = Vec::new();
2157+
let num_intervals = intervals.len();
2158+
2159+
let mut sorted_intervals: Vec<Interval> = intervals.into_iter()
21572160
.filter(|i| i.has_bounds())
2158-
.cloned()
21592161
.collect();
21602162
sorted_intervals.sort_by_key(|i| i.start());
21612163

21622164
let mut unhandled: VecDeque<Interval> = sorted_intervals.into();
21632165

2164-
while let Some(interval) = unhandled.pop_front() {
2165-
// Expire old intervals
2166-
active.retain(|active_interval| {
2167-
if active_interval.end() > interval.start() {
2168-
true
2166+
while let Some(mut interval) = unhandled.pop_front() {
2167+
// Expire old intervals.
2168+
for it in std::mem::take(&mut active) {
2169+
if it.end() > interval.start() {
2170+
active.push(it);
21692171
} else {
2170-
if let Some(allocation) = assignment[active_interval.id] {
2172+
if let Some(allocation) = it.assigned {
21712173
if let Some(reg) = allocation.alloc_pool_index(num_registers) {
21722174
let was_not_there_before = free_registers.insert(reg);
21732175
assert!(
@@ -2188,14 +2190,14 @@ impl Assembler
21882190
);
21892191
}
21902192
}
2191-
false
2193+
handled.push(it);
21922194
}
2193-
});
2195+
}
21942196

21952197
let preferred_reg = preferred_registers[interval.id];
21962198
let preferred_taken = preferred_reg.is_some_and(|reg| {
21972199
active.iter().any(|active_interval| {
2198-
assignment[active_interval.id]
2200+
active_interval.assigned
21992201
.and_then(|alloc| alloc.assigned_reg())
22002202
.is_some_and(|active_reg| active_reg.reg_no == reg.reg_no)
22012203
})
@@ -2204,13 +2206,13 @@ impl Assembler
22042206
if let Some(preferred_reg) = preferred_reg.filter(|_| !preferred_taken) {
22052207
if let Some(reg_idx) = Allocation::Fixed(preferred_reg).alloc_pool_index(num_registers) {
22062208
if free_registers.remove(&reg_idx) {
2207-
assignment[interval.id] = Some(Allocation::Fixed(preferred_reg));
2209+
interval.assigned = Some(Allocation::Fixed(preferred_reg));
22082210
let insert_idx = active.partition_point(|i| i.end() < interval.end());
22092211
active.insert(insert_idx, interval);
22102212
continue;
22112213
}
22122214
} else {
2213-
assignment[interval.id] = Some(Allocation::Fixed(preferred_reg));
2215+
interval.assigned = Some(Allocation::Fixed(preferred_reg));
22142216
let insert_idx = active.partition_point(|i| i.end() < interval.end());
22152217
active.insert(insert_idx, interval);
22162218
continue;
@@ -2226,36 +2228,43 @@ impl Assembler
22262228
// can be mutated below.
22272229
let spill = active.iter().rev()
22282230
.find(|active_interval| {
2229-
matches!(assignment[active_interval.id], Some(Allocation::Reg(_)))
2231+
matches!(active_interval.assigned, Some(Allocation::Reg(_)))
22302232
})
22312233
.map(|active_interval| (active_interval.id, active_interval.end()));
22322234
let slot = Allocation::Stack(num_stack_slots);
22332235
num_stack_slots += 1;
22342236

22352237
if let Some((spill_id, _)) = spill.filter(|&(_, spill_end)| spill_end > interval.end()) {
22362238
// Spill the last active interval; give its register to current
2237-
assignment[interval.id] = assignment[spill_id];
2238-
assignment[spill_id] = Some(slot);
22392239
let spill_idx = active.iter().position(|active_interval| active_interval.id == spill_id).unwrap();
2240-
active.remove(spill_idx);
2240+
let mut spilled = active.remove(spill_idx);
2241+
interval.assigned = spilled.assigned;
2242+
spilled.assigned = Some(slot);
2243+
handled.push(spilled);
22412244
// Insert current into sorted active
22422245
let insert_idx = active.partition_point(|i| i.end() < interval.end());
22432246
active.insert(insert_idx, interval);
22442247
} else {
22452248
// Spill the current interval
2246-
assignment[interval.id] = Some(slot);
2249+
interval.assigned = Some(slot);
2250+
handled.push(interval);
22472251
}
22482252
} else {
22492253
// Allocate lowest free register
22502254
let reg = *free_registers.iter().min().unwrap();
22512255
free_registers.remove(&reg);
2252-
assignment[interval.id] = Some(Allocation::Reg(reg));
2256+
interval.assigned = Some(Allocation::Reg(reg));
22532257
// Insert into sorted active
22542258
let insert_idx = active.partition_point(|i| i.end() < interval.end());
22552259
active.insert(insert_idx, interval);
22562260
}
22572261
}
22582262

2263+
let mut assignment: Vec<Option<Allocation>> = vec![None; num_intervals];
2264+
for it in active.into_iter().chain(handled) {
2265+
assignment[it.id] = it.assigned;
2266+
}
2267+
22592268
(assignment, num_stack_slots)
22602269
}
22612270

0 commit comments

Comments
 (0)