Skip to content

Local variables are not the most efficient way to use values multiple times. #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ghost opened this issue May 24, 2016 · 5 comments

Comments

@ghost
Copy link

ghost commented May 24, 2016

The PushPop document notes:

'However, push/pop are representing expression tree edges in WebAssembly, which can only have a single definition and a single use. The way to use a value multiple times in WebAssembly is to use set_local and get_local.'

However a single definition value used multiple times within it's lexical scope is more efficiently kept on the values stack and referenced from there as proposed in WebAssembly#685

In a single pass compiler a value kept on the blocks values stack is known to no longer be live at the end of the block which helps the compiler with register allocation, whereas if a local variable is used the compiler may not know this until much later when there is another write to the variable.

An expressionless encoding in which there was no values stack was explored and while possible it leads to more local variables than necessary and this slows decoding. At the other extreme it may well be possible to eliminate local variables and this might lead to even faster and simpler decoding to SSA form.

So I strongly dispute the assertion that local variable are 'the way to use a value multiple times in WebAssembly', rather this is just one known poor option.

@qwertie
Copy link

qwertie commented May 24, 2016

I know you're coming at this in terms of binary encoding again; but I would critique it from a different angle. "use a value multiple times" misses the point, since it wouldn't be uncommon to want to repeat something multiple times that reads memory (which is different than using a value multiple times) or even has side effects. If there were some substantial cost associated with allowing the syntax tree to be expanded multiple times, that should be in the rationale rather than talking about using a "value" multiple times.

The way I think about it, lots of assemblers have a macro feature - and everyone knows the macros are not part of the output code. So it doesn't hurt to also have one in wasm text. On the other hand, in terms of reading code, there is some value in knowing that a subtree will only be used once. So for now I won't complain too loudly about being unable to use a subtree multiple times.

I assume the idea of standardizing a 'level 1 encoding' - with macros in the binary format - is still on the table. So maybe we should wait and see how the level 1 encoding turns out, then incorporate it properly in the text format as a "reified macro" feature.

@ghost
Copy link
Author

ghost commented May 24, 2016

@qwertie I read the push / pop in this context to be about the implicit pushing and popping of values on the values stack, not the pre-processor feature allowing lines to be split. A macro layer has nothing to do with the efficiency of compiling the binary encoding. Local variables a just not as efficient for a one pass compiler as a definition on the values stack in my experience. I don't think anyone is proposing macros in the binary format, perhaps the operator table comes close.

@sunfishcode
Copy link
Owner

@JSStats This text format aims to reflect the underlying WebAssembly structure. If WebAssembly is changed as you propose, this text format will adapt accordingly.

@qwertie The way to avoid computing a value multiple times in WebAssembly today is to use set_local and get_local. If we add syntax sugar that can either be set_local/get_local or stack transfers, it will be harder to accurately round trip information between text and binary. In this text format, I'm attempting to make a distinction between obvious syntax sugar that unambiguously reflects the underlying structure, which is good, and macro features which abstract over multiple constructs, which is undesirable.

@qwertie
Copy link

qwertie commented May 24, 2016

@sunfishcode I don't follow. Are you saying that allowing the use of a named subexpression multiple times in the text format would somehow be "harder to accurately round trip information between text and binary"? That isn't correct, except in the sense that text => binary => text wouldn't round-trip (but it is explicitly not intended to). I can't agree that "macro features which abstract over multiple constructs" are undesirable. Says who?

But as I said, I won't complain too loudly about this.

@sunfishcode
Copy link
Owner

@qwertie Well, at the moment, this is my experiment, and I am making some subjective choices.

But I will also observe that, in native circles, macro-assemblers used to be quite popular a few decades ago. As compilers matured, compiler-writers frequently found that macro-assemblers got in their way more than they helped, and programmers found that the advantages of dedicated programming languages were far beyond what the best macro-assemblers could provide for the majority of programming tasks. These days, macro-assemblers are limited to specialized niches. WebAssembly isn't the same as traditional assembly in every respect, so the analogy isn't perfect, but it is worth thinking about.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants