1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use crate::macros::codegen_assert::CODEGEN_ASSERT;
use crate::records::const_prop_state::ConstPropState;
use crate::records::numbered_instruction::NumberedInstruction;
impl ConstPropState {
pub fn get_max_internal_overlap(
&mut self,
set: &mut Vec<NumberedInstruction>,
slot: usize,
) -> i32 {
// Start with one live range for the slot we want to reuse
let mut curr = 1;
// For any slots where lifetime began before the slot of interest, mark as live if lifetime end is still active
// This saves us from processing slots [0; slot] in the range sweep later, which requires sorting the lifetime end points
for i in 0..slot {
if set[i].finish_pos >= set[slot].start_pos {
curr += 1;
}
}
let mut max = curr;
// Collect lifetime end points and sort them
self.range_end_temp.clear();
for i in (slot + 1)..set.len() {
self.range_end_temp.push(set[i].finish_pos);
}
self.range_end_temp.sort_unstable();
// Go over the lifetime begin/end ranges that we store as separate array and walk based on the smallest of values
let mut i1 = (slot + 1) as usize;
let mut i2 = 0usize;
while i1 < set.len() && i2 < self.range_end_temp.len() {
if self.range_end_temp[i2] == set[i1].start_pos {
i1 += 1;
i2 += 1;
} else if self.range_end_temp[i2] < set[i1].start_pos {
CODEGEN_ASSERT!(curr > 0);
curr -= 1;
i2 += 1;
} else {
curr += 1;
i1 += 1;
if curr > max {
max = curr;
}
}
}
// We might have unprocessed lifetime end entries, but we will never have unprocessed lifetime start entries
// Not that lifetime end entries can only decrease the current value and do not affect the end result (maximum)
max
}
}