1use rucc_mir::{Block, Func, Reg, Role};
55
56use crate::order::{Order, Point};
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub struct Range {
67 pub start: Point,
69 pub end: Point,
71}
72
73impl Range {
74 #[must_use]
76 pub fn covers(self, point: Point) -> bool {
77 self.start <= point && point <= self.end
78 }
79
80 #[must_use]
82 pub fn overlaps(self, other: Self) -> bool {
83 self.start <= other.end && other.start <= self.end
84 }
85
86 fn with(self, point: Point) -> Self {
89 Self { start: self.start.min(point), end: self.end.max(point) }
90 }
91}
92
93#[derive(Debug, Clone, Copy)]
104pub struct Area<'a> {
105 pieces: &'a [Range],
106 also: Option<Point>,
107}
108
109impl<'a> Area<'a> {
110 #[must_use]
115 pub fn with(self, point: Point) -> Self {
116 Self { also: Some(point), ..self }
117 }
118
119 #[must_use]
122 pub fn hull(self) -> Range {
123 Range { start: self.piece(0).start, end: self.pieces[self.pieces.len() - 1].end }
124 }
125
126 #[must_use]
132 pub fn covers(self, point: Point) -> bool {
133 let first = self.pieces.partition_point(|piece| piece.end < point);
134 first < self.pieces.len() && self.piece(first).covers(point)
135 }
136
137 #[must_use]
142 pub fn overlaps(self, other: Self) -> bool {
143 let (mut mine, mut theirs) = (0, 0);
144 while mine < self.pieces.len() && theirs < other.pieces.len() {
145 let (one, two) = (self.piece(mine), other.piece(theirs));
146 if one.overlaps(two) {
147 return true;
148 }
149 if one.end < two.end {
151 mine += 1;
152 } else {
153 theirs += 1;
154 }
155 }
156 false
157 }
158
159 pub fn pieces(self) -> impl Iterator<Item = Range> + 'a {
161 (0..self.pieces.len()).map(move |piece| self.piece(piece))
162 }
163
164 fn piece(self, index: usize) -> Range {
167 let piece = self.pieces[index];
168 match self.also {
169 Some(also) if also + 1 == piece.start => Range { start: also, end: piece.end },
170 _ => piece,
171 }
172 }
173}
174
175#[derive(Debug, Clone)]
177pub struct Live {
178 live_in: Rows,
179 live_out: Rows,
180 pieces: Vec<Range>,
182 spans: Vec<(usize, usize)>,
184}
185
186impl Live {
187 #[must_use]
189 pub fn of(func: &Func, order: &Order) -> Self {
190 let vregs = func.vregs();
191 let (used, defined) = exposed(func, order);
192 let (live_in, live_out) = flow(func, order, &used, &defined);
193 let (pieces, spans) = carve(func, order, &live_in, &live_out, vregs);
194 Self { live_in, live_out, pieces, spans }
195 }
196
197 #[must_use]
200 pub fn area(&self, reg: Reg) -> Option<Area<'_>> {
201 let pieces = self.pieces(reg);
202 if pieces.is_empty() {
203 return None;
204 }
205 Some(Area { pieces, also: None })
206 }
207
208 #[must_use]
210 pub fn range(&self, reg: Reg) -> Option<Range> {
211 self.area(reg).map(Area::hull)
212 }
213
214 pub fn live_in(&self, block: Block) -> impl Iterator<Item = Reg> + '_ {
219 self.live_in.iter(block.index())
220 }
221
222 pub fn live_out(&self, block: Block) -> impl Iterator<Item = Reg> + '_ {
225 self.live_out.iter(block.index())
226 }
227
228 fn pieces(&self, reg: Reg) -> &[Range] {
230 let number = reg.number().and_then(|number| usize::try_from(number).ok());
231 let Some(&(from, to)) = number.and_then(|number| self.spans.get(number)) else {
232 return &[];
233 };
234 &self.pieces[from..to]
235 }
236}
237
238fn carve(
248 func: &Func,
249 order: &Order,
250 live_in: &Rows,
251 live_out: &Rows,
252 vregs: usize,
253) -> (Vec<Range>, Vec<(usize, usize)>) {
254 let mut found: Vec<(u32, Range)> = Vec::new();
257 let mut last = vec![u32::MAX; vregs];
259 let mut here: Vec<Option<Range>> = vec![None; vregs];
260 let mut touched: Vec<usize> = Vec::new();
261
262 for &block in order.blocks() {
263 for reg in live_in.iter(block.index()) {
266 note(&mut here, &mut touched, reg, order.start(block));
267 }
268 for reg in live_out.iter(block.index()) {
269 note(&mut here, &mut touched, reg, order.end(block));
270 }
271 for param in &func[block].params {
272 note(&mut here, &mut touched, param.reg, order.start(block));
273 }
274 for inst in func.insts(block) {
275 for operand in &func[func[inst].operands] {
276 match operand.role {
277 Role::Use => note(&mut here, &mut touched, operand.reg, order.early(inst)),
278 Role::Def => note(&mut here, &mut touched, operand.reg, order.late(inst)),
279 Role::EarlyDef => {
286 note(&mut here, &mut touched, operand.reg, order.early(inst));
287 note(&mut here, &mut touched, operand.reg, order.late(inst));
288 }
289 }
290 }
291 }
292 for call in &func[block].succs {
293 for &arg in &call.args {
294 note(&mut here, &mut touched, arg, order.end(block));
295 }
296 }
297
298 for &number in &touched {
299 let Some(piece) = here[number].take() else { continue };
300 match found.get_mut(last[number] as usize) {
301 Some((_, previous)) if previous.end + 1 == piece.start => previous.end = piece.end,
305 _ => {
306 last[number] = u32::try_from(found.len()).expect("a piece number");
307 found.push((u32::try_from(number).expect("a register number"), piece));
308 }
309 }
310 }
311 touched.clear();
312 }
313
314 let mut starts = vec![0usize; vregs + 1];
316 for &(number, _) in &found {
317 starts[number as usize + 1] += 1;
318 }
319 for number in 0..vregs {
320 starts[number + 1] += starts[number];
321 }
322 let mut filled = starts.clone();
323 let mut pieces = vec![Range { start: 0, end: 0 }; found.len()];
324 for &(number, piece) in &found {
325 let at = &mut filled[number as usize];
326 pieces[*at] = piece;
327 *at += 1;
328 }
329 let spans = (0..vregs).map(|number| (starts[number], starts[number + 1])).collect();
330 (pieces, spans)
331}
332
333fn note(here: &mut [Option<Range>], touched: &mut Vec<usize>, reg: Reg, point: Point) {
335 let Some(number) = reg.number().and_then(|number| usize::try_from(number).ok()) else {
336 return;
337 };
338 let Some(slot) = here.get_mut(number) else { return };
339 match slot {
340 Some(range) => *range = range.with(point),
341 None => {
342 *slot = Some(Range { start: point, end: point });
343 touched.push(number);
344 }
345 }
346}
347
348fn exposed(func: &Func, order: &Order) -> (Rows, Rows) {
353 let vregs = func.vregs();
354 let mut used = Vec::new();
355 let mut defined = Vec::new();
356 let mut reads = Building::new(vregs);
357 let mut writes = Building::new(vregs);
358 for &block in order.blocks() {
359 let row = block.index();
360 for call in &func[block].succs {
361 for &arg in &call.args {
362 reads.insert(arg);
363 }
364 }
365 let insts: Vec<_> = func.insts(block).collect();
366 for &inst in insts.iter().rev() {
367 let operands = &func[func[inst].operands];
368 for operand in operands.iter().filter(|operand| operand.role.is_def()) {
369 reads.remove(operand.reg);
370 writes.insert(operand.reg);
371 }
372 for operand in operands.iter().filter(|operand| !operand.role.is_def()) {
373 reads.insert(operand.reg);
374 }
375 }
376 for param in &func[block].params {
377 reads.remove(param.reg);
378 writes.insert(param.reg);
379 }
380 used.extend(reads.take().into_iter().map(|number| (row_of(row), number)));
381 defined.extend(writes.take().into_iter().map(|number| (row_of(row), number)));
382 }
383 (Rows::gather(func.block_count(), &used), Rows::gather(func.block_count(), &defined))
384}
385
386fn flow(func: &Func, order: &Order, used: &Rows, defined: &Rows) -> (Rows, Rows) {
400 let count = func.block_count();
401 let vregs = func.vregs();
402 let mut preds: Vec<Vec<usize>> = vec![Vec::new(); count];
403 for &block in order.blocks() {
404 for call in &func[block].succs {
405 preds[call.block.index()].push(block.index());
406 }
407 }
408 let mut starts = vec![0usize; vregs + 1];
410 for &block in order.blocks() {
411 for &number in used.row(block.index()) {
412 starts[number as usize + 1] += 1;
413 }
414 }
415 for number in 0..vregs {
416 starts[number + 1] += starts[number];
417 }
418 let mut readers = vec![0usize; starts[vregs]];
419 let mut filled = starts.clone();
420 for &block in order.blocks() {
421 for &number in used.row(block.index()) {
422 readers[filled[number as usize]] = block.index();
423 filled[number as usize] += 1;
424 }
425 }
426 let mut ends = vec![0usize; vregs + 1];
429 for &block in order.blocks() {
430 for &number in defined.row(block.index()) {
431 ends[number as usize + 1] += 1;
432 }
433 }
434 for number in 0..vregs {
435 ends[number + 1] += ends[number];
436 }
437 let mut writers = vec![0usize; ends[vregs]];
438 let mut filled = ends.clone();
439 for &block in order.blocks() {
440 for &number in defined.row(block.index()) {
441 writers[filled[number as usize]] = block.index();
442 filled[number as usize] += 1;
443 }
444 }
445
446 let mut live_in = Vec::new();
447 let mut live_out = Vec::new();
448 let mut arrived = vec![u32::MAX; count];
451 let mut left = vec![u32::MAX; count];
452 let mut wrote = vec![u32::MAX; count];
453 let mut waiting = Vec::new();
454 for number in 0..vregs {
455 let value = u32::try_from(number).expect("a register number");
456 for &row in &writers[ends[number]..ends[number + 1]] {
457 wrote[row] = value;
458 }
459 for &row in &readers[starts[number]..starts[number + 1]] {
460 if arrived[row] != value {
461 arrived[row] = value;
462 live_in.push((row_of(row), value));
463 waiting.push(row);
464 }
465 }
466 while let Some(row) = waiting.pop() {
467 for &pred in &preds[row] {
468 if left[pred] != value {
469 left[pred] = value;
470 live_out.push((row_of(pred), value));
471 }
472 if arrived[pred] != value && wrote[pred] != value {
473 arrived[pred] = value;
474 live_in.push((row_of(pred), value));
475 waiting.push(pred);
476 }
477 }
478 }
479 }
480 (Rows::transpose(count, &live_in), Rows::transpose(count, &live_out))
481}
482
483#[derive(Debug, Clone)]
503struct Rows {
504 starts: Vec<usize>,
506 numbers: Vec<u32>,
507}
508
509impl Rows {
510 fn gather(rows: usize, pairs: &[(u32, u32)]) -> Self {
516 let (starts, mut filled) = Self::starts(rows, pairs);
517 let mut numbers = vec![0u32; pairs.len()];
518 for &(row, number) in pairs {
519 let at = &mut filled[row as usize];
520 numbers[*at] = number;
521 *at += 1;
522 }
523 Self { starts, numbers }
524 }
525
526 fn transpose(rows: usize, pairs: &[(u32, u32)]) -> Self {
535 let mut shift = 0;
536 while rows > Self::WAYS << shift {
537 shift += 1;
538 }
539 if shift == 0 {
540 return Self::gather(rows, pairs);
541 }
542 let (starts, mut filled) = Self::starts(rows, pairs);
543 let mut next: Vec<usize> =
545 (0..rows.div_ceil(1 << shift)).map(|run| starts[run << shift]).collect();
546 let mut runs = vec![(0u32, 0u32); pairs.len()];
547 for &pair in pairs {
548 let at = &mut next[(pair.0 >> shift) as usize];
549 runs[*at] = pair;
550 *at += 1;
551 }
552 let mut numbers = vec![0u32; pairs.len()];
553 for &(row, number) in &runs {
554 let at = &mut filled[row as usize];
555 numbers[*at] = number;
556 *at += 1;
557 }
558 Self { starts, numbers }
559 }
560
561 const WAYS: usize = 256;
563
564 fn starts(rows: usize, pairs: &[(u32, u32)]) -> (Vec<usize>, Vec<usize>) {
567 let mut starts = vec![0usize; rows + 1];
568 for &(row, _) in pairs {
569 starts[row as usize + 1] += 1;
570 }
571 for row in 0..rows {
572 starts[row + 1] += starts[row];
573 }
574 let filled = starts.clone();
575 (starts, filled)
576 }
577
578 fn row(&self, row: usize) -> &[u32] {
579 &self.numbers[self.starts[row]..self.starts[row + 1]]
580 }
581
582 fn iter(&self, row: usize) -> impl Iterator<Item = Reg> + '_ {
583 self.row(row).iter().copied().map(Reg::virtual_reg)
584 }
585}
586
587fn row_of(index: usize) -> u32 {
589 u32::try_from(index).expect("a block number")
590}
591
592struct Building {
602 flags: Vec<bool>,
603 touched: Vec<u32>,
607}
608
609impl Building {
610 fn new(vregs: usize) -> Self {
611 Self { flags: vec![false; vregs], touched: Vec::new() }
612 }
613
614 fn number(&self, reg: Reg) -> Option<usize> {
618 let number = usize::try_from(reg.number()?).ok()?;
619 (number < self.flags.len()).then_some(number)
620 }
621
622 fn insert(&mut self, reg: Reg) {
623 let Some(number) = self.number(reg) else { return };
624 if !self.flags[number] {
625 self.flags[number] = true;
626 self.touched.push(u32::try_from(number).expect("a register number"));
627 }
628 }
629
630 fn remove(&mut self, reg: Reg) {
631 if let Some(number) = self.number(reg) {
632 self.flags[number] = false;
633 }
634 }
635
636 fn take(&mut self) -> Vec<u32> {
638 let flags = &mut self.flags;
639 let mut out: Vec<u32> = self
640 .touched
641 .drain(..)
642 .filter(|&number| std::mem::replace(&mut flags[number as usize], false))
643 .collect();
644 out.sort_unstable();
645 out
646 }
647}
648
649#[cfg(test)]
650mod tests {
651 use rucc_base::Interner;
652 use rucc_mir::{BlockCall, Constraint, Opcode, Operand};
653 use rucc_target::x86_64::GPR;
654
655 use super::*;
656
657 fn regs(of: impl Iterator<Item = Reg>) -> Vec<u32> {
659 of.filter_map(Reg::number).collect()
660 }
661
662 #[test]
663 fn a_value_is_live_from_where_it_is_written_to_where_it_is_last_read() {
664 let mut names = Interner::new();
665 let mut func = Func::new(names.intern("f"));
666 let opcode = Opcode::new(names.intern("x64.nop"));
667 let block = func.create_block();
668 let value = func.new_vreg(GPR);
669 let other = func.new_vreg(GPR);
670 let write = func.build(block, opcode).def(value, GPR).finish();
671 let idle = func.build(block, opcode).def(other, GPR).finish();
672 let read = func.build(block, opcode).uses(value, GPR).finish();
673
674 let order = Order::of(&func);
675 let live = Live::of(&func, &order);
676 let range = live.range(value).expect("the value is live somewhere");
677 assert_eq!(range, Range { start: order.late(write), end: order.early(read) });
678 assert!(range.covers(order.early(idle)));
679 assert_eq!(
682 live.range(other),
683 Some(Range { start: order.late(idle), end: order.late(idle) })
684 );
685 assert!(!range.overlaps(Range { start: order.late(read), end: order.late(read) }));
686 assert_eq!(regs(live.live_in(block)), Vec::<u32>::new());
687 }
688
689 #[test]
690 fn a_value_read_in_another_block_is_live_between_them() {
691 let mut names = Interner::new();
692 let mut func = Func::new(names.intern("f"));
693 let opcode = Opcode::new(names.intern("x64.nop"));
694 let head = func.create_block();
695 let middle = func.create_block();
696 let tail = func.create_block();
697 let value = func.new_vreg(GPR);
698 func.build(head, opcode).def(value, GPR).finish();
699 *func.succs_mut(head) = vec![BlockCall::to(middle)];
700 *func.succs_mut(middle) = vec![BlockCall::to(tail)];
701 let read = func.build(tail, opcode).uses(value, GPR).finish();
702
703 let order = Order::of(&func);
704 let live = Live::of(&func, &order);
705 assert_eq!(regs(live.live_in(middle)), vec![0]);
708 assert_eq!(regs(live.live_out(middle)), vec![0]);
709 assert!(live.range(value).expect("live somewhere").covers(order.start(middle)));
710 assert_eq!(live.range(value).expect("live somewhere").end, order.early(read));
711 }
712
713 #[test]
714 fn a_block_the_value_never_reaches_is_a_hole_between_two_pieces() {
715 let mut names = Interner::new();
716 let mut func = Func::new(names.intern("f"));
717 let opcode = Opcode::new(names.intern("x64.nop"));
718 let entry = func.create_block();
719 let arm = func.create_block();
720 let tail = func.create_block();
721 let value = func.new_vreg(GPR);
722 let write = func.build(entry, opcode).def(value, GPR).finish();
723 *func.succs_mut(entry) = vec![BlockCall::to(arm), BlockCall::to(tail)];
724 let idle = func.build(arm, opcode).finish();
725 let read = func.build(tail, opcode).uses(value, GPR).finish();
726
727 let order = Order::of(&func);
728 let live = Live::of(&func, &order);
729 let area = live.area(value).expect("live somewhere");
730 assert!(live.range(value).expect("live somewhere").covers(order.early(idle)));
734 assert!(!area.covers(order.early(idle)));
735 assert_eq!(
736 area.pieces().collect::<Vec<_>>(),
737 vec![
738 Range { start: order.late(write), end: order.end(entry) },
739 Range { start: order.start(tail), end: order.early(read) },
740 ]
741 );
742 }
743
744 #[test]
745 fn a_value_in_a_hole_of_another_may_have_its_register() {
746 let mut names = Interner::new();
747 let mut func = Func::new(names.intern("f"));
748 let opcode = Opcode::new(names.intern("x64.nop"));
749 let entry = func.create_block();
750 let arm = func.create_block();
751 let tail = func.create_block();
752 let value = func.new_vreg(GPR);
753 let inside = func.new_vreg(GPR);
754 func.build(entry, opcode).def(value, GPR).finish();
755 *func.succs_mut(entry) = vec![BlockCall::to(arm), BlockCall::to(tail)];
756 func.build(arm, opcode).def(inside, GPR).finish();
757 func.build(arm, opcode).uses(inside, GPR).finish();
758 func.build(tail, opcode).uses(value, GPR).finish();
759
760 let order = Order::of(&func);
761 let live = Live::of(&func, &order);
762 let value = live.area(value).expect("live somewhere");
763 let inside = live.area(inside).expect("live somewhere");
764 assert!(value.hull().overlaps(inside.hull()));
768 assert!(!value.overlaps(inside));
769 assert!(!inside.overlaps(value));
770 }
771
772 #[test]
773 fn one_point_added_in_front_of_a_piece_is_part_of_the_area() {
774 let mut names = Interner::new();
775 let mut func = Func::new(names.intern("f"));
776 let opcode = Opcode::new(names.intern("x64.nop"));
777 let block = func.create_block();
778 let first = func.new_vreg(GPR);
779 let second = func.new_vreg(GPR);
780 let write = func.build(block, opcode).def(first, GPR).finish();
781 let both = func.build(block, opcode).def(second, GPR).uses(first, GPR).finish();
782
783 let order = Order::of(&func);
784 let live = Live::of(&func, &order);
785 let first = live.area(first).expect("live somewhere");
786 let second = live.area(second).expect("live somewhere");
787 assert!(!first.overlaps(second));
792 assert!(first.overlaps(second.with(order.early(both))));
793 assert!(second.with(order.early(both)).covers(order.early(both)));
794 assert_eq!(second.with(order.early(both)).hull().start, order.early(both));
795 assert_eq!(first.hull().start, order.late(write));
796 }
797
798 #[test]
799 fn the_point_added_in_front_joins_the_piece_it_belongs_to_and_not_the_first_one() {
800 let mut names = Interner::new();
801 let mut func = Func::new(names.intern("f"));
802 let nop = Opcode::new(names.intern("x64.nop"));
803 let add = Opcode::new(names.intern("x64.add"));
804 let entry = func.create_block();
805 let head = func.create_block();
806 let arm = func.create_block();
807 let latch = func.create_block();
808 let out = func.create_block();
809 let seed = func.new_vreg(GPR);
810 let sum = func.new_vreg(GPR);
811 let inside = func.new_vreg(GPR);
812 let loaded = func.new_vreg(GPR);
813 func.build(entry, nop).def(seed, GPR).finish();
814 func.build(entry, nop).def(sum, GPR).finish();
815 *func.succs_mut(entry) = vec![BlockCall::to(head)];
816 func.build(head, nop).uses(sum, GPR).finish();
817 *func.succs_mut(head) = vec![BlockCall::to(arm), BlockCall::to(latch)];
818 func.build(arm, nop).def(inside, GPR).finish();
819 func.build(arm, nop).uses(inside, GPR).finish();
820 *func.succs_mut(arm) = vec![BlockCall::to(out)];
821 func.build(latch, nop).def(loaded, GPR).finish();
822 let carry = func
823 .build(latch, add)
824 .operand(Operand::write(sum, GPR).with(Constraint::Reuse(1)))
825 .uses(seed, GPR)
826 .uses(loaded, GPR)
827 .finish();
828 *func.succs_mut(latch) = vec![BlockCall::to(head), BlockCall::to(out)];
829
830 let order = Order::of(&func);
831 let live = Live::of(&func, &order);
832 let sum = live.area(sum).expect("live somewhere");
833 let loaded = live.area(loaded).expect("live somewhere");
834 assert_eq!(sum.pieces().count(), 2);
839 assert!(!sum.covers(order.early(carry)));
840 assert!(sum.with(order.early(carry)).covers(order.early(carry)));
841 assert!(!loaded.overlaps(sum));
842 assert!(loaded.overlaps(sum.with(order.early(carry))));
843 }
844
845 #[test]
846 fn a_value_carried_round_a_loop_is_live_round_all_of_it() {
847 let mut names = Interner::new();
848 let mut func = Func::new(names.intern("f"));
849 let opcode = Opcode::new(names.intern("x64.nop"));
850 let header = func.create_block();
851 let body = func.create_block();
852 let carried = func.append_param(header, GPR);
853 let next = func.new_vreg(GPR);
854 *func.succs_mut(header) = vec![BlockCall::to(body)];
855 func.build(body, opcode).def(next, GPR).uses(carried, GPR).finish();
856 *func.succs_mut(body) = vec![BlockCall::with(header, vec![next])];
857
858 let order = Order::of(&func);
859 let live = Live::of(&func, &order);
860 assert_eq!(regs(live.live_in(header)), Vec::<u32>::new());
863 assert_eq!(regs(live.live_in(body)), vec![carried.number().expect("virtual")]);
864 let range = live.range(next).expect("live somewhere");
865 assert_eq!(range.end, order.end(body));
866 }
867
868 #[test]
869 fn two_values_that_are_never_both_wanted_do_not_overlap() {
870 let mut names = Interner::new();
871 let mut func = Func::new(names.intern("f"));
872 let opcode = Opcode::new(names.intern("x64.nop"));
873 let block = func.create_block();
874 let first = func.new_vreg(GPR);
875 let second = func.new_vreg(GPR);
876 let write = func.build(block, opcode).def(first, GPR).finish();
877 func.build(block, opcode).def(second, GPR).uses(first, GPR).finish();
878
879 let order = Order::of(&func);
880 let live = Live::of(&func, &order);
881 let first = live.range(first).expect("live somewhere");
882 let second = live.range(second).expect("live somewhere");
883 assert!(!first.overlaps(second));
887 assert!(first.start > order.start(block));
888 assert_eq!(first.start, order.late(write));
889 }
890
891 #[test]
892 fn an_operand_written_early_is_wanted_where_the_operands_are_read() {
893 let mut names = Interner::new();
894 let mut func = Func::new(names.intern("f"));
895 let opcode = Opcode::new(names.intern("x64.nop"));
896 let block = func.create_block();
897 let source = func.new_vreg(GPR);
898 let early = func.new_vreg(GPR);
899 func.build(block, opcode).def(source, GPR).finish();
900 func.build(block, opcode)
901 .operand(Operand::write_early(early, GPR))
902 .operand(Operand::read(source, GPR))
903 .finish();
904
905 let order = Order::of(&func);
906 let live = Live::of(&func, &order);
907 let source = live.range(source).expect("live somewhere");
908 let early = live.range(early).expect("live somewhere");
909 assert!(source.overlaps(early));
912 }
913
914 #[test]
915 fn a_register_a_memory_operand_names_is_read_like_any_other() {
916 use rucc_mir::Mem;
917
918 let mut names = Interner::new();
919 let mut func = Func::new(names.intern("f"));
920 let opcode = Opcode::new(names.intern("x64.nop"));
921 let block = func.create_block();
922 let address = func.new_vreg(GPR);
923 let write = func.build(block, opcode).def(address, GPR).finish();
924 let load = func.build(block, opcode).mem(Mem::at(Operand::read(address, GPR))).finish();
925
926 let order = Order::of(&func);
927 let live = Live::of(&func, &order);
928 assert_eq!(
929 live.range(address),
930 Some(Range { start: order.late(write), end: order.early(load) })
931 );
932 }
933
934 #[test]
935 fn rows_from_a_list_a_value_at_a_time_over_many_blocks_keep_the_order_the_numbers_came_in() {
936 let rows = 3000;
939 let mut pairs = Vec::new();
940 let mut seed = 7u32;
941 for number in 0..400 {
942 for _ in 0..30 {
943 seed = seed.wrapping_mul(1_103_515_245).wrapping_add(12345);
944 pairs.push(((seed >> 8) % 3000, number));
945 }
946 }
947 let gathered = Rows::transpose(rows, &pairs);
948 for row in 0..rows {
949 let wanted: Vec<u32> = pairs
950 .iter()
951 .filter(|&&(at, _)| at as usize == row)
952 .map(|&(_, number)| number)
953 .collect();
954 assert_eq!(gathered.row(row), wanted, "row {row}");
955 }
956 }
957}