Closed Hywan closed 4 years ago
A general comment: when a machine like wasm is implemented by lowering into actual machine code, stack movement instructions (like pop, push, pick etc) do not normally lead to generated code. This is because the lowering compiler uses these instructions to maintain a virtual stack. E.g., a push instruction leads to the lowering compiler to remember where the value is; then, when the value is actually needed, the remembered value is loaded from where it would have been loaded in the original push. So, apart from reducing the code size of a wasm module, (which is a legitimate concern) there is no merit from optimizing pushes with other stack manipulation.
Discussing about this version of the proposal (the latest at the time of writing): https://github.com/WebAssembly/interface-types/blob/5af0606baceab6c5ecc8bd247fae944998c2aa61/proposals/interface-types/working-notes/Instructions.md#stringlower_memory
A typical string lowering requires the following instructions:
arg.get 0
[string("foo")]
string.size
[i32(3)]
call-core 42
[i32(1024)]
42
is the function index of an allocatorarg.get 0
[i32(1024), string("foo")]
string.lower_memory
[]
My observation is the following. Considering
string.lower_memory
is going to appear often, and considering an allocator must be called before, the string to be lowered must be loaded twice on the stack. For small strings, it could be OK, for larger strings, it could be a problem.It's very likely that I'm missing something. With the Covid-19 situation, I have difficulties to follow every discussions of this WG.
If my observation is valid, then we could probably modify
string.size
such as it peeks one value from the stack rather than popping it; thus its type becomes:Note: I know peeking can feel somewhat unusual, and more importantly, it would require another
pop n
ordrop n
instruction.The set of instructions would become:
arg.get 0
[string("foo")]
string.size
[string("foo"), i32(3)]
call-core 42
[string("foo"), i32(1024)]
swap
[i32(1024), string("foo")]
swap
is a new instructionstring.lower_memory
[]
Notice the new
swap
instruction. It is required to fulfill the type ofstring.lower_memory
. It is possible to avoidswap
if we updatestring.lower_memory
type to:And thus, the set of instructions become:
arg.get 0
[string("foo")]
string.size
[string("foo"), i32(3)]
call-core 42
[string("foo"), i32(1024)]
string.lower_memory
[]
Which is the simplest version for lowering a string.
Thoughts?