fix stackifier
This commit is contained in:
parent
ca0570c0d0
commit
c79e6aab05
|
@ -25,6 +25,11 @@ enum Region {
|
||||||
/// end (after terminator) of second block. Can be extended past
|
/// end (after terminator) of second block. Can be extended past
|
||||||
/// the end if needed.
|
/// the end if needed.
|
||||||
Backward(OrderedBlockId, OrderedBlockId),
|
Backward(OrderedBlockId, OrderedBlockId),
|
||||||
|
|
||||||
|
// TODO: support irreducible CFGs by adding a `BackwardDispatch`
|
||||||
|
// region kind whose start is adjusted back to the first loop
|
||||||
|
// block. BackwardDispatch is contagious, i.e. converts adjacent
|
||||||
|
// Backward region records to BackwardDispatch.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
@ -123,25 +128,34 @@ impl Shape {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match (prev, this) {
|
// Important invariant: none of these merging/extension
|
||||||
|
// operations alter the sorted order, because at worst
|
||||||
|
// they "pull back" the start of the second region
|
||||||
|
// (`this`) to the start of the first (`prev`). If the
|
||||||
|
// list was sorted by region-start before, it will be
|
||||||
|
// after this edit.
|
||||||
|
let did_edit = match (prev, this) {
|
||||||
(a, b) if a == b => {
|
(a, b) if a == b => {
|
||||||
regions.remove(i);
|
regions.remove(i);
|
||||||
i -= 1;
|
true
|
||||||
}
|
}
|
||||||
(Region::Backward(a, b), Region::Backward(c, d)) if a == c => {
|
(Region::Backward(a, b), Region::Backward(c, d)) if a == c => {
|
||||||
// Merge by extending end.
|
// Merge by extending end.
|
||||||
regions[i - 1] = Region::Backward(a, std::cmp::max(b, d));
|
regions[i - 1] = Region::Backward(a, std::cmp::max(b, d));
|
||||||
regions.remove(i);
|
regions.remove(i);
|
||||||
i -= 1;
|
true
|
||||||
}
|
}
|
||||||
(Region::Backward(a, b), Region::Backward(c, _d)) if a < c && c <= b => {
|
(Region::Backward(a, b), Region::Backward(c, d)) if a < c && c <= b && b < d => {
|
||||||
panic!("Irreducible CFG");
|
// Extend outer Backward to nest the inner one.
|
||||||
|
regions[i - 1] = Region::Backward(a, d);
|
||||||
|
true
|
||||||
}
|
}
|
||||||
(Region::Backward(a, b), Region::Forward(c, d)) if a <= c && c <= b => {
|
(Region::Backward(a, b), Region::Forward(c, d)) if a <= c && c <= b => {
|
||||||
// Put the Forward before the Backward (extend its
|
// Put the Forward before the Backward (extend its
|
||||||
// start) to ensure proper nesting.
|
// start) to ensure proper nesting.
|
||||||
regions[i - 1] = Region::Forward(a, d);
|
regions[i - 1] = Region::Forward(a, d);
|
||||||
regions[i] = Region::Backward(a, b);
|
regions[i] = Region::Backward(a, b);
|
||||||
|
true
|
||||||
}
|
}
|
||||||
(Region::Forward(_a, b), Region::Backward(c, d)) if b > c && b <= d => {
|
(Region::Forward(_a, b), Region::Backward(c, d)) if b > c && b <= d => {
|
||||||
panic!("Irreducible CFG");
|
panic!("Irreducible CFG");
|
||||||
|
@ -150,13 +164,20 @@ impl Shape {
|
||||||
// Merge.
|
// Merge.
|
||||||
regions[i - 1] = Region::Forward(std::cmp::min(a, c), b);
|
regions[i - 1] = Region::Forward(std::cmp::min(a, c), b);
|
||||||
regions.remove(i);
|
regions.remove(i);
|
||||||
i -= 1;
|
true
|
||||||
}
|
}
|
||||||
(Region::Forward(a, b), Region::Forward(c, d)) if a <= c && b < d => {
|
(Region::Forward(a, b), Region::Forward(c, d)) if a <= c && b < d => {
|
||||||
regions[i - 1] = Region::Forward(a, d);
|
regions[i - 1] = Region::Forward(a, d);
|
||||||
regions[i] = Region::Forward(a, b);
|
regions[i] = Region::Forward(a, b);
|
||||||
|
true
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if did_edit {
|
||||||
|
// Back up to re-examine i-1 vs i-2, unless we
|
||||||
|
// were examining i=0 vs i=1 already.
|
||||||
|
i = std::cmp::max(2, i) - 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue