Eliminate call stack recursion in VirtRegs::find (#584)

* Eliminate call stack recursion in VirtRegs::find
This commit is contained in:
oooooba
2018-11-15 05:58:50 +09:00
committed by Dan Gohman
parent 5baeed06bb
commit 155fd4c72a

View File

@@ -291,21 +291,23 @@ impl UFEntry {
impl VirtRegs { impl VirtRegs {
/// Find the leader value and rank of the set containing `v`. /// Find the leader value and rank of the set containing `v`.
/// Compress the path if needed. /// Compress the path if needed.
fn find(&mut self, val: Value) -> (Value, u32) { fn find(&mut self, mut val: Value) -> (Value, u32) {
let mut val_stack = vec![];
let found = loop {
match UFEntry::decode(self.union_find[val]) { match UFEntry::decode(self.union_find[val]) {
UFEntry::Rank(rank) => (val, rank), UFEntry::Rank(rank) => break (val, rank),
UFEntry::Link(parent) => { UFEntry::Link(parent) => {
// TODO: This recursion would be more efficient as an iteration that pushes val_stack.push(val);
// elements onto a SmallVector. val = parent;
let found = self.find(parent); }
// Compress the path if needed. }
if found.0 != parent { };
// Compress the path
while let Some(val) = val_stack.pop() {
self.union_find[val] = UFEntry::encode_link(found.0); self.union_find[val] = UFEntry::encode_link(found.0);
} }
found found
} }
}
}
/// Union the two sets containing `a` and `b`. /// Union the two sets containing `a` and `b`.
/// ///