///|
pub(all) enum RegClass {
Int
Float
Vector
} derive(Eq, Debug)
///|
pub(all) struct VirtualReg {
id : Int
class : RegClass
} derive(Eq, Debug)
///|
pub(all) struct PhysicalReg {
id : Int
class : RegClass
} derive(Eq, Debug)
///|
pub(all) enum OperandRole {
Use
Def
UseDef
} derive(Eq, Debug)
///|
pub(all) struct Operand {
vreg : VirtualReg
role : OperandRole
constraint : OperandConstraint
tie_id : Int
} derive(Eq, Debug)
///|
pub fn Operand::use_reg(vreg : VirtualReg) -> Operand {
{ vreg, role: Use, constraint: AnyReg, tie_id: -1 }
}
///|
pub fn Operand::def(vreg : VirtualReg) -> Operand {
{ vreg, role: Def, constraint: AnyReg, tie_id: -1 }
}
///|
pub fn Operand::with_constraint(
self : Operand,
constraint : OperandConstraint,
) -> Operand {
{ vreg: self.vreg, role: self.role, constraint, tie_id: self.tie_id }
}
///|
pub fn Operand::with_tie(self : Operand, tie_id : Int) -> Operand {
{ vreg: self.vreg, role: self.role, constraint: self.constraint, tie_id }
}
///|
pub(all) struct Instruction {
id : Int
operands : Array[Operand]
clobbers : Array[PhysicalReg]
} derive(Debug)
///|
pub fn Instruction::Instruction(id : Int) -> Instruction {
{ id, operands: [], clobbers: [] }
}
///|
pub fn Instruction::add_operand(self : Instruction, operand : Operand) -> Unit {
self.operands.push(operand)
}
///|
pub fn Instruction::add_clobber(self : Instruction, preg : PhysicalReg) -> Unit {
self.clobbers.push(preg)
}
///|
pub(all) struct Block {
id : Int
instructions : Array[Instruction]
successors : Array[Int]
} derive(Debug)
///|
pub fn Block::Block(id : Int) -> Block {
{ id, instructions: [], successors: [] }
}
///|
pub fn Block::append(self : Block, inst : Instruction) -> Unit {
self.instructions.push(inst)
}
///|
pub fn Block::add_successor(self : Block, block_id : Int) -> Unit {
self.successors.push(block_id)
}
///|
pub(all) struct Program {
blocks : Array[Block]
physical_regs : Array[PhysicalReg]
} derive(Debug)
///|
pub fn Program::Program(physical_regs : Array[PhysicalReg]) -> Program {
{ blocks: [], physical_regs }
}
///|
pub fn Program::add_block(self : Program, block : Block) -> Unit {
self.blocks.push(block)
}