///|
let inst_id : Ref[Int] = Ref::new(0)
///|
pub(all) struct Instruction {
id : Int
opcode : OpCode
defs : Array[Operand]
uses : Array[Operand]
bb : BasicBlock
func : Function
mut live_in : Set[Operand]
mut live_out : Set[Operand]
}
///|
pub fn Instruction::new(
opcode : OpCode,
defs : Array[Operand],
uses : Array[Operand],
bb : BasicBlock,
) -> Instruction {
let id = inst_id.val
inst_id.val += 1
Instruction::{
id,
opcode,
defs,
uses,
bb,
func: bb.parent,
live_in: Set::new(),
live_out: Set::new(),
}
}
///|
pub impl Eq for Instruction with equal(self, other) {
self.id == other.id
}
///|
///
/// Returns true if live_in changed.
pub fn Instruction::update_live_out(
self : Self,
live_out : Set[Operand],
) -> Bool {
if self.live_out == live_out {
return false
}
self.live_out = live_out
true
}
///|
///
/// Returns true if live_out changed.
pub fn Instruction::update_live_in(self : Self, live_in : Set[Operand]) -> Bool {
if self.live_in == live_in {
return false
}
self.live_in = live_in
true
}
///|
pub fn Instruction::contains_virtual_reg(self : Self) -> Bool {
for op in self.defs {
if op.is_virtual_reg() {
return true
}
}
for op in self.uses {
if op.is_virtual_reg() {
return true
}
}
false
}
///|
pub impl Show for Instruction with output(self, logger) {
match self.defs {
[] => ()
[d] => logger.write_string("\{d} = ")
_ as defs => {
let defs_str = defs.map(d => "\{d}").join(", ")
logger.write_string("(\{defs_str}) = ")
}
}
logger.write_object(self.opcode)
if self.uses.length() > 0 {
let uses_str = self.uses.map(u => "\{u}").join(", ")
logger.write_string(" \{uses_str}")
}
}