///|
struct SlotTracker {
function : Function
valueMap : Map[&Value, UInt64]
}
///|
fn SlotTracker::new(function : Function) -> SlotTracker {
SlotTracker::{ function, valueMap: Map::new() }
}
///|
fn SlotTracker::process(self : SlotTracker) -> Unit {
self.clear()
let mut slot : UInt64 = 0
// set slot for arguments
for arg in self.function.arguments {
if arg.getName() is None {
self.valueMap.set(arg, slot)
slot += 1
}
}
// set slot for basic blocks and instructions
for bb in self.function.basicBlocks {
if bb.getName() is None {
self.valueMap.set(bb, slot)
slot += 1
}
// REVIEW: Do we need to check the type of `i` is `void`?
// `&& not(i.getType().asTypeEnum() is VoidType(_)`
loop bb.head {
Some(i) if i.getInstName() is None => {
self.valueMap.set(i, slot)
slot += 1
continue i.next()
}
Some(i) => continue i.next()
None => break
}
}
}
///|
fn SlotTracker::clear(self : SlotTracker) -> Unit {
self.valueMap.clear()
}
///|
fn SlotTracker::getSlot(self : SlotTracker, value : &Value) -> UInt64? {
match self.valueMap.get(value) {
Some(slot) => Some(slot)
None => {
self.process()
match self.valueMap.get(value) {
Some(slot) => Some(slot)
None => None
}
}
}
}