Stackify bugfixes

This commit is contained in:
Chris Fallin 2021-12-15 02:10:59 -08:00
parent ff1398ba73
commit e63bb7a113

View file

@ -72,6 +72,7 @@ impl Shape {
if start >= order.len() { if start >= order.len() {
None None
} else if regions.is_empty() || start < regions[0].start().block { } else if regions.is_empty() || start < regions[0].start().block {
log::trace!(" -> leaf");
Some(( Some((
Shape::Leaf { Shape::Leaf {
block: order[start], block: order[start],
@ -84,7 +85,7 @@ impl Shape {
let end = regions[0].end(); let end = regions[0].end();
let region_end = regions let region_end = regions
.iter() .iter()
.position(|region| region.start() > end) .position(|region| region.start() >= end)
.unwrap_or(regions.len()); .unwrap_or(regions.len());
let subregions = &regions[1..region_end]; let subregions = &regions[1..region_end];
let (children, next_start) = Self::get_shapes(start, end.block, order, subregions); let (children, next_start) = Self::get_shapes(start, end.block, order, subregions);
@ -109,16 +110,24 @@ impl Shape {
order: &[BlockId], order: &[BlockId],
mut regions: &'a [Region], mut regions: &'a [Region],
) -> (Vec<Shape>, OrderedBlockId) { ) -> (Vec<Shape>, OrderedBlockId) {
log::trace!("get_shapes: start {} regions {:?}", start, regions); log::trace!(
"get_shapes: start {} end {} regions {:?}",
start,
end,
regions
);
let mut shapes = vec![]; let mut shapes = vec![];
let mut block = start; let mut block = start;
while block < end { while block < end {
log::trace!("get_shapes: now at {}, regions {:?}", block, regions);
let (shape, next_start, next_regions) = let (shape, next_start, next_regions) =
Self::get_one_shape(block, order, regions).unwrap(); Self::get_one_shape(block, order, regions).unwrap();
shapes.push(shape); shapes.push(shape);
block = next_start; block = next_start;
log::trace!(" -> next_regions = {:?}", next_regions);
regions = next_regions; regions = next_regions;
} }
log::trace!("get_shapes: returning {:?}", shapes);
(shapes, block) (shapes, block)
} }
} }
@ -145,7 +154,7 @@ impl Region {
} }
fn overlaps(&self, other: &Region) -> bool { fn overlaps(&self, other: &Region) -> bool {
self.end() >= other.start() && other.end() >= self.start() self.end() > other.start() && other.end() > self.start()
} }
fn is_forward(&self) -> bool { fn is_forward(&self) -> bool {
@ -303,15 +312,33 @@ impl Shape {
// Fix up contiguous runs of `Forward` regions: when we have // Fix up contiguous runs of `Forward` regions: when we have
// overlap, make them properly nest. We need to scan backward // overlap, make them properly nest. We need to scan backward
// to do this. // to do this.
for i in (0..(regions.len() - 1)).rev() { log::trace!("before forward-edge re-nesting: {:?}", regions);
let a = regions[i]; let mut stack: Vec<usize> = vec![];
let b = regions[i + 1]; for i in (0..regions.len()).rev() {
if a.is_forward() && b.is_forward() && a.overlaps(&b) && !a.contains(&b) { if !regions[i].is_forward() {
assert!(a.start() < b.start()); continue;
assert!(b.start() <= a.end()); }
assert!(a.end() < b.end()); log::trace!("cleaning up forward edges: looking at {:?}", regions[i]);
regions[i] = Region::Forward(a.start().block, b.end().block);
regions[i + 1] = Region::Forward(a.start().block, a.end().block); while let Some(&top_idx) = stack.last() {
if regions[i].end() <= regions[top_idx].start() {
stack.pop();
} else {
break;
}
}
stack.push(i);
for &stack_idx in &stack {
log::trace!(" -> examining against {:?}", regions[stack_idx]);
if regions[i].start() < regions[stack_idx].start() {
let inner =
Region::Forward(regions[i].start().block, regions[stack_idx].end().block);
let outer = Region::Forward(regions[i].start().block, regions[i].end().block);
regions[stack_idx] = outer;
regions[i] = inner;
log::trace!(" -> re-nest");
}
} }
} }