From 71288c77b71e82e89cafd9a8f601529e3c48e87b Mon Sep 17 00:00:00 2001 From: Tyler Hou Date: Thu, 17 Oct 2024 13:38:05 -0700 Subject: [PATCH] Modify brili to properly execute phi instructions This fixes issue 330: https://github.com/sampsyo/bril/issues/330 The approach (copy the environment at the end of the last basic block) was inspired/copied from the comment on the Bril issue: https://github.com/sampsyo/bril/issues/330#issuecomment-2380389110 --- brili.ts | 10 +++++----- test/interp/ssa/ssa-swap.bril | 21 +++++++++++++++++++++ test/interp/ssa/ssa-swap.out | 6 ++++++ 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 test/interp/ssa/ssa-swap.bril create mode 100644 test/interp/ssa/ssa-swap.out diff --git a/brili.ts b/brili.ts index 3177028f6..cb9136058 100644 --- a/brili.ts +++ b/brili.ts @@ -687,10 +687,10 @@ function evalInstr(instr: bril.Instruction, state: State): Action { if (labels.length != args.length) { throw error(`phi node has unequal numbers of labels and args`); } - if (!state.lastlabel) { + if (state.lastblock === null) { throw error(`phi node executed with no last label`); } - let idx = labels.indexOf(state.lastlabel); + let idx = labels.indexOf(state.lastblock.label); if (idx === -1) { // Last label not handled. Leave uninitialized. state.env.delete(instr.dest); @@ -700,7 +700,7 @@ function evalInstr(instr: bril.Instruction, state: State): Action { throw error(`phi node needed at least ${idx+1} arguments`); } let src = instr.args[idx]; - let val = state.env.get(src); + let val = state.lastblock.endenv.get(src); if (val === undefined) { state.env.delete(instr.dest); } else { @@ -817,7 +817,7 @@ function evalFunc(func: bril.Function, state: State): Value | null { // count "aborted" instructions. Object.assign(state, { env: state.specparent.env, - lastlabel: state.specparent.lastlabel, + lastblock: state.specparent.lastblock, curlabel: state.specparent.curlabel, specparent: state.specparent.specparent, }); @@ -954,7 +954,7 @@ function evalProg(prog: bril.Program) { heap, env: newEnv, icount: BigInt(0), - lastlabel: null, + lastblock: null, curlabel: null, specparent: null, } diff --git a/test/interp/ssa/ssa-swap.bril b/test/interp/ssa/ssa-swap.bril new file mode 100644 index 000000000..2c37299c5 --- /dev/null +++ b/test/interp/ssa/ssa-swap.bril @@ -0,0 +1,21 @@ +@main { + i: int = const 5; + one: int = const 1; + zero: int = const 0; + +.l0: + x0: int = const 0; + y0: int = const 1; + jmp .l1; + +.l1: + x1: int = phi .l0 x0 .l1 y1; + y1: int = phi .l0 y0 .l1 x1; + print x1 y1; + + cond: bool = gt i zero; + i: int = sub i one; + br cond .l1 .end; + +.end: +} diff --git a/test/interp/ssa/ssa-swap.out b/test/interp/ssa/ssa-swap.out new file mode 100644 index 000000000..8c3dac765 --- /dev/null +++ b/test/interp/ssa/ssa-swap.out @@ -0,0 +1,6 @@ +0 1 +1 0 +0 1 +1 0 +0 1 +1 0