///|
pub struct FunctionBuilder {
func : Function
mut current_block : @block.Block
}
///|
pub fn FunctionBuilder::FunctionBuilder(name : String) -> FunctionBuilder {
let func = Function(name)
let entry = func.new_block()
{ func, current_block: entry }
}
///|
pub fn FunctionBuilder::add_param(
self : FunctionBuilder,
class : @abi.RegClass,
) -> @abi.VReg {
self.func.add_param(class)
}
///|
pub fn FunctionBuilder::add_result(
self : FunctionBuilder,
kind : ValueKind,
) -> Unit {
self.func.add_result_kind(kind)
}
///|
pub fn FunctionBuilder::create_block(self : FunctionBuilder) -> Int {
self.func.new_block().id
}
///|
pub fn FunctionBuilder::switch_to_block(
self : FunctionBuilder,
block_id : Int,
) -> Unit {
for block in self.func.blocks {
if block.id == block_id {
self.current_block = block
return
}
}
abort("unknown MachV block \{block_id}")
}
///|
pub fn FunctionBuilder::new_vreg(
self : FunctionBuilder,
class : @abi.RegClass,
) -> @abi.VReg {
self.func.new_vreg(class)
}
///|
pub fn FunctionBuilder::append(
self : FunctionBuilder,
opcode : @instr.Opcode,
uses? : Array[@abi.Reg] = [],
defs? : Array[@abi.Writable] = [],
use_constraints? : Array[@abi.OperandConstraint] = [],
def_constraints? : Array[@abi.OperandConstraint] = [],
) -> Int {
let inst = @instr.Inst(opcode)
for i, src in uses {
if i < use_constraints.length() {
match use_constraints[i] {
Any => inst.add_use(src)
FixedReg(preg) => inst.add_use_fixed(src, preg)
}
} else {
inst.add_use(src)
}
}
for i, def in defs {
if i < def_constraints.length() {
match def_constraints[i] {
Any => inst.add_def(def)
FixedReg(preg) => inst.add_def_fixed(def, preg)
}
} else {
inst.add_def(def)
}
}
self.current_block.add_inst(inst)
self.current_block.insts.length() - 1
}
///|
pub fn FunctionBuilder::terminate(
self : FunctionBuilder,
term : @instr.Terminator,
) -> Unit {
self.current_block.set_terminator(term)
}
///|
pub fn FunctionBuilder::finish(self : FunctionBuilder) -> Function {
self.func
}
///|
pub fn Function::blocks(self : Function) -> Array[@block.Block] {
self.blocks
}
///|
pub fn Function::params(self : Function) -> Array[@abi.VReg] {
self.params
}