mijit
mijit copied to clipboard
Separate `new_exit()`, `new_label()` and `new_entry()`
The one method Jit::new_entry()
currently creates an entry point, an exit point, and a merge point with a specified register allocation. Consider separating it into three simple methods.
In what follows, I assume #48 is done first.
fn new_exit(reason: u32) -> Label
creates a place where the Mijit code can return to the caller, passing reason
. The Convention
at the returned Label
specifies that R0
holds the one live value, which is the pointer to the VM state.
fn new_label(lives: &[Name], epilogue: impl FnOnce(Builder<Label>, &[Node]) -> CFT<Label>) -> Label
creates a merge point with a non-trivial Convention
. I'm not sure what Name
is: maybe &str
? It identifies a live value. The same Name
is always allocated to the same register. Input
nodes (SSA "phi" nodes) are constructed for the live variables, and passed to the epilogue
callback, which then constructs the code. The code will be used after an interrupt to save state and jump to an appropriate exit. The code will also be used if Jit::define()
is not called for the returned Label
.
fn new_entry(prologue: impl FnOnce(&mut Builder<Label>, Node) -> Vec<Node>) -> EntryId
creates a place where the caller can enter the Mijit code. The convention on entry is that R0
holds the one live value, which is a pointer to the VM state. An Input
node is constructed for it, and passed to the prologue
callback, which then constructs the code. The code will be used to restore state and resume execution after an interrupt.
These methods alone allow the construction of finite code paths through Mijit code, maintaining the invariant that every Label
has a distinguished finite path to an exit. The existing method fn define(Label, |mut Builder<Label>, &[Node]) -> CFT<Label>
is needed in addition to define loops and other cyclic control-flow paths.
Splitting into these three separate methods abandons three features that Mijit currently enjoys:
- There is a unique shortest path from an entry to each point in the Mijit code.
- Mijit handles timer interrupts transparently.
- EntryId == Label.