Skip to content

Commit

Permalink
fix closure freezing
Browse files Browse the repository at this point in the history
  • Loading branch information
glyh committed Oct 22, 2024
1 parent 99ae57c commit 5182b5b
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 34 deletions.
49 changes: 21 additions & 28 deletions src/riscv/before_alloc.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -31,51 +31,44 @@ fn reserve_fregs(cfg : @ssacfg.SsaCfg, block : @ssacfg.Block) -> Unit {
block.insts = insts
}

// NOTE: load constant closure into scope whenever it's needed
fn ensure_closure_load(
// NOTE: replace constant closure with labels
fn freeze_closure(
all_constant_closures : @hashset.T[Var],
block : @ssacfg.Block
) -> Unit {
let insts_backup = block.insts
let insts : Array[@ssacfg.Inst] = []
let defined_constant_closure : @hashset.T[Var] = @hashset.new()
fn check_constant_closure_val(v : Value) {
fn fix_val(v : Value) -> Value {
match v {
Var(v) =>
if all_constant_closures.contains(v) &&
not(defined_constant_closure.contains(v)) {
insts.push(LoadAddr(v, v.to_string()))
defined_constant_closure.insert(v)
if all_constant_closures.contains(v) {
Label(v)
} else {
Var(v)
}
_ => ()
_ => v
}
}

for inst in insts_backup {
match inst {
MakeTuple(bind, vals) => {
vals.each(check_constant_closure_val)
defined_constant_closure.insert(bind)
}
KthTuple(bind, tup, _) => {
check_constant_closure_val(tup)
defined_constant_closure.insert(bind)
}
Prim(bind, _, args) => {
args.each(check_constant_closure_val)
defined_constant_closure.insert(bind)
}
let inst : @ssacfg.Inst = match inst {
MakeTuple(bind, vals) => MakeTuple(bind, vals.map(fix_val))
KthTuple(bind, tup, k) => KthTuple(bind, fix_val(tup), k)
Prim(bind, op, args) => Prim(bind, op, args.map(fix_val))
Store(_) | Load(_) =>
@util.die("unreachable: load/store occurs before allocation")
Copy(bind, copied) => {
check_constant_closure_val(copied)
defined_constant_closure.insert(bind)
}
LoadAddr(bind, _) => defined_constant_closure.insert(bind)
Copy(bind, copied) => Copy(bind, fix_val(copied))
}
insts.push(inst)
}
block.insts = insts
block.last_inst.val = match block.last_inst.val {
Branch(cond, _then, _else) => Branch(fix_val(cond), _then, _else)
Call(f, args) => Call(fix_val(f), args.map(fix_val))
MakeArray(len, elem, kont) =>
MakeArray(fix_val(len), fix_val(elem), fix_val(kont))
Exit => Exit
}
}

fn before_alloc(cfg : @ssacfg.SsaCfg) -> @ssacfg.SsaCfg {
Expand All @@ -87,7 +80,7 @@ fn before_alloc(cfg : @ssacfg.SsaCfg) -> @ssacfg.SsaCfg {
for item in cfg.blocks {
let (_, block) = item
reserve_fregs(cfg, block)
ensure_closure_load(all_constant_closures, block)
freeze_closure(all_constant_closures, block)
}
cfg
}
1 change: 0 additions & 1 deletion src/riscv/codegen.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,6 @@ fn CodegenBlock::codegen(self : CodegenBlock) -> Unit {
for inst in block.insts {
self.insert_asm(Comment(inst.to_string()))
match inst {
LoadAddr(var, addr) => self.assign_i(var, fn(reg) { [La(reg, addr)] })
Copy(bind, copied) =>
match get_reg_ty(copied) {
F64 => {
Expand Down
1 change: 0 additions & 1 deletion src/riscv/collect_labels.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ fn collect_externals(cfg : @ssacfg.SsaCfg) -> ExternalLabels {
collect_label_val(val)
}
Store(var) | Load(var) => collect_label_var(var)
LoadAddr(_) => () // load addr can't be external
}
}
match blk.last_inst.val {
Expand Down
1 change: 0 additions & 1 deletion src/riscv/interference_graph_build.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ fn LiveVarAnalysis::collect_inst(
args.each(fn(v) { self.collect_val(v) })
}
Load(bind) => self.var_set.remove(bind)
LoadAddr(bind, _) => self.var_set.remove(bind)
Store(bind) => self.var_set.insert(bind)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/riscv/reg_spill.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn reg_spill_block(blk : @ssacfg.Block, spilled_var : Var) -> @ssacfg.Block {
insts_new.push(Store(spilled_var))
}
}
LoadAddr(_) | Load(_) | Store(_) => insts_new.push(inst)
Load(_) | Store(_) => insts_new.push(inst)
}
}
let load_before_exit = match blk.last_inst.val {
Expand Down
2 changes: 0 additions & 2 deletions src/ssacfg/ssa_ir.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ pub enum Inst {
Load(Var)
// So we can deal with the case where 1 tmp reg is not enough
Copy(Var, Value)
// Support for constant closure
LoadAddr(Var, String)
} derive(Show)

pub enum PCInst {
Expand Down

0 comments on commit 5182b5b

Please sign in to comment.