More layout tests and bugfixes.
Fix bugs in append methods. Linked lists are hard.
This commit is contained in:
@@ -67,14 +67,18 @@ impl Layout {
|
|||||||
pub fn append_ebb(&mut self, ebb: Ebb) {
|
pub fn append_ebb(&mut self, ebb: Ebb) {
|
||||||
assert!(!self.is_ebb_inserted(ebb),
|
assert!(!self.is_ebb_inserted(ebb),
|
||||||
"Cannot append EBB that is already in the layout");
|
"Cannot append EBB that is already in the layout");
|
||||||
|
{
|
||||||
let node = &mut self.ebbs[ebb];
|
let node = &mut self.ebbs[ebb];
|
||||||
assert!(node.first_inst == NO_INST && node.last_inst == NO_INST);
|
assert!(node.first_inst == NO_INST && node.last_inst == NO_INST);
|
||||||
node.prev = self.last_ebb.unwrap_or_default();
|
node.prev = self.last_ebb.unwrap_or_default();
|
||||||
node.next = NO_EBB;
|
node.next = NO_EBB;
|
||||||
self.last_ebb = Some(ebb);
|
}
|
||||||
if self.first_ebb.is_none() {
|
if let Some(last) = self.last_ebb {
|
||||||
|
self.ebbs[last].next = ebb;
|
||||||
|
} else {
|
||||||
self.first_ebb = Some(ebb);
|
self.first_ebb = Some(ebb);
|
||||||
}
|
}
|
||||||
|
self.last_ebb = Some(ebb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert `ebb` in the layout before the existing EBB `before`.
|
/// Insert `ebb` in the layout before the existing EBB `before`.
|
||||||
@@ -151,13 +155,18 @@ impl Layout {
|
|||||||
assert!(self.is_ebb_inserted(ebb),
|
assert!(self.is_ebb_inserted(ebb),
|
||||||
"Cannot append instructions to EBB not in layout");
|
"Cannot append instructions to EBB not in layout");
|
||||||
let ebb_node = &mut self.ebbs[ebb];
|
let ebb_node = &mut self.ebbs[ebb];
|
||||||
|
{
|
||||||
let inst_node = &mut self.insts[inst];
|
let inst_node = &mut self.insts[inst];
|
||||||
inst_node.ebb = ebb;
|
inst_node.ebb = ebb;
|
||||||
inst_node.prev = ebb_node.last_inst;
|
inst_node.prev = ebb_node.last_inst;
|
||||||
assert_eq!(inst_node.next, NO_INST);
|
assert_eq!(inst_node.next, NO_INST);
|
||||||
|
}
|
||||||
if ebb_node.first_inst == NO_INST {
|
if ebb_node.first_inst == NO_INST {
|
||||||
ebb_node.first_inst = inst;
|
ebb_node.first_inst = inst;
|
||||||
|
} else {
|
||||||
|
self.insts[ebb_node.last_inst].next = inst;
|
||||||
}
|
}
|
||||||
|
ebb_node.last_inst = inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert `inst` before the instruction `before` in the same EBB.
|
/// Insert `inst` before the instruction `before` in the same EBB.
|
||||||
@@ -222,6 +231,44 @@ mod tests {
|
|||||||
use entity_map::EntityRef;
|
use entity_map::EntityRef;
|
||||||
use entities::{Ebb, Inst};
|
use entities::{Ebb, Inst};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn append_ebb() {
|
||||||
|
let mut layout = Layout::new();
|
||||||
|
let e0 = Ebb::new(0);
|
||||||
|
let e1 = Ebb::new(1);
|
||||||
|
let e2 = Ebb::new(2);
|
||||||
|
|
||||||
|
{
|
||||||
|
let imm = &layout;
|
||||||
|
assert!(!imm.is_ebb_inserted(e0));
|
||||||
|
assert!(!imm.is_ebb_inserted(e1));
|
||||||
|
|
||||||
|
let v: Vec<Ebb> = layout.ebbs().collect();
|
||||||
|
assert_eq!(v, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.append_ebb(e1);
|
||||||
|
assert!(!layout.is_ebb_inserted(e0));
|
||||||
|
assert!(layout.is_ebb_inserted(e1));
|
||||||
|
assert!(!layout.is_ebb_inserted(e2));
|
||||||
|
let v: Vec<Ebb> = layout.ebbs().collect();
|
||||||
|
assert_eq!(v, [e1]);
|
||||||
|
|
||||||
|
layout.append_ebb(e2);
|
||||||
|
assert!(!layout.is_ebb_inserted(e0));
|
||||||
|
assert!(layout.is_ebb_inserted(e1));
|
||||||
|
assert!(layout.is_ebb_inserted(e2));
|
||||||
|
let v: Vec<Ebb> = layout.ebbs().collect();
|
||||||
|
assert_eq!(v, [e1, e2]);
|
||||||
|
|
||||||
|
layout.append_ebb(e0);
|
||||||
|
assert!(layout.is_ebb_inserted(e0));
|
||||||
|
assert!(layout.is_ebb_inserted(e1));
|
||||||
|
assert!(layout.is_ebb_inserted(e2));
|
||||||
|
let v: Vec<Ebb> = layout.ebbs().collect();
|
||||||
|
assert_eq!(v, [e1, e2, e0]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_ebb() {
|
fn insert_ebb() {
|
||||||
let mut layout = Layout::new();
|
let mut layout = Layout::new();
|
||||||
@@ -260,6 +307,45 @@ mod tests {
|
|||||||
assert_eq!(v, [e2, e0, e1]);
|
assert_eq!(v, [e2, e0, e1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn append_inst() {
|
||||||
|
let mut layout = Layout::new();
|
||||||
|
let e1 = Ebb::new(1);
|
||||||
|
|
||||||
|
layout.append_ebb(e1);
|
||||||
|
let v: Vec<Inst> = layout.ebb_insts(e1).collect();
|
||||||
|
assert_eq!(v, []);
|
||||||
|
|
||||||
|
let i0 = Inst::new(0);
|
||||||
|
let i1 = Inst::new(1);
|
||||||
|
let i2 = Inst::new(2);
|
||||||
|
|
||||||
|
assert_eq!(layout.inst_ebb(i0), None);
|
||||||
|
assert_eq!(layout.inst_ebb(i1), None);
|
||||||
|
assert_eq!(layout.inst_ebb(i2), None);
|
||||||
|
|
||||||
|
layout.append_inst(i1, e1);
|
||||||
|
assert_eq!(layout.inst_ebb(i0), None);
|
||||||
|
assert_eq!(layout.inst_ebb(i1), Some(e1));
|
||||||
|
assert_eq!(layout.inst_ebb(i2), None);
|
||||||
|
let v: Vec<Inst> = layout.ebb_insts(e1).collect();
|
||||||
|
assert_eq!(v, [i1]);
|
||||||
|
|
||||||
|
layout.append_inst(i2, e1);
|
||||||
|
assert_eq!(layout.inst_ebb(i0), None);
|
||||||
|
assert_eq!(layout.inst_ebb(i1), Some(e1));
|
||||||
|
assert_eq!(layout.inst_ebb(i2), Some(e1));
|
||||||
|
let v: Vec<Inst> = layout.ebb_insts(e1).collect();
|
||||||
|
assert_eq!(v, [i1, i2]);
|
||||||
|
|
||||||
|
layout.append_inst(i0, e1);
|
||||||
|
assert_eq!(layout.inst_ebb(i0), Some(e1));
|
||||||
|
assert_eq!(layout.inst_ebb(i1), Some(e1));
|
||||||
|
assert_eq!(layout.inst_ebb(i2), Some(e1));
|
||||||
|
let v: Vec<Inst> = layout.ebb_insts(e1).collect();
|
||||||
|
assert_eq!(v, [i1, i2, i0]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_inst() {
|
fn insert_inst() {
|
||||||
let mut layout = Layout::new();
|
let mut layout = Layout::new();
|
||||||
@@ -298,4 +384,30 @@ mod tests {
|
|||||||
let v: Vec<Inst> = layout.ebb_insts(e1).collect();
|
let v: Vec<Inst> = layout.ebb_insts(e1).collect();
|
||||||
assert_eq!(v, [i2, i0, i1]);
|
assert_eq!(v, [i2, i0, i1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_ebbs() {
|
||||||
|
let mut layout = Layout::new();
|
||||||
|
|
||||||
|
let e0 = Ebb::new(0);
|
||||||
|
let e1 = Ebb::new(1);
|
||||||
|
|
||||||
|
layout.append_ebb(e0);
|
||||||
|
layout.append_ebb(e1);
|
||||||
|
|
||||||
|
let i0 = Inst::new(0);
|
||||||
|
let i1 = Inst::new(1);
|
||||||
|
let i2 = Inst::new(2);
|
||||||
|
let i3 = Inst::new(3);
|
||||||
|
|
||||||
|
layout.append_inst(i0, e0);
|
||||||
|
layout.append_inst(i1, e0);
|
||||||
|
layout.append_inst(i2, e1);
|
||||||
|
layout.append_inst(i3, e1);
|
||||||
|
|
||||||
|
let v0: Vec<Inst> = layout.ebb_insts(e0).collect();
|
||||||
|
let v1: Vec<Inst> = layout.ebb_insts(e1).collect();
|
||||||
|
assert_eq!(v0, [i0, i1]);
|
||||||
|
assert_eq!(v1, [i2, i3]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user