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