Stackify bugfixes
This commit is contained in:
parent
ff1398ba73
commit
e63bb7a113
|
@ -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 = ®ions[1..region_end];
|
let subregions = ®ions[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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue